I have written a smal real mode OS before, and decided some months ago to start over, and go to Protected Mode. After months of reading about PMode, and planning the system architecture accordningly, I felt ready to start what some people describe as an adventurous journey into the land of protected mode.
However, despite being described many a place as a simple thing to do, I cannot enable the magic 0th bit of CR0.
I have tried almost everything I can come up with: My code is still in its simplest stage, so theres not too many things to bug the system.
I know this may sound annoying: But here's my code. If you would take a really quick look at it, you might be able to spot what I have stared myself blind at.
I really appreciate all kinds of hints to what may be causing me trouble for longer time than it takes to read the complete Intel manual hundreds of times.
Here comes the code and system status:
Code: Select all
;This is the start of the boot sequence. It is loaded by the bootloader to 0x8000.
;After this (still in real mode) my kernel (A set of system calls) and the complete IDT is loaded to 0x00030000 and 0x0004000 respectively.
;Right after this, a jump is performed to the tricky bit:
enterpmode:
;Clear interrupt flag
cli
;Enable A20
in al, 0x92
or al, 00000010b
out 0x92, al
;Get memory size
mov ah, 0x88
int 0x15
jc error_rmode
;ax=Contiguous KB starting at 0x00100000
shr ax, 0x06
;ax=Contiguous 64KB blocks starting at 0x00100000
add ax, 0x10
;ax=Contiguous 64KB blocks starting at 0x00000000
;Store for later use
mov [mem_size], ax
jmp @f
mem_size: dw 0x0000
@@:
;Set up the three first GDT entries (NULL, K_CODE, K_DATA)
mov cx, gdt_template
mov dx, 0x0000;Table start offset
mov ax, 0x5000;Table start segment
mov es, ax
@@:
cmp cx, gdt_template_end
jae gdt_template_end
mov bx, cx
mov al, [bx]
mov bx, dx
mov [es:bx], al
inc cx
inc dx
jmp @b
gdt_template:;these entries have been checked more times than humanly possible in two months.
;NULL
dw 0x0000;limit low
dw 0x0000;base low
db 0x00;base middle
db 00000000b;access
db 00000000b;flags/limit high
db 0x00;base high
;K_CODE:
dw 0xffff;limit low
dw 0x0000;base low
db 0x00;base middle
db 10011010b;access
db 11001111b;flags/limit high
db 0x00;base high
;K_DATA:
dw 0xffff;limit low
dw 0x0000;base low
db 0x00;base middle
db 10010010b;access
db 11001111b;flags/limit high
db 0x00;base high
gdt_template_end:
;Load GDT (BASE=0x00050000 SIZE=0xffff)
lgdt [gdtr_template]
jmp @f
gdtr_template:
dw 0xffff;limit
dd 0x00050000;offset
@@:
;I have tried inserting a hang here. Result: No tripple fault.
;Set bit 0 of cr0 (Enable protected mode)
mov eax, cr0
or eax, 0x00000001
mov cr0, eax
use32
;Jump into segment 0x0008 (K_CODE)
jmp far 0x0008:@f
@@:
;Tried another hang here. Processor never reaches it: Tripple fault. I assume this is because of some techincal stuff related to PMode...?