Hello World Bootloader

Now we did, enough of the theory. Time to bring the baby bootloader into the land of the OS development.

Simple Bootloader

We now build a simple bootloader that does nothing. Our simplest bootloader will have its signature, so BIOS can locate it:

  • Create a file hello-world.asm in your testing folder and add the below lines of code into it.
jmp $



; Pad the rest of the sector with zeroes

times 510 - ($ - $$) db 0



; Magic numbers indicating bootable device

dw 0xAA55

Explanation:

Magic Numbers:

  • The boot sector of a disk must end with the magic numbers 0x55 and 0xaa in the last two bytes.
  • We need to store them in 511 and 512 bytes in our boot sector (0x55 at 511 and 0xAA at 512).
  • These magic numbers indicate to the BIOS that the disk is bootable.

dw 0xAA55:

  • This line writes the magic numbers 0xAA55 at the end of the boot sector.
  • dw stands for “data write”, and it writes a 16-bit (2-byte) value to memory.

times 510 - ($ - $$) db 0:

  • The times directive repeats an instruction or block of instruction a specified number of times.
  • In this case, it's used to pad the boot sector with zeroes so that the magic numbers 0x55 and 0xAA are in the last two bytes.

We know that the boot sector must be:

  • 512 bytes in size;
  • 511 and 512 bytes must be 0x55 and 0xAA.

Based on that, we make a mathematical formula, calculate how many zeroes we need to write after our code, so magic numbers will be at the correct place: 510 - CURRENT_ADDRESS - START_ADDRESS.

Explanation of the Formula:

  • The formula 510 - ($ - $$) calculates the number of zero bytes needed to pad the boot sector.
  • $ represents the current address, and $$ represents the start address of the section.
  • $ - $$ calculates the number of bytes used by the bootloader code.
  • Subtracting this value from 510 gives the number of zero bytes needed to reach the end of the sector.

Example:

  • Let's say we have 100 bytes of bootloader code.
  • Using the formula 510 - (100 - 0), we get 510 - 100 = 410
  • So, we need to write 410 bytes of zeroes after our code to ensure that the magic numbers are at bytes 511 and 512.

Compilation and Running

Let's build our code, in order to do so we would need nasm assembler:

nasm hello-world.asm -f bin hello-world.bin
  • This command, will assemble the hello-world.asm source code into raw binary format (-f bin), and then it will save the output as hello-world.bin
  • This binary file will contain machine code that can be executed by a computer or emulated by a virtual machine.

Running it with Qemu:

qemu-system-i386 -fda hello-world.bin

This is the command to start the QEMU emulator for the X86 architecture.

  • - fda hello-world.bin:
    • -fda is an option that tells QEMU to use hello-world.bin as the first floppy disk image (a stands for “floppy disk A”).
    • we can pass -hda instead of -fda to boot from the hard disk.
    • hello-world.bin is the binary file that we want to run in the emulator.
image-115.png

It's kind of infinite loop that does nothing.

  • Below is the screenshot if we use -hda option instead of -fda:
image-116.png