Page 2 of 5
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 8:30 am
by rdos
Brendan wrote:
If the emulator emulates the BIOS/VBE code's instructions but reads/writes to real physical addresses and IO ports, then any devices (that respond to reads/writes to those real physical addresses and IO ports) won't know the difference. In that way you can (in theory) run BIOS/VBE code, including software interrupts and IRQ handlers.
However; the BIOS/VBE code makes assumptions about the state of hardware, and the hardware's state must match
the assumptions that BIOS/VBE code makes for those reads/writes to real physical addresses and IO ports to work correctly. For a simple example; if you reconfigure the PIC chips like you should, then any BIOS code that accesses the PIC chip/s will get all confused and broken. To fix that you could also emulate the PIC chips, so that you can reconfigure the real PIC chips and emulate fake PIC chips to satisfy the BIOS. The same applies to any hardware that you touch (e.g. emulate any/all hardware that you've reconfigured, to keep the BIOS/VBE happy).
Theoretically, sure, but in the real world the VESA BIOS doesn't have much connection to ordinary PC BIOS hardware, and it shouldn't in order to not need to be customized to particular hardware platforms (other than other video chips). That means you won't see VESA BIOSes access the PIC chip, or any other non-video hardware. It won't call non-standard BIOS software ints. Actually, a typical VESA BIOS might rely on functional timer tics, but not much more than that.
Brendan wrote:
Of course a decent OS will take full control of all hardware (including reconfiguring PIC chips, reserving the right to change PCI configuration space for any/all devices, using all RAM for whatever it likes, etc); and an OS that isn't crap will also be designed to support UEFI one day (where there's no guarantee that any hardware was ever in the state that VBE code expects and no guarantee that the video card itself actually has a ROM containing VBE). For these reasons it's far better to set a high resolution video mode during boot using whatever services the firmware provides (VBE for BIOS, and UGA or GOP for UEFI), before the OS starts doing its job (e.g. before the OS takes control of the computer and starts reconfiguring everything to suit itself). In this case you have no need for a large, complex/unstable, slow and ugly emulator to execute code that may or may not exist.
I think it is indeed possible to fool the UEFI to do video-mode switches for you even after you have exited boot-services. Apparently, the whole UEFI BIOS is kept in a small memory arena which can be detected during boot, and saved. I think it is very possible that you can just save all the code & data in the UEFI area, exit boot services, and then setup it again in an isolated environment and then call the mode switch code at any point. It's just sloppy design that doesn't allow this already in the official documentation of UEFI. After all, this is no different from switching to V86 mode and executing the VESA mode set from a completely altered environment. A decent video BIOS shouldn't care about other hardware state than the video hardware state, and if it does, it is severely broken.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 8:37 am
by rdos
PearOs wrote:Nessphoro wrote:I don't really understand your issue.
Basically I want to write a 8086 Emulator to access real mode BIOS interrupts. What I am wondering and trying to understand is how a Real Mode Emulator running in Protected Mode allows BIOS interrupts. Is this because the BIOS code running in the Emulator for example when you call Int10h is called, the code behind that interrupt is ran in the Emulator right?
Thanks, Matt
I'm trying to access the VBE in Protected mode by writing an Emulator.
If you are in protected mode (not in long mode), then you don't need an emulator. All you need is to create a iretd callback frame with the V86 bit set, and then execute it. You also need to handle a few faults from V86 mode, but if you have a processor with VME, you don't even need to emulate all IOPL-sensitive instructions, but can let the processor handle the virtual interrupt state automatically. You setup the call to int 10h by loading the original IVT entry at physical address 40h (offset at 40h, segment at 42h).
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 9:45 am
by Antti
rdos wrote:I think it is indeed possible to fool the UEFI to do video-mode switches for you even after you have exited boot-services.
There are boot services and run-time services. The Graphics Output Protocol (GOP) is a boot service like you suggested. Using boot services after ExitBootServices() is not supported. If you found a way to run it afterwards, it would be risky business anyway. Abstractions should be taken seriously. Using interfaces like they are meant to be used will guarantee that your system is forward compatible.
rdos wrote:I think it is very possible that you can just save all the code & data in the UEFI area, exit boot services, and then setup it again in an isolated environment and then call the mode switch code at any point.
This is very scary. I would not even think about it.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 11:45 am
by rdos
Antti wrote:
There are boot services and run-time services. The Graphics Output Protocol (GOP) is a boot service like you suggested. Using boot services after ExitBootServices() is not supported. If you found a way to run it afterwards, it would be risky business anyway.
It is actually as easy as setting up an V86 environment for the VESA BIOS. You just create the environment by copying the exact contents of the UEFI code & data sections from
before you did ExitBootServices, and UEFI will have no idea it has been manipulated. This is possible since you can setup UEFI using your own paging structures. This will be no more risky than running VESA BIOS code with altered hardware configuration. A sane UEFI GOP should not rely on hardware settings for anything else than the graphics system, and when nothing touches the graphics systems this should be safe.
Antti wrote:
Abstractions should be taken seriously. Using interfaces like they are meant to be used will guarantee that your system is forward compatible.
Any abstraction that is meant to deny important functionality (dynamic mode switching without native drivers) should be manipulated.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:03 pm
by PearOs
madanra wrote:PearOs wrote:I have never really done this before, isn't INT 10h remapped because I setup my own table so that I could get interrupts working. Or is it still intact somehow?
The real mode
Interrupt Vector Table (IVT) is stored in the first 1KB of RAM, so you can look it up there, as long as neither isolinux nor your OS has overwritten that part of RAM.
Thank you so much. I think I finally get this now. So what I will do is lookup where Int10h is pointing to. Then write a 8086 Emulator, point it to that address and then when I want to set a mode for example, I just set the registers in the emulator like you would in real mode, tell it to run and let is emulate that code. Thus allowing me to run the VBE Bios.
Hopefully I'm right on that.
Thanks, Matt
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:22 pm
by Owen
rdos wrote:Antti wrote:
There are boot services and run-time services. The Graphics Output Protocol (GOP) is a boot service like you suggested. Using boot services after ExitBootServices() is not supported. If you found a way to run it afterwards, it would be risky business anyway.
It is actually as easy as setting up an V86 environment for the VESA BIOS. You just create the environment by copying the exact contents of the UEFI code & data sections from
before you did ExitBootServices, and UEFI will have no idea it has been manipulated. This is possible since you can setup UEFI using your own paging structures. This will be no more risky than running VESA BIOS code with altered hardware configuration. A sane UEFI GOP should not rely on hardware settings for anything else than the graphics system, and when nothing touches the graphics systems this should be safe.
Until you realize that the GOP implementation relies upon the UEFI boot services, and that calling into those has a tendency to not work after ExitBootServices has reconfigured all the hardware to reflect the fact that its' handing off. For example, GOP mode setting might require a timeout, but of course you have taken control of the system timers...
Or, boot services might somehow decide that a DHCP timer has expired, causing the network stack to try to send out a DHCP request. It might even succeed, configuring receive DMA and overwriting some portion of memory with random network packets.
Hell, answer me this: how do you deal with the GOP code calling the UEFI memory allocator?
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:30 pm
by PearOs
I'm totally lost. I don't know what the UEFI boot services are. I mean from what I understand it's as simple as just writing an advanced 8086 emulator that is almost exactly like the real thing and then just running the code at 10h which would be the VBE Bios. But maybe I missing some info here.
Thanks, Matt
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:46 pm
by rdos
Owen wrote:
Until you realize that the GOP implementation relies upon the UEFI boot services, and that calling into those has a tendency to not work after ExitBootServices has reconfigured all the hardware to reflect the fact that its' handing off. For example, GOP mode setting might require a timeout, but of course you have taken control of the system timers...
Again, if the system is sane, GOP shouldn't rely on UEFI boot services that are hardware dependent.
Also, as far as I understand the interface at this point, it is perfectly possible to replace UEFI services that deal with delays and timers with a native interface.
Owen wrote:
Or, boot services might somehow decide that a DHCP timer has expired, causing the network stack to try to send out a DHCP request. It might even succeed, configuring receive DMA and overwriting some portion of memory with random network packets.
It can't. The UEFI will not be linked to any IRQ, so it won't be notified about DHCP events.
This is similar as in the BIOS case. You don't need the full BIOS running in order to support VESA BIOS video mode changes. It is typically enough to have a working int 8/1C timer interrupt.
Owen wrote:
Hell, answer me this: how do you deal with the GOP code calling the UEFI memory allocator?
Change the UEFI memory allocator service (if needed).
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:53 pm
by PearOs
Ok, if someone could answer this for me I would really appreciate it. So the Interrupt Vector Table in real mode contains INT 10h right? If this is the case, 0x00-0x1F are reserved but 0x00-0x13 are error handlers so where is 10h located then? Because you call it in real mode with "int 10h" right? So what number is it in the table? Thanks, Matt
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 12:57 pm
by rdos
PearOs wrote:Ok, if someone could answer this for me I would really appreciate it. So the Interrupt Vector Table in real mode contains INT 10h right? If this is the case, 0x00-0x1F are reserved but 0x00-0x13 are error handlers so where is 10h located then? Because you call it in real mode with "int 10h" right? So what number is it in the table? Thanks, Matt
I told you above. The entry for int 10h is at 40h. 40h is the offset and 42h is the segment.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 1:06 pm
by PearOs
rdos wrote:PearOs wrote:Ok, if someone could answer this for me I would really appreciate it. So the Interrupt Vector Table in real mode contains INT 10h right? If this is the case, 0x00-0x1F are reserved but 0x00-0x13 are error handlers so where is 10h located then? Because you call it in real mode with "int 10h" right? So what number is it in the table? Thanks, Matt
I told you above. The entry for int 10h is at 40h. 40h is the offset and 42h is the segment.
Ah ok sorry. I haven't had my coffee this morning. I must have totally missed that.
Thanks, rdos.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 1:36 pm
by DavidCooper
PearOs wrote:I'm totally lost. I don't know what the UEFI boot services are. I mean from what I understand it's as simple as just writing an advanced 8086 emulator that is almost exactly like the real thing and then just running the code at 10h which would be the VBE Bios. But maybe I missing some info here.
Don't worry about the UEFI stuff - it relates to machines with no BIOS (or which have it as well as a BIOS), but you probably won't want to get into that yet. What you need to do is decide on a strategy for now and stick to it. The options are to switch back to real mode to change screen mode, but that's impractical once your OS has advanced beyond a certain point, or you can use V86 mode (complicated), or you can use an emulator to run the BIOS code, but the easiest thing to do is what Brendan always tells everyone to do, and that's to set up the best screen mode the machine offers and don't change it again. There's very little reason to want to change it again anyway other than for the sake of playing with older screen modes (which you really shouldn't need to do - all software should be adaptable enough to adapt itself to whatever resolution of screen is thrown at it), so just save yourself the effort and program your OS to select the best screen mode for the machine it finds itself on and don't change it after that.
You might need to get your OS to ask the user to select what they consider to be the best mode out of the ones available, perhaps displaying a square on the screen so that they can switch through a number of different modes to find one that actually makes the square look the most square. In some cases there will be no mode offered by VESA that results in squares looking square, so the only cure for that would be to write your own driver to control the screen on that kind of machine - until you do that, your OS will always have to compromise. The alternative to offering the user a choice of screen mode is simply to select the highest-resolution mode that is offered unless it is 3:4 AND there are also non-3:4 modes offered by VESA, in which case the highest-resolution non-3:4 mode is likely to be a better fit, though it will not necessarily be the best fit available. For example, on a machine with a 1080x1920 screen where VESA does not offer you that mode, selecting 1024x600 will make squares look more square than 1280x800. I don't know how other people handle this.
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 6:28 pm
by PearOs
DavidCooper wrote:PearOs wrote:I'm totally lost. I don't know what the UEFI boot services are. I mean from what I understand it's as simple as just writing an advanced 8086 emulator that is almost exactly like the real thing and then just running the code at 10h which would be the VBE Bios. But maybe I missing some info here.
Don't worry about the UEFI stuff - it relates to machines with no BIOS (or which have it as well as a BIOS), but you probably won't want to get into that yet. What you need to do is decide on a strategy for now and stick to it. The options are to switch back to real mode to change screen mode, but that's impractical once your OS has advanced beyond a certain point, or you can use V86 mode (complicated), or you can use an emulator to run the BIOS code, but the easiest thing to do is what Brendan always tells everyone to do, and that's to set up the best screen mode the machine offers and don't change it again. There's very little reason to want to change it again anyway other than for the sake of playing with older screen modes (which you really shouldn't need to do - all software should be adaptable enough to adapt itself to whatever resolution of screen is thrown at it), so just save yourself the effort and program your OS to select the best screen mode for the machine it finds itself on and don't change it after that.
You might need to get your OS to ask the user to select what they consider to be the best mode out of the ones available, perhaps displaying a square on the screen so that they can switch through a number of different modes to find one that actually makes the square look the most square. In some cases there will be no mode offered by VESA that results in squares looking square, so the only cure for that would be to write your own driver to control the screen on that kind of machine - until you do that, your OS will always have to compromise. The alternative to offering the user a choice of screen mode is simply to select the highest-resolution mode that is offered unless it is 3:4 AND there are also non-3:4 modes offered by VESA, in which case the highest-resolution non-3:4 mode is likely to be a better fit, though it will not necessarily be the best fit available. For example, on a machine with a 1080x1920 screen where VESA does not offer you that mode, selecting 1024x600 will make squares look more square than 1280x800. I don't know how other people handle this.
Thank you for the reply David, that really helps sum up some of my questions. Though one thing I still wonder is this. On the Interrupt Vector Table wiki, it says that in real mode the interrupt 0x10 offset 0x40 is x87 FPU Error. So how is Int 10 used in real mode if its a error? Or is this false info and Int 10, offset 0x40 is really the VBE Bios like people are saying?
Thanks, Matt
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 8:50 pm
by PearOs
Out of curiosity would it be possible just to convert the Video Bios to 32bit assembly instructions and then boot that? Or is that entirely impossible? Thanks, Matt
Re: Running a VBE Bios or VESA Bios?
Posted: Sat Oct 05, 2013 11:31 pm
by Brendan
Hi,
PearOs wrote:Out of curiosity would it be possible just to convert the Video Bios to 32bit assembly instructions and then boot that? Or is that entirely impossible? Thanks, Matt
It's theoretically possible to translate the code from 16-bit to 32-bit (or even from 16-bit 80x86 to ARM or something else). However, it'd be the most complex (and most error prone/buggy) method; and worse than all the other methods.
PearOs wrote:On the Interrupt Vector Table wiki, it says that in real mode the interrupt 0x10 offset 0x40 is x87 FPU Error. So how is Int 10 used in real mode if its a error? Or is this false info and Int 10, offset 0x40 is really the VBE Bios like people are saying?
Once upon a time the FPU was a separate chip (not built into the CPU at all), and FPU errors were routed through the PIC chips to ISA IRQ 0x13 (interrupt 0x75). This meant that you could get the interrupt long after the error occurred (which caused race conditions). It was also slow. Worse, when there's more than 1 FPU (e.g. modern multi-core systems) it doesn't work at all because there's no way to determine which FPU caused the error.
To fix all of this, for 80486 and later (where the FPU is built into the CPU) Intel introduced "native FPU exceptions", where FPU errors generate exception 0x10. This is enabled by setting a bit in CR0. All modern OSs use the "native FPU exceptions". Sadly (due to backward compatibility) the BIOS had to remain retarded, so the BIOS doesn't enable "native FPU exceptions" and uses the old and broken "FPU errors routed through IRQ13" mess.
PearOs wrote:I don't know what the UEFI boot services are.
Over the years the BIOS gained a lot of obsolete puss due to backward compatibility (A20 gate, FPU error handling, PIC chips, etc) and limitations that seemed OK at the time became very painful (640 KiB of RAM, 128 KiB of "device ROM" space, etc). To fix all of the problems with the BIOS, it's being replaced by something completely different called UEFI. UEFI provides "boot time services" (that an OS can only use during boot) and "run time services" (that an OS can use during boot or after boot). The idea is that when an OS has finished using UEFI's boot time services (e.g. the OS is ready to take control of the hardware itself) it calls an "exit boot services" function, which allows UEFI to free a lot of resources (RAM, etc) that it was using to provide the boot time services.
Of course for UEFI none of the obsolete puss needs to exist because it's all been replaced by something "better". Currently (because UEFI is still sort of new) most hardware still supports the obsolete puss (in case the hardware is used for BIOS); but it'd be a massive design flaw for any modern software to rely on the existence of any of the obsolete puss; including VBE (and the "legacy VGA" display memory window, and legacy VGA IO port routing, etc).
Cheers,
Brendan