Mode Switching Help

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.
PearOs
Member
Member
Posts: 194
Joined: Mon Apr 08, 2013 3:03 pm
Location: Usually at my keyboard!

Mode Switching Help

Post by PearOs »

Hey guys ,well I wanted to stay away from this as much as possible. But it needs to be done, so my operating system uses ISOLinux to boot into protected mode, I then setup a few things and jump to long mode. This works just fine. But I want to make some BIO calls using Real Mode. So in order to do this I have a few options.

Way1:
Jump to real mode from long mode
Make the BIOS call
Jump to protected mode
Reset our stuff and Jump to long mode

Way2:
Jump to protected mode from long mode
Jump to Real Mode
Run the BIOS Call
Jump to Protected Mode
Reset our stuff for Long Mode
Jump To Long Mode

Way3:
Jump to Real Mode from Long Mode
Jump to Long Mode From Real Mode

I am pretty sure Way3, is out of the picture. I don't see it being possible. But I think Way2 would work best.
What do you guys think? And can someone please provide some Assembly code for going to protected mod from long mode, and from protected mode to real mode. And then real mode to protected mode. I have my own code to get into long mode so that's not a problem. Thanks guys, Matt
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Mode Switching Help

Post by Mikemk »

PearOs wrote:I am pretty sure Way3, is out of the picture. I don't see it being possible. But I think Way2 would work best.
What do you guys think? And can someone please provide some Assembly code for going to protected mod from long mode, and from protected mode to real mode. And then real mode to protected mode. I have my own code to get into long mode so that's not a problem. Thanks guys, Matt
Way 3 is perfectly possible, just not recommended, because you can't recover if something goes wrong. I think way 1 is best, short of using an emulator.
As for the code, that's all in the wiki.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
PearOs
Member
Member
Posts: 194
Joined: Mon Apr 08, 2013 3:03 pm
Location: Usually at my keyboard!

Re: Mode Switching Help

Post by PearOs »

Thanks! Well is there anyway you can show me some links/code to accomplish way 3? I know its not recommended but for learning purposes it would be nice to have. As for Way1 can someone please provide some links/code to accomplish that? I have been reading through the AMD64 Programmers Manual, but switching modes is a little confusing at times. Thanks a ton! - Matt


So I found out how to enter long mode directly from real mode here: http://bcos.hopto.org/temp/init.html
but now I need to know how to enter real mode from long mode.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Mode Switching Help

Post by Mikemk »

cli, unset bits 0 and 31 of cr0, reload ivt, sti
I'm sure you can figure out the details from that general outline.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
PearOs
Member
Member
Posts: 194
Joined: Mon Apr 08, 2013 3:03 pm
Location: Usually at my keyboard!

Re: Mode Switching Help

Post by PearOs »

m12 wrote:cli, unset bits 0 and 31 of cr0, reload ivt, sti
I'm sure you can figure out the details from that general outline.
Ok, so basically I just disable interrupts, unset the bits reload the interrupt vector table and restore interrupts. But what I don't quite understand is, just unsetting bit 0, and 31 from cr0 puts me in real mode? Is that correct? Thanks for the help, Matt
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Mode Switching Help

Post by Brendan »

Hi,
PearOs wrote:Ok, so basically I just disable interrupts, unset the bits reload the interrupt vector table and restore interrupts. But what I don't quite understand is, just unsetting bit 0, and 31 from cr0 puts me in real mode? Is that correct? Thanks for the help, Matt
To correctly switch from protected mode to real mode:
  • disable IRQs; set the IDT limit to zero (to ensure NMI causes triple fault rather than chaos), disable paging if necessary, and load "16-bit compatible" descriptors into all segment registers (e.g. 16-bit, 64 KiB limit)
  • clear bit 0 of CR0 to disable protected mode
  • load all segment registers with actual real mode values
