Next Previous Contents

3. Linux and the BIOS : Linuxbios !

In this part, I explain the link Linux-LinuxBios and Linuxbios role and action. Linuxbios result is a BIOS like any other. First as a general matter, I describe what a BIOS do in details and what resources it offers and handles. Second, I'll explain the specific Linux device handling regarding to other OSes. Third, I'll try to explain how vital it is to consider the frontier between BIOS and OS helped by a synpotic boot chart. At least, you'll also get a simple howto customize Linux Kernel for your Linuxbios.

3.1 Generalities

Maybe it's useful to explain some general notions of BIOS behavior.

Bios code is stored in an EEPROM called variable size CMOS chip, often it is a 128Ko or a 256Ko chip located on the motherboard near a flat round battery to sustain electrically this code in case of power cuts.

When you got a bad BIOS code or a bad configuration "a manual override" processus can be undertaken. It consists in powering down the motherboard and taking off that battery for a dozen of seconds. Upon rebooting, BIOS (partly) ereased code will raise a checksum control error. As a result, the rest of this code will launch a default recovering procedure as you'll act according to "Checksum error -- Hit F1 to retore default values" display. Last thing to mention, nowadays BIOS codes are copied into RAM memory, this common BIOS ability is called 'bios shadow' or 'Shadow RAM'.

When system is on, cpu self tests its efficience : voltage, frequency, etc.. If correct it emit a PowerGood signal which spreads to activate PnP compliant cards and other controllers connected to motherboard. CPU initialize with its default values and know it has to read 0FFFF:FFF0 address and to jump to the address it holds (See the complete boot sequence). this is the first BIOS code line. Then it determines the CPU L1 cache memory and the CPU L2 cache memory. Remember thoses leveled memory caches as temporary zones for CPU calculus chains. When it is done it tests so called 'compagnion chips', for instance on some motherboard, an arithmetic coCPU is tested with a built-in dedicated instruction.

All theses steps are made into the real mode but the rest will run into the protected mode. Real mode is based in 16 bits and thus can't map all memory. That's the main reason why it has to go into protected mode which is based in 32 bits. At this junction, CPU is up and running fine so it stands as a grant for 16 ot 32 conversions, that why it's called 'protected'.

Now that a protected runtime environnement has been triggered, BIOS has to reinitialized CPU to rerun it with the optimal values . This phase is essential to define and initialize all devices and hardwares around the CPU. Bios could then use assembly call CPUID to identify CPU. This instruction returns best fitted values matching CPU model and working.

This is the end of the 'core intialization'. Then it is devices init. time, BIOS sends activation bytes to hardware controllers. To keep it simple every device use a base controller --a chip. It is an interface with a lowlevel dialog protocol between hardware and BIOS. Even better, for Linux and from what I have understood, the dialog is set from hardware to kernel itself. (See Linux Hardware Abstraction Layer).

3.2 Specifications

Linuxbios as any other conventionnal BIOS is able to handle/do :

Except this grand initializer role, BIOS offers resources, to be more precise, gateways to access them. Theses resources could then be consulted and accessed. Notably the Linuxbios :

By the time computer architecture have no more secret to this pre-system, BIOS looks for the OS. Depending on boot order which is a BIOS option that Linuxbios regard as a parameter, it goes to fetch MBR/PBR on disk, floppy, whatever it is... Then it looks for an id value 0XAA55h which tags a bootable sector and obviously a disk that contains an OS. BIOS copies this MBR in RAM and orders CPU to point to this RAM MBR copy. This sector is actually executable code which loads and decompress the Linux Kernel (if you deal with a GNU/Linux). At least, this short stage (called 'Stage 1' in GNU/Linux) ends after positionning stack pointer to first line of OS code. Well that's it, that's a BIOS life.

All right, you can see it as a whole in a synoptic flowchart. But before if you wish there is still a delicate point for you to see. If it's a fact that devices are set in a way BIOSes are bound to identify them, it's not all the same for the OS. There are many reasons to this in which glitchy proprietary BIOS codes, counter-performances boot sequences and unsuitable OS-BIOS frontier, both leads to a fragile design. Next follows what Linuxbios exploits which explains its power upon other BIOS.

3.3 Abstract device layer

Linux adds an immediate hardware controller-Linux interface, shortcutting greatly classical controller-bios dialog and bios-OS dialog (bios service). Note is precisely true when theses interfaces are in the kernel land (builtin) and not as much when they are in the user land (modules). Equally, theses codes are simply called device drivers, they establish a link between an architecture and a protocol to enable dialog.

