This stage of my bootloader is loaded at 0x7e0:0x0000
. After some "debugging" I've discovered that the following code generates a triple fault after my far jump. If I move the hang (Yes, including the actual procedure itself) before the jump, it doesn't triple fault. Sorry I couldn't include less code. I'm just trying to make sure I'm providing enough code so the bug isn't missed.
Here's my code:
bits 16
jmp SetUpPMode
GTDData:
dd 0
dd 0
;Code Descriptor
dw 0xFFFF
dw 0
db 0
db 10011010b
db 11001111b
db 0
;Data Descriptor
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
GTDEnd:
GDTPointer:
dw (GTDEnd - GTDData) - 1
dd GTDData
LoadGDT:
lgdt [GDTPointer]
ret
SetUpPMode:
cli
mov ax, 0x7E0
mov ds, ax
call LoadGDT
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:main
bits 32
main:
mov ax, 0x10
mov ds, ax
mov es, ax
mov ss, ax
mov esp, 0x90000
jmp hang
hang:
;cli
hlt
jmp hang
I bet the bug/error is blatantly obvious, but I just can't seem to find it. Could someone please point it out? (If it matters, I'm using Virtual Box)
You load the code and the data at 0x07E0:0x0000
. Therefore, all the references that the assembler and linker make are based at 0x07E0:0x0000
- such as main
, which may be 0x0020
or something.
But your GDT has the Code Segment based to 0x00000000
- so the jmp 0x8:main
would JMP
to absolute address 0x00000020
or something - nowhere near where the code is at 0x00007E20
or wherever. Either change the base of the segments in the GDT, or change the code to work from a real mode segment of 0x0000
.