Boot Process & Preparation for Implementation
Before The Tutorial
This post will cover general booting process starting from when a computer is powered on to when bootloader loads kernel.
Simply say, the boot process works like this:
Power-on -> BIOS (Basic Input/Output System) -> Bootloader -> OS
So bootloader is loaded by BIOS, and bootloader prepares everything before it loads a OS and it loads OS.
ROM (Read-only memory) is a special memory chip that can only be read because instructions and data are permanently “burned into” a ROM chip. [TODO: memory type].
BIOS is a firmware used to perform hardware initializing during the booting process such as interrupt service table. Originally, BIOS used to resides in ROM, but in modern computer systems, it is stored on flash memory so it can be rewritten. In this tutorial, I’m just gonna assume BIOS is written in ROM.
When the power button is pressed, CPU enters a reset state, clears all memory to zero, executes the first instruction at ROM address “FFFF:0000”. The first instruction is the entry point to actual ROM BIOS in a way that the address contains only JMP instruction pointing to the actual BIOS code.
Turning on computer causes “cold boot” which means the boot process should go through POST. If it’s started as cold boot, BIOS runs a series of diagnostic tests (POST).
If the tests pass, BIOS copies itself to RAM because variables cannot modified in ROM. By the relocating and the memory remapping, BIOS can update variables, use stack operations, and be accessed quickly.
What we are going to implement ->
The BIOS will then examine the MBR (Master Boot Record) which is the first sector (512 byte) of a hard disk. MBR contains information about how and where an OS is located. Since one sector is not enough to contain all the information, it usually loads another larger program (often called bootloader’s 2nd stage) that contains more information and configuration settings. This is why bootloader has two stages.
For this tutorial, I’m going to implement the MBR and the program loaded by the MBR.
Software used in this tutorial
These are the programs needed for this tutorial. I’ll be working in Linux (Ubuntu) environment
This is the assembler used for this tutorial. You can download it from http://nasm.us
This is an emulator. We are going to test the bootloader on x86 hardware using QEMU.
Emulator vs. Virtual Machine
Some people might not have concrete knowledge of differences between Virtual Machine (VM) and emulator. Virtual machine uses hardware resources directly, but it can separate environment with the host machine by using virtualized interfaces. On the other hand, emulator accurately reproduce some hardware behavior.
Since bootloader is closely related with hardware’s behavior, we are going to need to use an emulator for x86 architecture.
This GNU debugger is going to be useful when you debug bootloader because it is especially harder to debug than other program. For example, the most basic debugging skill, printing results on screen, is not available until you implement the printing function using BIOS interrupt.