For instance, an interruption : a file read request emitted by a lambda application whereas the main handler is OS.

"Layers OS" will waste energy in echoing this simple instruction throughout various layers until delivry at bottom hardware layer. Also, worse is that resulting treatment, the answer, has to travel back until the top layer. You can notice in the following flowchart that actually effective interruption's handler relies on sole BIOS.

In other words, end-of-the-line request is processed by a proprietary, "rigiddy" hardware oriented BIOS code which is based on an old BIOS services concept.

This didn't bother anyone until relative recent widespread use of networking and personnal computing has made computers to be used in a new way. Hardware handling has reached a new point; where grid processing and mass storage centralization, or the opposite, small scaled hardware (embedded devices) and massive client display requieres more efficience and quickness; where security and viability wouldn't obviously lead to many time-consuming integrity checks at I/Os. Linuxbios seems to aim also to theses objectives because of the Linux Kernel.

The Linux kernel as it is, is naturally at this rendez-vous point. Linux self implements a "generic layer", an "hardware abstraction layer" or still a "virtual device", whatsoever you call it. Thus it does not need any bios service from BIOS. Linux is to fit every type of device in order to prevent too frequent BIOS updates. This also means, that you could buy your hardware regardless of what your classical BIOS would accept.

Ok now, let's walk back on the ground, in fact obviously, this means porting effort anyway in the kernel notably but not only. Also, if you've made your own card, you got to make your own driver to fit in that layer. However, Linuxbios already supports many mainboards and handles succesfully numerous chipsets. In below flowchart, you can see difference and realize that this layout enables a single mapping and a signal centralization controlled by Linux OS solely. You'll see later on in the next section that indeed maintaining upwards this logical unity is a fair defy. To sum up roughly : it enhance global performance for response time are shorten. Useless to mention that this is utterly wished for upper said applications field (embedded, constraint milieu as well as clustering, grid calculus).

This architecture boosts performance from BIOS to OS. But BIOS obviously remains hardware dependant. Linux offers a great flexibility without it wouldn't be able to run a freebios such as Linuxbios. For beneath flowchart instance, to display, a frambuffer driver exists which is attached to this abstracted device layer. Does such an abstracted device layer would exist for your typical needs, if for example you feel like booting from a Compact Flash (CF) ? This is what you have to consider if you ask your freebios to be viable and flexible. Because you don't want to rebuild and burn a BIOS every time you change a device, or you change a boot order, (do you ?) then you need to consider where to put the frontier between BIOS and OS.

3.4 BIOS-OS frontier : a crucial choice

I come more on the theorical point in this part...

Without BIOS, or rather if it was completly integrated into the OS, this latter would be solely and wholly in charge of hardware. Because it seems inconceivable to change OS as you change your sound card, BIOS exists. I see you start bending over yourself, does this frontier recalls you the kernelspace and userspace 's one ? Heh heh it is, so why not asking yourself if Compact Flash handling, for instance, could be directly flashed in BIOS rather that present in the OS?

The answer is obvious for such a easy question. If you usually use a CF to BOOT your OS, you'll merge the handler within BIOS. It would be a pity to wait for OS to take over the system so you could use a functionality whereas you could have use it earlier in Linuxbios. Moreover, for the CF instance, it become compulsory to have it earlier within the BIOS to boot from it.

Ok, I feel you might start thinking that we are running to nonsense by pushing down to BIOS layers what's used to be into OS one. If you can't reconsider this maybe you just don't see the scope of this project...

Now let's stray for a while, as evoqued in the previous section most OS, to carry a problem out of its sight, layers proceeds requests, by redirection, that is nearing the idea : "What's not my job is surely lower/upper/lessloaded layer's one". Look, BIOS is far from being alone to work like that, in fact all computing items, real or virtual, works upon this idea from the most low-level piece, BIOS, to the most high-level one, Internet. It is just a very "pyramidal concept" which is looking to dispatch and assign jobs or requests.

This is not a strange coincidence, it has historical reasons. For instance, if a software realize the cpu can't do 150 * 33 because it lacks a bigger operation register for example, then we write it to do ((150*3)*11) and even (((15*10)*3)*11). Surely, You catch my meaning : this requieres a I/O stack, and processes to picks up and compute operations. All right, and when all this runs in more complexity, speed, capacity we have to wonder why still go on writing it up that complex way, why using it still the same way ?

