Hi,
This code allows software to use the BIOS from protected mode.
WARNING: This is just an experimental prototype hack, and wasn't written as 100% bullet-proof code.
It switches to protected mode and installs its own IDT. When any interrupt occurs in protected mode, it switches back to real mode and executes the relevant BIOS interrupt handler, then switches back to protected mode and returns to protected mode.
I also made it so that it knows the difference between an exception and a software interrupt or IRQ. If an exception occurs it just locks up instead of executing the BIOS's interrupt handler (I was going to add some "blue screen of death" crash dump code to it but I was lazy).
There's also some extremely bad floppy disk boot code that I slapped together for testing. You'd want to use NASM to assemble it (but YASM would probably work too).
Source code is in the attachment. The copyright is "public domain" - do whatever you want with it.
Cheers,
Brendan
Brendan's BIOS Wrapper (experimental!)
Brendan's BIOS Wrapper (experimental!)
- Attachments
-
- bbw.tar.gz
- (5.2 KiB) Downloaded 255 times
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: Brendan's BIOS Wrapper (experimental!)
If I were to start writing a boot loader now, I would think about using this idea. I could write almost everything being 32-bit code written in C. However, maybe the end result would be more entangled because inline assembly would be needed anyway to do several things. In addition, this mechanism itself would constitute almost a half of the boot code in my case. Anyway, a good prototype for introducing the idea.
Re: Brendan's BIOS Wrapper (experimental!)
Hi,
My boot code uses protected mode and paging (and is probably more complex than some people's OSs ). For older versions I disabled IRQs while running in protected mode; which meant that the BIOS could lose IRQs. To work around that I peppered the code with "do nothing" calls (switch to real mode, enable IRQs and execute a few NOP instructions; just to give the BIOS a chance to handle any IRQs before it's too late). It's not pretty. For me, the BIOS wrapper would make things a lot cleaner (getting rid of the need for those "do nothing" calls all over the place, and also avoiding wrappers around individual BIOS functions) and I do intend to use this idea in my next "stage 2".
For the prototype itself there's still a few things missing. Mainly, if a BIOS function uses a segment register (e.g. ES for BIOS functions that read/write sectors) then the segment register has to be 0x0000 (it'd be easy to fix, it's just that I haven't yet). It'd also be nice to implement the "BSOD on exception" code, and maybe catch exceptions that occur while the CPU is in real mode (in case the BIOS crashes), to make it a little easier to debug the boot code on real hardware if things go wrong.
Cheers,
Brendan
Boot code is the reason I was playing around with the idea.Antti wrote:If I were to start writing a boot loader now, I would think about using this idea. I could write almost everything being 32-bit code written in C. However, maybe the end result would be more entangled because inline assembly would be needed anyway to do several things. In addition, this mechanism itself would constitute almost a half of the boot code in my case. Anyway, a good prototype for introducing the idea.
My boot code uses protected mode and paging (and is probably more complex than some people's OSs ). For older versions I disabled IRQs while running in protected mode; which meant that the BIOS could lose IRQs. To work around that I peppered the code with "do nothing" calls (switch to real mode, enable IRQs and execute a few NOP instructions; just to give the BIOS a chance to handle any IRQs before it's too late). It's not pretty. For me, the BIOS wrapper would make things a lot cleaner (getting rid of the need for those "do nothing" calls all over the place, and also avoiding wrappers around individual BIOS functions) and I do intend to use this idea in my next "stage 2".
For the prototype itself there's still a few things missing. Mainly, if a BIOS function uses a segment register (e.g. ES for BIOS functions that read/write sectors) then the segment register has to be 0x0000 (it'd be easy to fix, it's just that I haven't yet). It'd also be nice to implement the "BSOD on exception" code, and maybe catch exceptions that occur while the CPU is in real mode (in case the BIOS crashes), to make it a little easier to debug the boot code on real hardware if things go wrong.
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.