SudoBIOS
SudoBIOS
SudoBIOS is a completely transparent 32bit protected mode BIOS extender. SudoBIOS uses simple mode switching, address translation and buffering to provide interrupt based classic (Compatibility Support Module) BIOS services while in 32bit protected mode.
A typical application is to have the boot sector or mbr load SudoBIOS as a 2nd stage (to absolute address 0x2000). A far call to that location returns in 32bit protected mode. A subset of the native BIOS functions (the common usable ones) are supported.
SudoBIOS is written in FASM (2200+ lines of Intel syntax x86 assembly language) and will assemble as is in NASM. Both output files are essentially the same (with NASM -O2). The only insignificant difference is the order of the operand (0x66) and address (0x67) override opcode pairing of the 2 assemblers.
There is a SudoBIOS demo. MikeOS32_4.4.img. It's a 1.44MB FAT12 USB flash drive image of the real mode MikeOS converted to 32bit, running in 32bit protected mode and accessing BIOS services transparently through SudoBIOS. It will boot and run as either a floppy disk or hard disk format on real hardware and QEMU. The image is a non standard floppy disk so BOCHS has trouble running it as a floppy image, but will work fine as a disk image.
The source code for MikeOS32 is MikeOS32_4.4.zip
SudoBIOS
A typical application is to have the boot sector or mbr load SudoBIOS as a 2nd stage (to absolute address 0x2000). A far call to that location returns in 32bit protected mode. A subset of the native BIOS functions (the common usable ones) are supported.
SudoBIOS is written in FASM (2200+ lines of Intel syntax x86 assembly language) and will assemble as is in NASM. Both output files are essentially the same (with NASM -O2). The only insignificant difference is the order of the operand (0x66) and address (0x67) override opcode pairing of the 2 assemblers.
There is a SudoBIOS demo. MikeOS32_4.4.img. It's a 1.44MB FAT12 USB flash drive image of the real mode MikeOS converted to 32bit, running in 32bit protected mode and accessing BIOS services transparently through SudoBIOS. It will boot and run as either a floppy disk or hard disk format on real hardware and QEMU. The image is a non standard floppy disk so BOCHS has trouble running it as a floppy image, but will work fine as a disk image.
The source code for MikeOS32 is MikeOS32_4.4.zip
SudoBIOS
Last edited by mikegonta on Sun Jun 07, 2015 9:13 am, edited 6 times in total.
Re: SudoBIOS
Having a 32-bit BIOS-like service and running MikeOS in 32-bit mode sound very interesting. Nice work! I will try, when I will get to my computer soon.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
- Alan Kay
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: SudoBIOS
Not working.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: SudoBIOS
Hi,
The only limitation is that some BIOS functions use segment registers and you can't load "real mode compatible" segment registers in protected mode; but it's enough to have "real mode DS and ES" in global variables that are set and/or read by the caller (if they care); that are loaded after switching to real mode (before passing control to BIOS interrupt handler), and are stored before switching back to protected mode.
The other problem is if you want decent protected mode exception handlers. It's entirely possible to tell the difference between an exception and an IRQ by examining the PIC's "in service" register; and possible to tell the difference between an exception with an error code and a software interrupt by examining the stack (e.g. see if "return CS" and "saved EFLAGS" look sane), and possible to tell the difference between an exception (that has no error code) and a software interrupt (by checking if "return CS:EIP - 2" points to an "int n" instruction).
Cheers,
Brendan
I took a quick look at the code, and noticed you've got different code for every single BIOS function. This is completely unnecessary - protected mode interrupt handlers can switch to real mode and transfer control to the BIOS without caring what it is.mikegonta wrote:SudoBIOS (my latest project) is a partial rewrite/update of my previous aeBIOS.
The only limitation is that some BIOS functions use segment registers and you can't load "real mode compatible" segment registers in protected mode; but it's enough to have "real mode DS and ES" in global variables that are set and/or read by the caller (if they care); that are loaded after switching to real mode (before passing control to BIOS interrupt handler), and are stored before switching back to protected mode.
The other problem is if you want decent protected mode exception handlers. It's entirely possible to tell the difference between an exception and an IRQ by examining the PIC's "in service" register; and possible to tell the difference between an exception with an error code and a software interrupt by examining the stack (e.g. see if "return CS" and "saved EFLAGS" look sane), and possible to tell the difference between an exception (that has no error code) and a software interrupt (by checking if "return CS:EIP - 2" points to an "int n" instruction).
Exactly - it could be more like 200 lines of Intel syntax x86 assembly language.mikegonta wrote:SudoBIOS is written in FASM (2400+ lines of Intel syntax x86 assembly language)
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.
Re: SudoBIOS
But can you do that consistently? The "int n" instruction at CS:EIP could be part of another, larger instruction, e.g. it could be an immediate with the most significant bytes being n and 0xCD. And how much more complex you'd want the heuristics to be in both cases? Checking bits that are hardwired to 0 and 1 in what's supposed to contain EFLAGS? Checking 16 bits of what could be CS against GDT and LDT? And also checking what could be EIP against the segment limit?Brendan wrote: and possible to tell the difference between an exception with an error code and a software interrupt by examining the stack (e.g. see if "return CS" and "saved EFLAGS" look sane), and possible to tell the difference between an exception (that has no error code) and a software interrupt (by checking if "return CS:EIP - 2" points to an "int n" instruction).
Re: SudoBIOS
The transfer is handled by the small rm_interrupt routine.Brendan wrote:I took a quick look at the code, and noticed you've got different code for every single BIOS function. This is completely unnecessary -
protected mode interrupt handlers can switch to real mode and transfer control to the BIOS ...
SudoBIOS cares.Brendan wrote:... without caring what it is.
That would be fine for a simple extender. The user would be required to call setup routines and juggle various aspects of the interface.
SudoBIOS "emulates" a 32bit protected mode BIOS transparently. 32bit input/output use only one register (not two like in RM), user
address buffers are in high memory (SudoBIOS does the translations and buffering) and only those registers and flags in the specification
of the functions are altered (SudoBIOS guarantees this). Even RM interrupts which occur while the RM BIOS is executing are handled in PM
(the default handler merely executes the original RM handler), this is so the user can manage all interrupts (if they choose) totally in PM.
The attention is in the detail.Brendan wrote:Exactly - it could be more like 200 lines of Intel syntax x86 assembly language.mikegonta wrote:SudoBIOS is written in FASM (2400+ lines of Intel syntax x86 assembly language)
Re: SudoBIOS
Thanks for trying it. It works fine in QEMU and of course on a real PC (don't be shy). The image is a non standard FAT12 "floppy disk". However, it works fine as a FAT12 hard drive image. As a USB flash drive image itomarrx024 wrote:Not working.
will boot and run as either a floppy disk or hard disk format (on real hardware and QEMU). It works fine when booted as a disk
image in BOCHS. SudoBIOS (like the RM BIOS) has little to do with the loading of the running program. SudoBIOS is a 2nd stage loaded by the boot sector
or mbr to absolute address 2000h. A far call to that location returns in 32bit protected mode. The boot sector in this case has relocated
itself (like an mbr) and loaded a "fake" 32bit PM boot sector (the one that loads the MikeOS32) before making the call.
Last edited by mikegonta on Mon May 18, 2015 6:46 am, edited 2 times in total.
Re: SudoBIOS
An excellent point. It is very complex, perhaps impossible to do 100% correctly, to interpret machine instructions "backwards" although it might be "almost always correct". However, it is possible to say "we know for sure that it was NOT a software interrupt".alexfru wrote:The "int n" instruction at CS:EIP could be part of another, larger instruction, e.g. it could be an immediate with the most significant bytes being n and 0xCD.
Re: SudoBIOS
Thanks Roman.Roman wrote:Having a 32-bit BIOS-like service and running MikeOS in 32-bit mode sound very interesting. Nice work! I will try, when I will get to my computer soon.
There was a small bug that worked fine in QEMU but failed on real hardware.
The latest version is here: http://mikegonta.github.io/SudoBIOS/
Re: SudoBIOS
Hi,
Cheers,
Brendan
You can split the interrupt vectors into several "bands"; specifically:alexfru wrote:But can you do that consistently? The "int n" instruction at CS:EIP could be part of another, larger instruction, e.g. it could be an immediate with the most significant bytes being n and 0xCD. And how much more complex you'd want the heuristics to be in both cases? Checking bits that are hardwired to 0 and 1 in what's supposed to contain EFLAGS? Checking 16 bits of what could be CS against GDT and LDT? And also checking what could be EIP against the segment limit?Brendan wrote: and possible to tell the difference between an exception with an error code and a software interrupt by examining the stack (e.g. see if "return CS" and "saved EFLAGS" look sane), and possible to tell the difference between an exception (that has no error code) and a software interrupt (by checking if "return CS:EIP - 2" points to an "int n" instruction).
- 0x00 to 0x07: Must be an exception
0x08 to 0x0F: Either IRQ or exception
0x10 to 0x1F: Either software interrupt or exception
0x20 to 0x6F: Must be software interrupt
0x70 to 0x77: Must be IRQ
0x78 to 0xFF: Must be software interrupt
- 0x10 = potential FPU error; however it's impossible for it to be an exception (unless "native FPU error reporting is enabled which is a good idea in general but breaks BIOS compatibility and therefore can't/shouldn't be enabled).
0x11 = potential Alignment Check; however it's likely to be impossible for this to be an exception (as alignment checking must be enabled and nobody ever does that).
0x12 = potential Machine Check; however it's likely to be impossible for this to be an exception (as machine checking must be enabled and nobody using real mode is likely to ever do that).
0x13 = potential SIMD floating point exception; however even if software uses SIMD the causes of this exception are all almost always masked.
0x14 = potential virtualisation exception; however it's likely to be impossible for this to be an exception (as virtualisation need to be "in use" and that's extremely unlikely).
0x15 to 0x1F = never an exception ("reserved" by Intel)
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.