http://julipedia.blogspot.com/2006/02/calling-bios-from-within-kernel.html

Calling the BIOS from within the kernel

NetBSD/i386's bioscall(9) trampoline is one of those interesting and tricky things you come across from time to time when reading kernel code. This apparently simple kernel function lets the caller execute BIOS functions and retrieve their results.

The BIOS (Basic Input/Output System) is the PCs "firmware". It initializes the hardware, starts the boot process (in a primitive way) and provides a set of utility functions in the form of software interrupts. These interrupts can be used by applications to do tasks such as reading disk sectors, gathering information about the hardware or switching the video mode, among many other things. This "library" is what concerns us now.

x86 processors start their operation in real mode (MMU-less, 16-bit addressing) for compatibility reasons with the 8086. As the BIOS contains the very first code executed by the system, it has to be callable from real mode. The BIOS cannot either switch to protected mode due to compatibility reasons again: all the boot code is real mode code (not to mention some legacy OSes such as DOS). This means that all the functions it offers to applications were designed to be called from real mode and with 16-bit addressing. (N.B. I'm not sure if this is completely true; the BIOS could provide 32-bit functions to be executed in protected mode, but anyway this is not what we are interested in now.)

Sometimes, these functions can be a very useful resource for the operating system, specially before it has set up its own device drivers. But... virtually all OS kernels now work in protected mode with 32-bit addressing. In such configuration, it's impossible to call real mode code because of its 16-bit addressing and its direct access to the hardware.

So is it impossible to use those functions once the kernel has started? Of course not. But only if the kernel has not thrashed important memory regions nor put the hardware in an unknown status to the BIOS. (That is, the subset of available operations once the switch has happened is quite limited.)

Assuming everything is OK, the kernel can switch back to real mode (non-trivial), issue the call to the BIOS function, grab the results, return to protected mode and feed those results (if any) to the caller. And you guessed right, this is what bioscall(9) does in an automated way. The manual page contains some more details and sample codes.

By the way, the EFI (Extensible Firmware Interface) is Intel's replacement for the BIOS. All these compatibility issues should be gone, something that is certainly good to make the i386 platform better and free it from obsolete design issues.

3 comments:

Anonymous said...

If it is so complicated to switch from protected to real mode and then back to protected again, and considering that once the kernel has booted you don't need to make BIOS calls anymore (since you have theoretically and ideally configure all the hardware), why someone implemented that kernel function?

Julio M. Merino Vidal said...

The NetBSD/i386 kernel always runs in protected mode. The one who switches from real mode to protected mode is the second stage boot loader (/boot). (I promise to write about this some day.)

However, the kernel may still need to access the BIOS so the only way to do it is revert to real mode. I've seen calls to bioscall(9) in the APM code. Don't ask me why they are needed and why they cannot be reimplemented in protected mode, as it is something I do not know.

What made me look at this function is the recent implementation of vesafb. I think someone mentioned that the BIOS might be needed to easily switch to text mode... or something like that.

Jeff Dinham said...

thanks for the link to EFI, will be back again to read your articles


Reply via email to