cli ;Don't allow interrupts during this
push ds ;Save real mode selectors
push es
xor eax, eax ;Patch the GDT psuedo-descriptor
mov ax, ds ; (assuming ds points the segment containing the GDT)
shl eax, 4
add [GDT+2], eax
lgdt [GDT] ;Load the GDT
mov eax, cr0 ;Switch to pmode
inc ax
mov cr0, eax
mov bx, flat_data ;Our only pmode selector
mov ds, bx ;Install 4Gb limits (warning)
mov es, bx
dec ax ;Switch back to real mode
mov cr0, eax
pop es ;Restore real mode selectors
pop ds
sti ;Notice, I never needed to change the CS while in pmode.
Notice how you need the GDT functions for switching to unreal mode? Well I've tried defining them like this:
%include "gdtn.inc"
GDT start_gdt
flat_data desc 0, 0xFFFFF, D_DATA+D_WRITE+D_BIG_LIM
end_gdt
AND like this:
GDT dw 0xF, GDT, 0, 0, 0xFFFF, 0, 0x9200, 0x8F
flat_data equ 8
But neither of them work. My OS just hangs when it loads the kernel. It should display "Kernel Loaded..." before it tries to enter unreal mode, but it crashes right when the kernel loads. I'm not sure if this is a glitch with the unreal mode routine or the GDT, but I would really like it if someone could tell me if they notice something wrong.
Thanks!