I am in the process of writing my bootloader. I have followed the instructions here on how to enter x64 bit long mode. And then I have mapped virtual address 0xC000,0000 - 0xC020,0000 to 0x0000 - 0x20,0000. I was able to successfully load virtual address 0x4000,0000 but not 0x8000,0000 or any higher addresses. The below code demonstrates what I have done.
Code: Select all
; zero out tables
push edi
mov eax, 0x0
.ZeroOutAllTable:
mov [edi], eax ;zero out
add edi, 4
cmp edi, 0x900000
jb .ZeroOutAllTable
pop edi
;edi contains free memory space which starts at 0x100000
; I have set one page table to be at address edi + 0x6000
;PML4 at edi
;PDPT at edi+0x1000
;PD at edi + 0x2000
;Page Table at edi + 0x6000
; Build the Page Map Level 4.
; es:di points to the Page Map Level 4 table.
lea eax, [edi + 0x1000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi], eax
; Build the Page Directory Pointer Table.
; 0x0000,0000 - 0x3FFFF000
lea eax, [edi + 0x2000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi + 0x1000], eax
;; 0x4000,0000 - 0x7FFFF000
lea eax, [edi + 0x2000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi + 0x1008], eax
;; 0x8000,0000 - 0xBFFFF000
lea eax, [edi + 0x2000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi + 0x1010], eax
;; 0xC000,0000 - 0xFFFFF000
lea eax, [edi + 0x2000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi + 0x1018], eax
; Build the Page Directory.
;; 0x0000,0000 - 0x0020,0000
lea eax, [edi + 0x6000]
or eax, PAGE_PRESENT | PAGE_WRITE
mov [edi + 0x2000], eax
; Build the Identity map.
push edi
lea edi, [edi + 0x6000] ; Point DI to the page table.
mov eax, PAGE_PRESENT | PAGE_WRITE
.LoopIdentityPageTable:
mov [edi], eax
add eax, 0x1000
add edi, 8
cmp eax, 0x200000 ; If we did all 2MiB, end.
jb .LoopIdentityPageTable
pop edi ; Restore DI.