Page 1 of 1
Unsetting PM bit in cr0
Posted: Mon Aug 04, 2008 11:48 pm
by leledumbo
OK, I've read many articles about vm86 and unreal mode, but none tells me how to enable it. One (I forgot which one) told me to unset PM bit in cr0 (0-th bit) but when I try it, I think I'm still in PM mode since I can't call BIOS interrupts. Instead, it call my interrupt handler.
I need to set video mode which can't be done in PM mode.
Re: Unsetting PM bit in cr0
Posted: Tue Aug 05, 2008 12:33 am
by zhak
To set up unreal mode for data segments you need to do smth like:
Code: Select all
cli
lgdt [gdtr]
mov eax, cr0
or al, 1
mov cr0, eax
mov ax, 08
mov gs, ax
mov fs, ax
;. . . <<<< any other segment registers if needed
mov eax, cr0 ;
and al, 0FEh ; this clears PM bit
mov cr0, eax ;
sti
...
gdt: dq 0,00CF92000000FFFFh ;only NULL and Data Segment descriptors
gdtr: dw gdtr-gdt-1
dd gdt
Here unreal mode is enabled for segment registers gs and fs only
Re: Unsetting PM bit in cr0
Posted: Tue Aug 05, 2008 6:19 am
by bewing
Besides unsetting the PM bit, you need to "undo" the things you did to get into pmode in the first place.
So, after unsetting the bit, you need to do a far jump, to set CS back to 0 (or some other reasonable value). Then reset the other segment registers.
Then, you need to do an LIDT to switch back to the real mode IVT at physical address 0 (or a copy of it). Otherwise, the IDT register on the CPU will still be pointing to your pmode IDT.
Re: Unsetting PM bit in cr0
Posted: Wed Aug 06, 2008 1:45 am
by leledumbo
Then, you need to do an LIDT to switch back to the real mode IVT ...
How can I get real mode IVT? I use grub for booting and AFAIK the kernel is already in PMode from beginning because PM bit is already set before jumping to kernel.
Re: Unsetting PM bit in cr0
Posted: Wed Aug 06, 2008 1:54 am
by bewing
The Real Mode IVT is always in the first 1K of physical memory, from 0 to 0x3ff. The BIOS initialization code puts it there. GRUB does not overwrite it.