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
and0xaa
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
and0xAA
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
and0xAA
.
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 get510 - 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 ashello-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 usehello-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.

It's kind of infinite loop that does nothing.
- Below is the screenshot if we use
-hda
option instead of-fda
:
