Unsetting PM bit in cr0

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
leledumbo
Member
Member
Posts: 103
Joined: Wed Apr 23, 2008 8:46 pm

Unsetting PM bit in cr0

Post 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.
zhak
Member
Member
Posts: 25
Joined: Wed Jul 30, 2008 10:25 am

Re: Unsetting PM bit in cr0

Post 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
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Unsetting PM bit in cr0

Post 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.
leledumbo
Member
Member
Posts: 103
Joined: Wed Apr 23, 2008 8:46 pm

Re: Unsetting PM bit in cr0

Post 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.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Unsetting PM bit in cr0

Post 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.
Post Reply