Switching to real mode correctly is *not* enough to make the BIOS happy. The BIOS expects that the IDT/IVT will be at 0x00000000, so you need to load the BIOS' IVT after you've switched to real mode. The BIOS also expects things like IO APIC/s disabled, PIC chips configured a certain way, PIT still set to 18.2 Hz, local APIC interrupt sources disabled (local APIC timer, performance monitoring interrupt, etc), PCI devices still using the resources the BIOS assigned (if any), hard disks still in the "emulate legacy PATA" mode (or not), USB controllers still in the "emulate PS/2" (or not), ACPI disabled, etc. Of course a good OS will change most of these things; so a good OS would need to cripple everything (e.g. cancel networking connections, unmount USB flash devices, cancel any audio input/output, trash its own USB keyboard/mouse support, stop doing any power management, etc) before even considering a switch back to real mode.

However; this is only one of the reason why you shouldn't be touching real mode after boot (after you've initialised devices, etc to suit the OS). The other reason is that BIOS is obsolete/deprecated and real mode is entirely useless for UEFI.

Basically; for a well designed OS (e.g. designed to be easy to port to UEFI one day, hopefully before it's too late) you don't want to touch the BIOS after boot; and you do want to make the boot loader responsible for doing things like finding ACPI tables, setting up a default video mode, loading anything the OS needs from disk (including disk drivers), getting a memory map, etc (so that the OS itself doesn't have any reason to touch the firmware after boot).

This also means that you'd need native video drivers to be able to switch video modes after boot; but that's fine - end users typically don't switch video modes while the OS is running unless they're playing 3D games, and end users won't be playing 3D games without hardware acceleration (or without a native video driver).

If you want, you can make this a little less hassle for the end user - e.g. the boot loader can generate a list of possible video modes and give the list to the OS; and the OS can let the user choose a mode from this list and set a "desired video mode for next boot" somewhere for the boot loader to find. That way the end user can change video modes using some sort of dialog box just like they would if you had a video driver, but when they click "OK/Save changes" the OS would tell them "Need to reboot to make these changes". That way, the end user doesn't need to diddle about with messy boot loader configuration manually. Also note that when you do have a native video driver, the native video driver might set the "desired video mode number for next boot" to avoid/minimise video mode switches during boot (e.g. native video driver starts and sees that the video mode it wants has already been set).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
PearOs
Member
Member
Posts: 194
Joined: Mon Apr 08, 2013 3:03 pm
Location: Usually at my keyboard!

Re: Mode Switching Help

Post by PearOs »

Brendan wrote:Hi,
PearOs wrote:Ok, so basically I just disable interrupts, unset the bits reload the interrupt vector table and restore interrupts. But what I don't quite understand is, just unsetting bit 0, and 31 from cr0 puts me in real mode? Is that correct? Thanks for the help, Matt
To correctly switch from protected mode to real mode:
  • disable IRQs; set the IDT limit to zero (to ensure NMI causes triple fault rather than chaos), disable paging if necessary, and load "16-bit compatible" descriptors into all segment registers (e.g. 16-bit, 64 KiB limit)
  • clear bit 0 of CR0 to disable protected mode
  • load all segment registers with actual real mode values
Switching to real mode correctly is *not* enough to make the BIOS happy. The BIOS expects that the IDT/IVT will be at 0x00000000, so you need to load the BIOS' IVT after you've switched to real mode. The BIOS also expects things like IO APIC/s disabled, PIC chips configured a certain way, PIT still set to 18.2 Hz, local APIC interrupt sources disabled (local APIC timer, performance monitoring interrupt, etc), PCI devices still using the resources the BIOS assigned (if any), hard disks still in the "emulate legacy PATA" mode (or not), USB controllers still in the "emulate PS/2" (or not), ACPI disabled, etc. Of course a good OS will change most of these things; so a good OS would need to cripple everything (e.g. cancel networking connections, unmount USB flash devices, cancel any audio input/output, trash its own USB keyboard/mouse support, stop doing any power management, etc) before even considering a switch back to real mode.

However; this is only one of the reason why you shouldn't be touching real mode after boot (after you've initialised devices, etc to suit the OS). The other reason is that BIOS is obsolete/deprecated and real mode is entirely useless for UEFI.

Basically; for a well designed OS (e.g. designed to be easy to port to UEFI one day, hopefully before it's too late) you don't want to touch the BIOS after boot; and you do want to make the boot loader responsible for doing things like finding ACPI tables, setting up a default video mode, loading anything the OS needs from disk (including disk drivers), getting a memory map, etc (so that the OS itself doesn't have any reason to touch the firmware after boot).

This also means that you'd need native video drivers to be able to switch video modes after boot; but that's fine - end users typically don't switch video modes while the OS is running unless they're playing 3D games, and end users won't be playing 3D games without hardware acceleration (or without a native video driver).

If you want, you can make this a little less hassle for the end user - e.g. the boot loader can generate a list of possible video modes and give the list to the OS; and the OS can let the user choose a mode from this list and set a "desired video mode for next boot" somewhere for the boot loader to find. That way the end user can change video modes using some sort of dialog box just like they would if you had a video driver, but when they click "OK/Save changes" the OS would tell them "Need to reboot to make these changes". That way, the end user doesn't need to diddle about with messy boot loader configuration manually. Also note that when you do have a native video driver, the native video driver might set the "desired video mode number for next boot" to avoid/minimise video mode switches during boot (e.g. native video driver starts and sees that the video mode it wants has already been set).


Cheers,

Brendan
Brendan, I think your right my friend. Alright you've convinced me otherwise. So the only issue with me setting up stuff in Real Mode before Switching to Protected Mode, and then Long Mode, is that My bootloader ISOLinux, boots me into Protected Mode for me. It gives me VBE Information because of the Multiboot structure, but I would need to go from protected mode after ISOLinux boots my code, back to real mode, get my VBE Modes, set the highest livable mode and go back to protected mode and then Long Mode. Or is there an easier way? Thanks, Matt

Or what I could do from what I read somewhere, is reboot the PC. Which causes the BIOS to go back to real mode, and then run some real mode code and jump to long mode or protected mode. But I'm not sure if that would be very safe/feasible.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Mode Switching Help

Post by Brendan »

Hi,
PearOs wrote:Brendan, I think your right my friend. Alright you've convinced me otherwise. So the only issue with me setting up stuff in Real Mode before Switching to Protected Mode, and then Long Mode, is that My bootloader ISOLinux, boots me into Protected Mode for me. It gives me VBE Information because of the Multiboot structure, but I would need to go from protected mode after ISOLinux boots my code, back to real mode, get my VBE Modes, set the highest livable mode and go back to protected mode and then Long Mode. Or is there an easier way? Thanks, Matt
That sounds about right to me (I couldn't find any way to tell ISOLinux or SYSLINUX to boot with a graphics mode) .
PearOs wrote:Or what I could do from what I read somewhere, is reboot the PC. Which causes the BIOS to go back to real mode, and then run some real mode code and jump to long mode or protected mode. But I'm not sure if that would be very safe/feasible.
You should be able to set CMOS location 0x0F to 0x0A and put the address to far jump to at 0x00000467, then reset the CPU (e.g. with a triple fault). This may or may not be extremely slow (I'm not too sure how much the BIOS configures before it looks at the CMOS and does the far jump); and I don't know how reliable it is on modern computers. Switching to real using the normal way is likely to be a lot faster and a lot more reliable. ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
PearOs
Member
Member
Posts: 194
Joined: Mon Apr 08, 2013 3:03 pm
Location: Usually at my keyboard!

Re: Mode Switching Help

Post by PearOs »

Brendan wrote:Hi,
PearOs wrote:Brendan, I think your right my friend. Alright you've convinced me otherwise. So the only issue with me setting up stuff in Real Mode before Switching to Protected Mode, and then Long Mode, is that My bootloader ISOLinux, boots me into Protected Mode for me. It gives me VBE Information because of the Multiboot structure, but I would need to go from protected mode after ISOLinux boots my code, back to real mode, get my VBE Modes, set the highest livable mode and go back to protected mode and then Long Mode. Or is there an easier way? Thanks, Matt
That sounds about right to me (I couldn't find any way to tell ISOLinux or SYSLINUX to boot with a graphics mode) .
PearOs wrote:Or what I could do from what I read somewhere, is reboot the PC. Which causes the BIOS to go back to real mode, and then run some real mode code and jump to long mode or protected mode. But I'm not sure if that would be very safe/feasible.
You should be able to set CMOS location 0x0F to 0x0A and put the address to far jump to at 0x00000467, then reset the CPU (e.g. with a triple fault). This may or may not be extremely slow (I'm not too sure how much the BIOS configures before it looks at the CMOS and does the far jump); and I don't know how reliable it is on modern computers. Switching to real using the normal way is likely to be a lot faster and a lot more reliable. ;)


Cheers,

Brendan
Ok, thanks Brendan. Can you please show me some code that will take Protected Mode to Real Mode and back? This way I can set the VBE Mode and stuff. Thanks for your help - Matt
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Mode Switching Help

Post by Brendan »

Hi,
PearOs wrote:Ok, thanks Brendan. Can you please show me some code that will take Protected Mode to Real Mode and back? This way I can set the VBE Mode and stuff. Thanks for your help - Matt
Maybe check this page of the wiki. ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Mode Switching Help

Post by Gigasoft »

The BIOS also expects things like IO APIC/s disabled, PIC chips configured a certain way, PIT still set to 18.2 Hz, local APIC interrupt sources disabled (local APIC timer, performance monitoring interrupt, etc), PCI devices still using the resources the BIOS assigned (if any), hard disks still in the "emulate legacy PATA" mode (or not), USB controllers still in the "emulate PS/2" (or not), ACPI disabled, etc. Of course a good OS will change most of these things; so a good OS would need to cripple everything (e.g. cancel networking connections, unmount USB flash devices, cancel any audio input/output, trash its own USB keyboard/mouse support, stop doing any power management, etc) before even considering a switch back to real mode.
[...]
This also means that you'd need native video drivers to be able to switch video modes after boot; but that's fine - end users typically don't switch video modes while the OS is running unless they're playing 3D games, and end users won't be playing 3D games without hardware acceleration (or without a native video driver).
I don't follow. Why would video mode switching have anything to do with the (PC) BIOS? That's a separate, unrelated component, and there is no reason for it to call BIOS functions or care about hard disks, keyboards, ACPI, power management etc. Even in the case of an onboard integrated display controller, it is doubtful that the Int 10h handler should touch unrelated devices. To be on the safe side, I suppose one could set the PIT rate to 18.2 Hz and install a minimal timer handler that increments 46ch.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Mode Switching Help

Post by Combuster »

Why would video mode switching have anything to do with the (PC) BIOS?
It's real mode having everything to do with the BIOS. It'll be catching all the interrupts again even while the video card itself is not directly responsible for them.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: Mode Switching Help

Post by rdos »

I don't follow either. There is no reason why a video-mode switch (using real mode or V86 mode) would need to place APIC or any other devices in their real-mode state. If there is, the reason seems to be extremely uncommon, as I've not yet encountered any VBE implementation that needs anything else than a minimal V86 setup with a fictive timer int.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Mode Switching Help

Post by Combuster »

a minimal V86 setup with a fictive timer int.
I rest my case.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Mode Switching Help

Post by Brendan »

Hi,
rdos wrote:I don't follow either. There is no reason why a video-mode switch (using real mode or V86 mode) would need to place APIC or any other devices in their real-mode state. If there is, the reason seems to be extremely uncommon, as I've not yet encountered any VBE implementation that needs anything else than a minimal V86 setup with a fictive timer int.
So your OS is under heavy load, with IRQs (from ethernet, serial, disk, timers, etc) and IPIs (from multi-CPU TLB shootdown) flying all over the place; and you disable IRQs and call the BIOS function to switch video modes; hoping that the video BIOS doesn't do the right thing and enable IRQs, and also hoping that the massive increase in IRQ latency this causes (if the video BIOS does the wrong thing) won't cause lost IRQs, lost packets, etc?

It's a lot more likely your code is extremely buggy, your OS is never under load when you switch video modes, and you don't switch video modes often; and you think it's OK because you've been lucky and/or your idea of acceptable quality is significantly lower than mine.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply