by Pierre Roudier
http://perso.wanadoo.fr/pierrelib
Notes to the reader :
All information given in this document apply to IBM PC/AT clones based on Intel x86 (and compatibles) 16 & 32 bits CPUs. I don't know concerning 64bits platforms...
TODO: ACPI, PCI and PnP considerations...
1. Introduction:
All the operating system don't provide the same services, therefore they don't need to initialize the same way: no need to initialize unused devices as it would be a waste of time. Hence a need for a per-OS init process which can only be done by the OS itself. Moreover if the init process was performed by the BIOS, installing a new operating system would sometimes require an update of it which would bring avoidable extra costs for companies and difficulties for the common-user.
The overall booting protocol is the following: the BIOS initializes the hardware required to load the operating system and then loads a little piece of code provided by a third party than the BIOS manufacturers and called bootloader. This code is placed somewhere it can be easily found. It is responsible for loading the OS kernel and modules (depending on the OS architecture), initializing the hardware and jumping to the kernel code. During this step, the BIOS only provides services to the OS loader.
More in details, this is what chronologically happen when you switch your computer on:
What the BIOS does (among other actions) is:
2. Simple case: booting from a floppy :
In this section we consider an imaginary computer than has one single drive: a floppy disk.
The first sector of the first head of the first cylinder of the media is called the bootsector and contains the boot loader (usually 512bytes). Bootsectors must always have a signature: the two last bytes must be 0xAA55 otherwise the sector isn't considered as a bootsector.
At boot time, the BIOS loads it into memory at 0x7C00 and jump to address 0x7C00. CS, DS, ES, FS and GS are all set to 0. The CPU is then in real mode, caching and paging are disabled. And the A20 gate might be closed.
To give you an idea, a simple bootsector could load the kernel into memory using BIOS INT #13 and jumps to it.
Now, let's consider another computer with a floppy disk, a cdrom drive and one hard disk drive. In the fdd is inserted a copy of QNX, there is no media in the cdrom drive and WinXP is installed on the hdd. All the medias have a valid bootsector therefore the BIOS has to decide which bootsector to load.
The BIOS simply follows Boot Device Priority or Boot Sequence list specified in the BIOS configuration. The BIOS looks for a bootsector on the first drive of the list, if there is none, it tries the next disk and so on. If no bootsector has been found when the end of the list is reached, the BIOS looks on the first hard drive (which may not be enlisted in the boot devices list). If no bootsector is found, the BIOS display a message like "Boot Failure! Reboot and select proper boot device" and hungs the computer.
Once the good bootsector is located, it is loaded in the system memory at 0x7C00. The dl register is set with the number of the drive the bootsector has been loaded from. The first hdd is number 0x80 and the first floppy drive is number 0x0.
Note that booting from a CDROM is a bit different no treated in this document. Take a look at toward El Torito Bootable CD-ROM Format Specification. A copy can be found here.
Memo:
3. Real life: booting from a hard disk drive :
It is possible to split a hard drive in many partitions where each partition can hold a running operating system. As these OS can be very different, they can have different boot loaders therefore having one bootloader installed on the bootsector would require the user to update the bootsector everytime he wants to boot his PC under another OS. It can't be a solution.
On hdd, the first sector isn't a real bootsector but a Master Boot Record (MBR). It is treated the same way by the BIOS: loaded at 0x7C00, dl=boot drive and last word must be 0xAA55. But where a bootsector contains only code, a MBR also contains the partition table where (you guess) information about the partitions are stored.
In a valid partition table, only one partition is marked as active meaning that it is the partition which bootsector should be loaded. The bootloader code is located at the first sector of the partition under the form of a bootsector. This way it is possible to have different OSes installed on the same physical disk, each OS having its own partition and bootloader.
The job of the MBR is to find which partition is active then to load its bootsector at 0x7C00 and finally to give it the control. Note the MBR was already at 0x7C00 so it has to move itself out of the place before loading the bootsector. Don't forget to check for the 0xAA55 word and to set dl=bootdrive before jumping to the bootsector.
5. References :
If you want to read more on the topic:
Originally written on November 10, 2004.
Last modification on January 2nd, 2005.