Return to real mode from long mode and back

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
User avatar
catOS
Member
Member
Posts: 28
Joined: Tue Mar 31, 2020 6:28 pm

Return to real mode from long mode and back

Post by catOS »

I'm writing a bootloader that supports BIOS and UEFI and I need to use the VESA functions for the getting framebuffer. I understand that only way to access this functionality is through BIOS interrupts. The problem is I'm in long mode and I would need to switch back into real mode somehow. There's an OSDev page example (https://wiki.osdev.org/Real_Mode#x86_Assembly_Example) for switching from 32-bit protected mode to real mode but not long mode -> real mode.

According to the AMD manual, to return to protected mode (as protected mode is a prerequisite for switching to real mode)

To return from long mode to legacy protected mode with paging enabled, software must deactivate and disable long mode using the following sequence:
  • 1. Switch to compatibility mode and place the processor at the highest privilege level (CPL=0).2.
    2. Deactivate long mode by clearing CR0.PG to 0. This causes the processor to clear the LMA bit to 0. The MOV CR0 instruction used to disable paging must be located in an identity-mapped page. Once paging is disabled, the processor behaves as a standard 32-bit x86 processor.
    3. Load CR3 with the physical base-address of the legacy page tables.
    4. Disable long mode by clearing EFER.LME to 0.
    5. Enable legacy page-translation by setting CR0.PG to 1. The instruction following the MOV CR0 that enables paging must be a branch, and both the MOV CR0 and the following branch instruction must be located in an identity-mapped page.
but it does not tell you how to jump back into compatibility mode in step 1. I need help!
Visit ackOS's GitHub page:
>> https://github.com/ackOS-project/ackOS <<
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Return to real mode from long mode and back

Post by Octocontrabass »

catOS wrote:The problem is I'm in long mode and I would need to switch back into real mode somehow.
Why doesn't your BIOS bootloader call the VBE functions before switching away from real mode?

There's no VBE in UEFI.
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: Return to real mode from long mode and back

Post by rdos »

catOS wrote:I'm writing a bootloader that supports BIOS and UEFI and I need to use the VESA functions for the getting framebuffer. I understand that only way to access this functionality is through BIOS interrupts. The problem is I'm in long mode and I would need to switch back into real mode somehow. There's an OSDev page example (https://wiki.osdev.org/Real_Mode#x86_Assembly_Example) for switching from 32-bit protected mode to real mode but not long mode -> real mode.

According to the AMD manual, to return to protected mode (as protected mode is a prerequisite for switching to real mode)

To return from long mode to legacy protected mode with paging enabled, software must deactivate and disable long mode using the following sequence:
  • 1. Switch to compatibility mode and place the processor at the highest privilege level (CPL=0).2.
    2. Deactivate long mode by clearing CR0.PG to 0. This causes the processor to clear the LMA bit to 0. The MOV CR0 instruction used to disable paging must be located in an identity-mapped page. Once paging is disabled, the processor behaves as a standard 32-bit x86 processor.
    3. Load CR3 with the physical base-address of the legacy page tables.
    4. Disable long mode by clearing EFER.LME to 0.
    5. Enable legacy page-translation by setting CR0.PG to 1. The instruction following the MOV CR0 that enables paging must be a branch, and both the MOV CR0 and the following branch instruction must be located in an identity-mapped page.
but it does not tell you how to jump back into compatibility mode in step 1. I need help!
You jump to compatibility mode by loading a CS selector (a far jmp or call) that doesn't have the long mode bit set. Of course, you must jump to code that is 32-bit for this to work.
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: Return to real mode from long mode and back

Post by rdos »

Octocontrabass wrote:
catOS wrote:The problem is I'm in long mode and I would need to switch back into real mode somehow.
Why doesn't your BIOS bootloader call the VBE functions before switching away from real mode?

There's no VBE in UEFI.
I think this is unknown and dependent on BIOS. Some BIOSes appear to implement UEFI on top of the ordinary BIOS, and actually have the real-mode interrupt vectors & associated code mapped at the right positions. Some might just have it for legacy reasons and implement UEFI in parallel. Still, I anticipate this will become less common and it is not something that should be relied on.
User avatar
catOS
Member
Member
Posts: 28
Joined: Tue Mar 31, 2020 6:28 pm

Re: Return to real mode from long mode and back

Post by catOS »

just to clarify, in this bootloader VESA/VBE is only used if booted with BIOS. else in UEFI mode it will use GOP
Visit ackOS's GitHub page:
>> https://github.com/ackOS-project/ackOS <<
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Return to real mode from long mode and back

Post by iansjack »

catOS wrote:just to clarify, in this bootloader VESA/VBE is only used if booted with BIOS. else in UEFI mode it will use GOP
Then Octocontrabass question still stands. Why not just call the functions before switching to protected (and then long) mode?
Post Reply