Who hasn’t fantasized about programming their own OS? This utopia can materialize with minimal knowledge of assembly and C. In this article, we will explain the boot process of a computer and how to boot our super-reduced OS.
To perform all our tests, we will need an ASM compiler and the qemu emulator. We will use qemu instead of a virtualization system like VirtualBox because the latter would execute instructions directly on our CPU for superior performance, but the environment may not be exactly the same as that of a physical machine. With an emulator, we can achieve this.
Depending on the OS, we will install the software in one way or another:
FreeBSD:
Gentoo:
The article is based on the following document posted on the University of Birmingham website 2 ..
First of all, we must bear in mind that when a computer starts up, the first thing it does is load the BIOS from the integrated chip on the motherboard into RAM, and then perform a basic hardware check.
Once the hardware has been checked, it remains to determine where to boot from. The BIOS simply reads the first 512 bytes (boot sector) of all available disks in the system. If any of them contain the values AA 55 in bytes 511 and 512, it considers it to be a bootable disk.
These first 512 bytes are called the boot sector, and they are the instructions that will be loaded into RAM and then executed by the CPU.
We are going to create a very simple boot sector, we will simply mark bytes 511 and 512 with AA 55 so that the BIOS recognizes it as a valid boot sector, fill 510 bytes with 0s to reach a total of 512, and stay executing an infinite loop.
Remember that the CPU will blindly read from RAM what we have loaded from the first 512 bytes of the disk, if we did not define the infinite loop the CPU would continue reading RAM and executing random instructions, remains of previous program loads, this can be more or less dangerous depending on the instructions in question.
; Infinite loop (e9 fd ff)
loop:
jmp loop
; Fill with 510 zeros minus the size of the previous code
times 510-($-$$) db 0
; Magic number
dw 0xaa55
We generate the image:
We can see the content with xdd:
00000000: ebfe 0000 0000 0000 0000 0000 0000 0000 ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.
We load it into qemu:
SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F91410+07EF1410 C980
Booting from Hard Disk...
Impressive, we have been able to load our OS from scratch.