I have been having an issue whereby after long jumping to protected mode, seemingly when setting up the ss
register, a triple fault is caused. My code:
switch-to-32bit.asm
[org 0x7c00]
[bits 16]
switch_to_32bit:
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 0x1 ; protected mode
mov cr0, eax
jmp CODE_SEG:init_32bit ; far jump
[bits 32]
init_32bit:
mov ax, DATA_SEG ; 0x1000
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000 ; setup stack
mov esp, ebp
call BEGIN_32BIT
gdt.asm
gdt_start:
dq 0x0
gdt_code:
dw 0xffff ; segment length
dw 0x0 ; segment base
db 0x0 ; segment base
db 10011010b ; flags
db 11001111b ; flags
db 0x0 ; segment base
gdt_data:
dw 0xffff ; segment length
dw 0x0 ; segment base
db 0x0 ; segment base
db 10011010b ; flags
db 11001111b ; flags
db 0x0 ; segment base
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
When running this with bochs
, a lot of debugging lines come into the console, as seen here:
Does anyone know why setting the ss
register causes this issue? Or maybe if the issue is deeper (I see SS.mode = 16 bit
)? Thanks.
You have an incorrect flag on your data segment descriptor: 10011010b
should be 10010010b
. Bit 3 should be 0
to indicate a data segment.
When you mov
a value into a segment register, it checks it for validity. It's valid (though not desirable) to move a (readable) code segment descriptor into DS
, as long as you don't try to write to the segment. It's not, however, valid to move that descriptor into SS
, so that's the instruction that's faulting. You're probably getting a #GP(0x10)
exception, which is cascading into a triple fault.