It's supposed to work as follows (or so I think):
1. grub2 puts us in pmode and starts
2. sanity checks and remap pic
3. setup paging
4. set EFER and LM
5. enable LM - should be in compatibility mode so still need to load a GDT
The code is my poor attempt to identity map the first 4mb of ram and then enable paging. If you see what's wrong please let me know
Thanks!
Mike
Code: Select all
start:
mov esp, _sys_stack
mov [grub2_meminfo], ebx ; Store the grub2 memory pointer (if valid)
cmp eax, 0x36D76289 ; GRUB2 magic value
jne error
call check_cpuid ; Make sure CPUID is supported
cmp eax, dword 1
jne error
mov eax, 0x80000000 ; Check for extended CPUID functions
CPUID
cmp eax, 0x80000001 ; if < this, no extended fns to check for LM
jb error
mov eax, 0x80000001 ; Extended functions of CPUID
CPUID
bt edx, 29 ; Check for long mode
jnc error
cli ; Disable interrupts
call remap_pic ; Remap IRQ0 to IRQ15 -> INT 0x20 - INT 0x2F
mov eax, cr0 ; Get contents of cr0
bt eax, 31 ; Check bit 31
jc error ; Set means paging is already enabled
mov edi, PML4 ; Clear out the PML4 table
xor eax, eax
mov ecx, 1024
rep stosd
mov edi, 0x200000 ; Start of first PDPT
xor eax, eax
mov ecx, 0x1000 ; Clear some memory for page tables
rep stosd
mov eax, 0x200003 ; PML4 -> PDPT
mov [PML4], eax ; Thank you little endian machine
mov eax, 0x201003
mov edi, 0x200000
mov [edi], eax ; PDPT -> PDT
add edi, 0x1000
mov eax, 0x202003
mov [edi], eax ; PDT -> PT (first)
add edi, 8
mov eax, 0x203003
mov [edi], eax ; PDT -> PT (second)
mov edi, 0x00202000 ; Start of first PT to fill
mov ebx, 0x00000003 ; Map from address 0 (with present, r/w set)
mov ecx, 1024 ; Do BOTH PT's (first and second)
.SetEntry:
mov DWORD [edi], ebx
add ebx, 0x1000
add edi, 8
loop .SetEntry
mov eax, PML4
mov cr3, eax ; Set the top level page table address
mov eax, cr4
or eax, 1 << 5 ; Enable PAE
mov cr4, eax
mov ecx, 0xC0000080 ; Enable LM in the EFER register
rdmsr
or eax, 1 << 8
wrmsr
mov [0xb8000], byte 'Y' ; Display a char and halt
hlt
mov eax, cr0
or eax, 1 << 31
mov cr0, eax ; Should now be in 64-bit compatiblity mode
mov eax, 0x03200320
mov ecx, 0x0500
mov edi, 0xb8000
.here: mov [edi], eax
dec ecx
add edi, 4
jnz .here
error: mov edi, 0xb8000
mov [edi], eax
jmp $