;Input
; esi Address of module list
; ebp Number of AP CPUs present
MARK
START: |
clr ax mov ss,ax mov esp,STACK_TOP mov ds,ax mov es,ax mov fs,ax |
mov ecx,(BSS_END - BSS_START) / 4 ;ecx = size of BSS in dwords mov edi,BSS_START clr eax cld rep stosd |
CALL_BOOT_API 0x6C ;Get address of byte after highest used page test eax,eax ;Was there an error? jne .getMemTopFailed ; yes mov [identityMapTop],ebx |
CALL_BOOT_API 0x68 ;Allocate a page for the PML4 test eax,eax ;Was there an error? jne .getPageFailed ; yes mov edx,ebx ;edx = physical address of PML4 |
CALL_BOOT_API 0x68 ;Allocate a page for the PML4 test eax,eax ;Was there an error? jne .getPageFailed ; yes mov ecx,ebx ;ecx = physical address of PDPT or bl,00000111b ;Set present, read/write and user flags mov [gs:edx],ebx ;Put PDPT into PML4 |
CALL_BOOT_API 0x68 ;Allocate a page for the page directory test eax,eax ;Was there an error? jne .getPageFailed ; yes mov ebp,ebx ;ebp = physical address of page directory or bl,00000111b ;Set present, read/write and user flags mov [gs:ecx],ebx ;Put page directory into PDPT |
mov ecx,[identityMapTop] ;ecx = number of bytes to identity map clr esi ;esi = starting address for identity mapping shr ecx,12 ;ecx = number of pages to identity map .nextPageTable: CALL_BOOT_API 0x68 ;Allocate a page for the page table test eax,eax ;Was there an error? jne .getPageFailed ; yes mov edi,ebx ;edi = physical address of page table or bl,00000111b ;Set present, read/write and user flags mov [gs:ebp],ebx ;Put page table into page directory add ebp,8 ;Increase next address in page directory lea eax,[esi+00000111b] ;eax = first page table entry with present, read/write and user flags .nextPage: mov [gs:edi],eax ;Put next page into page table add eax,0x00001000 ;eax = next page table entry add esi,0x00001000 ;esi = next address to identity map add edi,8 ;edi = physical address for next page table entry sub ecx,1 ;ecx = number of pages left to identity map je .doneMapping ;Done if no pages left to identity map test edi,0xFFFFF000 ;Has this page table been filled? je .nextPageTable ; yes, get another page table jmp .nextPage ; no, identity map another page .doneMapping: |
mov eax,10100000b ;eax = PAE and PGE flags set
mov cr4,eax ;Enable PAE and PGE
mov cr3,edx ;Set address of PML4
mov ecx,0xC0000080 ;ecx = MSR for EFER
rdmsr ;Enable long mode in the EFER MSR
or eax,0x00000100
wrmsr ;Enable long mode in the EFER MSR
mov ebx,cr0 ;ebx = cr0
or ebx,0x80000001 ;eax = cr0 with paging and protection enabled
mov cr0,ebx ;Enable long mode
lgdt [GDT]
jmp 0x18:.startLongMode ;Load CS with 64 bit segment and flush the instruction cache |
.getMemTopFailed: .getPageFailed: mov eax,0xDEADBEEF jmp $ ;Lock up (no video access) |