[solved] Long Mode: Page fault when jumping into 64-bit code
Posted: Mon Apr 28, 2008 3:41 am
Excuse me for my (probably) bad english.
I writed a bootloader that should enter in 32-bit Protected Mode and then setup basic paging before enter in Long Mode.
But when I far jump into 64-bit code, I get a page fault (error 14, isn't it?).
This is the relevant section of my bochsout.txt:
And this is what the debugger says:
Obviously, the 0008 selector is a 64-bit valid GDT entry (I think).
Here it is:
The far jump is just after the mov cr0, as the AMD manual says:
And this is how I setup paging:
What's wrong? Can you help me?
P.S. I'm using NASM 2.02 in a 32-bit environment, and Bochs 2.3.6 compiled with x86-64 support.
I writed a bootloader that should enter in 32-bit Protected Mode and then setup basic paging before enter in Long Mode.
But when I far jump into 64-bit code, I get a page fault (error 14, isn't it?).
This is the relevant section of my bochsout.txt:
Code: Select all
00002778367i[CPU0 ] >> jmp far 0008:00007cda : EADA7C00000800
00002778367e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
Code: Select all
<bochs:21> s
Next at t=2778371
(0) [0x00007cd3] 0018:0000000000007cd3 (unk. ctxt): jmp far 0008:00007cda ; eada7c00000800
<bochs:22> s
Next at t=2778371
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0
Here it is:
Code: Select all
; Code Segment descriptor:
code64_desc:
; Limit = 0xFFFFF, Base = 0x00000000
dw 0xFFFF ; Limit = FFFFx
dw 0x0000 ; Base = 0000xxxx
db 0x00 ; Base = xxxx00xx
db 10011010b ; Access Byte = (Present, Highest Privilege, Executable, Read/Write)
db 0xAF ; 1st nibble: Flags = 1010 (Granularity, Long Mode)
; 2nd nibble: Limit = xxxxF
db 0x00 ; Base = xxxxxx00
Code: Select all
; Enable paging:
mov eax, cr0 ; Read CR0.
bts eax, 31 ; Set PE=1.
mov cr0, eax ; Write CR0.
jmp 8:start_kernel ; Jump to the kernel.
; Long Mode:
[BITS 64]
;*****************************************
;* Jump to the kernel *
;*****************************************
start_kernel:
mov rsp, 0x9FFF0 ; Set the 64-bit Stack Pointer.
jmp 0x10000 ; Jump to the kernel.
And this is how I setup paging:
Code: Select all
;*****************************************
;* Setup Paging Tables *
;*****************************************
paging:
; Clear the paging tables:
xor eax, eax ; Set EAX to 0x00000000 (value to write).
mov edi, 0x8000 ; EDI = Address from which start to write.
mov ecx, 0x1000 ; ECX = Number of dwords to write.
rep stosd ; Write the dwords.
; *** Map the first 8 MB of memory ***
; PML4 located at 0x8000:
mov dword [0x8000], 0x9000 + 11b ; 1st PML4 Entry -> PDP table.
; PDP located at 0x9000:
mov dword [0x9000], 10000h + 11b ; 1st PDP Entry -> PD table.
; PD located at 0x10000:
mov dword [0x10000 + (8*0)], 0h + 110000011b ; 1st PD Entry -> 0 MB
mov dword [0x10000 + (8*1)], 200000h + 110000011b ; 2nd PD Entry -> 2 MB
mov dword [0x10000 + (8*2)], 400000h + 110000011b ; 3rd PD Entry -> 4 MB
mov dword [0x10000 + (8*3)], 600000h + 110000011b ; 4th PD Entry -> 6 MB
mov dword [0x10000 + (8*4)], 800000h + 110000011b ; 5th PD Entry -> 8 MB
; address entry frame flags
What's wrong? Can you help me?
P.S. I'm using NASM 2.02 in a 32-bit environment, and Bochs 2.3.6 compiled with x86-64 support.