Also in order to get things running faster, to shorten render time while systems naturally tends to more complexity, we just aim to keep whole computer software stack as thin as possible, I/O between layers as fast as possible, etc.. That's it for embedded systems as for computer clustering, parallel and grid computization. We have "granularated" up/down that 'basic protocol' and until we have nothing new, more intelligent, to fit compatible (or not ?!) with this, we'll be keeping on running after Moore's law.

Enough 'trolls' on new theory, let's come back to our herd. If you need a proof of the existence of that new frontier, for example, when Linux does a new IDT description it overlap onto the classical BIOS attributions. Also, this cost extra time to do it once and for all (session time) at kernel loading. But after that, OS (the kernel) is able to spare BIOS the cost of dialog in frequent cpu interruption situation, leading to greater efficiency. Realize this simple cursor slide to OS side thus represents a cpu time spare before it is interrupted . Because by setting OS as true interruption leader, which manages time planning and interruption planning together, which masters interrup trigger mode, it can be more efficient. Since interruptions are everywhere talking about devices, talking about grid computing also, guess how up can reach this "optimization"...

This is a 'cursor adjustement' example if you prefer. Another is MTRR initialization, but you could get more infos onto LANL's Linuxbios site. Most optimizations comes with code to refactor or to rewrite, also sometimes enabling a high profit comes nevertheless with a redundancy. This is quite paradoxal isn't it, while we talk about efficiency ? True, but not weird. After all, this is rather "normal", for example the CPU is defined and initialized twice, the second stage bring advanced values enabling a more precise setting up, to exploit hardware the best way. Nobody find it weird or anormal. Same way, failsafe or fallback mechanism doesn't figure as secondary functionality. If Linuxbios has chosen the fallback mechanism, it is because it saves system from going into kernel panic or fatal error. So, indeed a better cursor adjustement will automatically raise the quality of your Linuxbios, and satisfaction of your Linuxbios users. Also, think of what is going to happen by bringing such code from BIOS to OS, and such other from OS to BIOS.

It is still very delicate to establish a frontier on the long term. Actually, I think we should let this as a floating frontier, moving according to various applications. It requiers to be redefined to match your applications needs. I can feel the most skeptical of you fearing for compatibility, don't worry we'll find other bridges. Until this raffines it needs to remain open, to enable people to think about this.

Now you can refer to boot sequence flowchart. It is my proposal to fit most common Linuxbios needs as well as mine according to IEEE Standard.

3.5 A linux kernel built for Linuxbios - howto -

This piece of work is essential, if you never build a kernel...err... summon up your patience/perseverance (SUYP). Now, you must have been enabled to qualify your needs, designate your platform and to test it. The next step is to customize a Linux Kernel in order to boot a given OS from a given device. I have chosen end of 2.4.xx series Linux Kernel 2.4.25 because it was the last kernel before 2.6.xx series. Moreover if you want to try other "exotic" kernel codes, don't hesistate to stress test 72 hours long or more. (cf. ref Linux Test Project (LTP) regression tests).

OS to be loaded by Linuxbios is totally BIOS independant although as presented earlier, Linux partly redoes more efficiently part of what a standard BIOS is used to do. So there's no much miles from using a kernel as an initializer. Indeed, a Linux kernel will boot an OS, which by the way can be a-n-other Linux kernel. I won't go for a extended howto on kernel building but I'll give you some quick info so you can go directly to the point.

You need the kernel source (cf www.kernel.org) and a setup file to configure kernel. Normally, you'll find documentation in the source to do it right. Be careful before replacing your build machine kernel, actually don't replace, add it in plus to your standard kernel. It'll serve as a failsafe kernel. Really, do extensive tests although they are time consuming they will prevent you from realizing further on that it's no a trouble with Linuxbios you have but one with your primary kernel. A crashing kernel which often freeze system will waste twenty to thirty maintenance minutes to restore previous working status... except if you have a stated recovery procedure.

In order to compile your Linux kernel, you need a minimal requierement software toolchain version. It is minimal also you could even try to strip off PPP or ISDN to gain more space if you have no use of them.

I can't set in detail here what you'll have to enable in your kernel configuration to accord your Linuxbios kernel to your motherboard hardware. You can display this type of information via a lspci -vt or even more in detail with a lspci -vv. For example, and corresponding to my experiment build machine (description) I had to install VIA CXX chipset and the C3 Ezra CPU. Devices supports can be taken either statically e.g merged to kernel, either dynamically e.g insmoded as modules in system from boot configuration files. Also keep on mind that the more supports you add to your kernel the more will it be weighing. Modules insertion is time consumming while booting. Light and compact kernel will decompress and load faster. I insist heavily (ruler slide), a sensible policy on this matter infers directly to boot time performance.

