Writing a bootloader for fun and grades
2020 was a rough year for many people: The world was on fire and there was this virus going on. So I set out to write a bootloader. This post is the start of a series based on my bachelor’s thesis I completed in 2021. (Yes, that’s two years ago, sorry I’m late with using pandoc.) It has been edited to be more easily readable and more fun (it uses shorter sentences, for example).
If you want to take at look at the code, it’s on GitHub.
What, why and how (introduction)
You might have heard of this thing called UEFI. It stands for Unified Extensible Firmware Interface and the firmware of current PCs is compatible to this standard. It describes (among other topics) so-called UEFI applications: Programs that are run by the firmware and can, for example, start an operating system (most of them do).
Multiboot is not only a commonly-used word, no, it’s also a standard created by the GNU GRUB project for both kernels and bootloaders: compatible bootloaders can start compatible kernels and provide them with information about the system. Currently, there are two major versions of the Multiboot standard: 0.9.96 (which I’ll call 1) and 2.0. They differ in design (version 2 is modular) and in which scenarios they support (version 2 for instance also supports kernels that use UEFI functionality by themselves) but at the core they both have the same purpose.
hhuOS is a “small operating system for learning purposes”. It is the main operating system I’m developing my bootloader for (and the one, I’m testing it with with, see a future post). Its images previously used GRUB (and an own bootloader for BIOS-based systems, much earlier), but having an own bootloader makes it possible to teach the boot process more completely (and it does not require shipping the bootloader’s source code with the operating system image).
My goal here is to write a UEFI application that is able to read a configuration file and load the therein specified Multiboot-compatible kernel and module(s), passing a framebuffer and more information about the system. Bootloader, configuration file, kernel and modules all reside on the same partition (this will be the EFI System Partition in most cases).
I’m going to write this UEFI application in Rust because it has good support for UEFI as a target platform, memory safety and both high-level language constructs and low-level instructions.
I’m going to explain the technologies I used, my implementation, testing and ideas on how it can be improved further in the next posts, so stay tuned.