Page table error in long mode
Posted: Fri Jul 04, 2008 5:32 am
OK, I 've been trying to enter long mode, and the program crashes when paging is set.
Here is the FASM code I use to setup the page code. I 've seen some code already, but I haven't yet managed to make it work. It crashes both Bochs and VMware. Do you notice any errors ?
PAGEORGBASE EQU 40000h
SEGMENT PAGE64 USE64
; For simplicity, put the page strutures at absolute memory 40000h, assuming it is empty.
; PAGE64 segment to hold the page
ORG PAGEORGBASE
; 4096 bytes for PML4
PML4_64 db 4096 dup (?)
; 4096 bytes of PDP
PDP_64 db 4096 dup (?)
; 4096 bytes of PD_64
PD_64 db 4096 dup (?)
;
PAGE_64 dq 4096 dup (?)
; 32768 Bytes = 4096 Pages = 4096*4096 = 16MB (Each page takes 8 bytes)
;
; Real mode code to initialize the page structures
; To provide a "see through" to the lower 16MB
;
InitPageTable64162:
; PageDirectory = PAGEORGBASE
pushad
push ds
mov eax,PML4_64
shr eax,4
mov ds,ax
xor edx,edx
; DS:DX = PML4_64
mov ecx,PDP_64
sub ecx,PAGEORGBASE
; DS:CX = PDP_64
; Put PDP to PML4
xor ebx,ebx
mov bx,cx
add ebx,PAGEORGBASE
or bl,111b ; Mark it as read/write/user
mov [ds:edx],ebx
mov ebp,PD_64
sub ebp,PAGEORGBASE
; DS:BP = PD_64
; Put PD to PDP
xor ebx,ebx
mov bx,bp
add ebx,PAGEORGBASE
or bl,111b ; Mark it as read/write/user
mov [ds:ecx],ebx
; 16MB map
mov ecx,16777216
shr ecx,12 ; Make it number of pages
; Build 4096 Pages to map 16MB of memory
; Each page takes 8 bytes
mov edi,PAGE_64
sub edi,PAGEORGBASE
;
; DS:BP = PD_64
; DS:DI = PAGE_64
;
xor esi,esi
xor ebx,ebx
mov bx,di
add ebx,PAGEORGBASE
NextPageTable:
; DS:DI holds the address of next page in memory
; EBX holds the absolute address of next page in memory
; DS:BP holds the address of the page directory entry for this page
; Put this page to page directory
PUSH EBX
or bl,111b ; Mark it as read/write/user
mov [ds:ebp],ebx
POP EBX
ADD EBX,8
ADD EBP,8
lea eax,[esi + 0111b]
; Configure this page to map memory
mov [ds:edi],eax ; Configure This Page
add edi,8 ; To next page, 8 bytes each
add esi,1000h ; Next 4096 bytes
; Are we finished doing our pages ?
dec ecx
jecxz Done
jmp NextPageTable
Done:
pop ds
popad
ret
;
; Here is the protected mode code that tries to enable long mode
;
; Enable Long Mode
mov eax, cr4
bts eax, 5
mov cr4, eax
; Load new page table
mov edx,PML4_64
mov cr3,edx
; Enable Long Mode
mov ecx, 0c0000080h ; EFER MSR number.
rdmsr ; Read EFER.
bts eax, 8 ; Set LME=1.
wrmsr ; Write EFER.
; Enable Paging to enter Compatibility Mode
mov eax, cr0 ; Read CR0.
or eax,80000000h ; Set PE=1.
mov cr0, eax ; Write CR0. BOOM !
....
Thanks a lot for any response.
Michael
Here is the FASM code I use to setup the page code. I 've seen some code already, but I haven't yet managed to make it work. It crashes both Bochs and VMware. Do you notice any errors ?
PAGEORGBASE EQU 40000h
SEGMENT PAGE64 USE64
; For simplicity, put the page strutures at absolute memory 40000h, assuming it is empty.
; PAGE64 segment to hold the page
ORG PAGEORGBASE
; 4096 bytes for PML4
PML4_64 db 4096 dup (?)
; 4096 bytes of PDP
PDP_64 db 4096 dup (?)
; 4096 bytes of PD_64
PD_64 db 4096 dup (?)
;
PAGE_64 dq 4096 dup (?)
; 32768 Bytes = 4096 Pages = 4096*4096 = 16MB (Each page takes 8 bytes)
;
; Real mode code to initialize the page structures
; To provide a "see through" to the lower 16MB
;
InitPageTable64162:
; PageDirectory = PAGEORGBASE
pushad
push ds
mov eax,PML4_64
shr eax,4
mov ds,ax
xor edx,edx
; DS:DX = PML4_64
mov ecx,PDP_64
sub ecx,PAGEORGBASE
; DS:CX = PDP_64
; Put PDP to PML4
xor ebx,ebx
mov bx,cx
add ebx,PAGEORGBASE
or bl,111b ; Mark it as read/write/user
mov [ds:edx],ebx
mov ebp,PD_64
sub ebp,PAGEORGBASE
; DS:BP = PD_64
; Put PD to PDP
xor ebx,ebx
mov bx,bp
add ebx,PAGEORGBASE
or bl,111b ; Mark it as read/write/user
mov [ds:ecx],ebx
; 16MB map
mov ecx,16777216
shr ecx,12 ; Make it number of pages
; Build 4096 Pages to map 16MB of memory
; Each page takes 8 bytes
mov edi,PAGE_64
sub edi,PAGEORGBASE
;
; DS:BP = PD_64
; DS:DI = PAGE_64
;
xor esi,esi
xor ebx,ebx
mov bx,di
add ebx,PAGEORGBASE
NextPageTable:
; DS:DI holds the address of next page in memory
; EBX holds the absolute address of next page in memory
; DS:BP holds the address of the page directory entry for this page
; Put this page to page directory
PUSH EBX
or bl,111b ; Mark it as read/write/user
mov [ds:ebp],ebx
POP EBX
ADD EBX,8
ADD EBP,8
lea eax,[esi + 0111b]
; Configure this page to map memory
mov [ds:edi],eax ; Configure This Page
add edi,8 ; To next page, 8 bytes each
add esi,1000h ; Next 4096 bytes
; Are we finished doing our pages ?
dec ecx
jecxz Done
jmp NextPageTable
Done:
pop ds
popad
ret
;
; Here is the protected mode code that tries to enable long mode
;
; Enable Long Mode
mov eax, cr4
bts eax, 5
mov cr4, eax
; Load new page table
mov edx,PML4_64
mov cr3,edx
; Enable Long Mode
mov ecx, 0c0000080h ; EFER MSR number.
rdmsr ; Read EFER.
bts eax, 8 ; Set LME=1.
wrmsr ; Write EFER.
; Enable Paging to enter Compatibility Mode
mov eax, cr0 ; Read CR0.
or eax,80000000h ; Set PE=1.
mov cr0, eax ; Write CR0. BOOM !
....
Thanks a lot for any response.
Michael