For example for VIA RHINE driver support (i.e VIA EPIA integrated chipset network controler ), here is how you can specify in the kernel configuration file this choice (specify only one of theses of course)

#VIA RHINE network controler support as a module
CONFIG_VIA_RHINE=m
#VIA RHINE network controler support as native
CONFIG_VIA_RHINE=y
#VIA RHINE network controler support deactivated
CONFIG_VIA_RHINE=n

Also you might be interested in knowing some other kernel configuration option about Memory Technology Devices (MTD) such as DiskOnChip(DOC). Of course, remember to add m/y/n to activate the option.

# DOC1000 serie chip handling
CONFIG_MTD_DOC1000
# DOC2000/ME series chip handling 
CONFIG_MTD_DOC2000
# DOC2001 serie chip handling
CONFIG_MTD_DOC2001
# Onboard DOC chip autoscan (probing)
CONFIG_MTD_DOCPROBE
# DOC chip Bootable sector handling and probing
CONFIG_MTD_DOCPROBE_55AA

Typically, here are commands that launch kernel compilation and modules building :

$make menuconfig [or] $make config
$make depend
$make bzImage
$make modules
$make modules_install

The two last commands build and install modules into the default location /lib/module/_KernelVersion_. Then you could insert a module for example VIA RHINE support module into system with insmod /lib/module/2.4.25/kernel/drivers/net/via-rhine.o

Linuxbios add itself some line in configuration file. By default, it enable ACPI function, you have to deactivate manually it in order your bios functions at best. However, a bad set up on this point won't affect BIOS starting. At worse will it raise an error in bootloader while loading and decompressing kernel.

Bootloader is a short binairy code located in MBR, it's loaded at the end of BIOS startup. This code can be classical LILO or GRUB or whatever program formatted in elf or a.out, depending on what was set up in kernel configuration file, depending on what format the kernel has been told to recognize. Further booting study will describe different possible bootloader combinaisons in Linuxbios. A bootloader is perfectly standalone thus in its code a system root partition must be defined as default. Nevertheless, via a commandline you always could (value "prompt") instruct it to consider another root partition. Actually, bootloader parameters are passed by copy (recopied) in kernel parameters line. Thus, you can early instruct bootloader and kernel with some options (cf. a full Kernel Howto). Let's state some Linuxbios dedicated useful options :

root=/dev/dha3      - Tell where root partition is.
console=/dev/ttyS0  - Activate I/O on serial port as a console.
vga=ask             - Prompt for desired vga mode line.

In deep to explain kernel loading, this procedure have two stages. Fisrt, bootloader loads a strap, a small kernel piece, and a message displays something like "In first stage loading". During this stage, pre-kernel install VFS to mount root partition in readonly mode that holds a second kernel image. Remember this detour is compulsary because bootloader is just a 512 bytes long block it obviously cannot holds the entiere kernel. Second, kernel have "hands-on" and oftenly a message displays "Second stage loading". Then it initializes devices drivers and it remounts its root partition in read/write mode (mount option remount,rw). Bios data about device parameter are stored in pci_dev structure.

struct pci_dev {
struct  pci_dev         *bus;
struct  pci_dev         *dev;
struct  pci_dev         *next;
...
unsigned int            devfn;
unsigned short          vendor;
unsigned short          device;
unsigned int            irq;
unsigned long           base_adress[6];
}

All of theses steps can be followed via Linuxbios debug strings and this given experiment appareil. You can also do this if you spend some money in a PCI POST card because Linuxbios sets a POST handling.

If there is a RAMdisk, another kernel option, then it is executed. A device driver has installed the main console so it be copied as virtual consoles, to create more console. At least, a bash script such as rc.sysint is executed in a terminal console. Note in V5 compliant system (all of GNU/Linux and most Linux distributions) that INIT process can start up and install swap memory as well as starting up servers services and deamons. At last, X server is available can be initialize and then you have your usual favorite windowed working space.

Preparation stage is finished. Matter is now on knowing how Linuxbios works to carry out a free BIOS prototype. And to do so, I've explained what kind of software solutions you may use. You could by yourself consider which one best fit your Linuxbios need.


Next Previous Contents