Page 1 of 1

Return to real mode from long mode and back

Posted: Mon Apr 26, 2021 4:40 am
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!

Re: Return to real mode from long mode and back

Posted: Mon Apr 26, 2021 5:33 am
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.

Re: Return to real mode from long mode and back

Posted: Mon Apr 26, 2021 5:56 am
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.

Re: Return to real mode from long mode and back

Posted: Mon Apr 26, 2021 6:00 am
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.

Re: Return to real mode from long mode and back

Posted: Tue Apr 27, 2021 1:32 am
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

Re: Return to real mode from long mode and back

Posted: Tue Apr 27, 2021 2:16 am
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?