60% OFF ALL COURSES | get full lifetime access now
Ends in: ...
Creating A X86 Bootloader From Scratch
Low Level Programming

Creating A X86 Bootloader From Scratch

What is a bootloader?

A bootloader is a piece of software responsible for booting a computer. When a computer is powered on, it typically does not have an operating system loaded in RAM. A bootloader is software that starts the loading of the operating system (OS) into RAM.  

When the computer boots up, the first thing that happens is the operation of the BIOS. The BIOS then runs a power on self-test to check that devices the computer relies on are functioning properly. If all the devices are functioning properly, BIOS then goes through the configured boot sequence searching for a bootable device. BIOS deems a device as bootable when the first 512 bytes of a device are readable and end in the exact bytes 0x55AA. Ox55AA is a magic number marking a boot sector as bootable. The first block of the bootable medium is where the bootloader is stored. Once a bootable device is found, BIOS loads the first 512 bytes of the drive into memory address 0x7C00, and transfers program control to this address with a jump instruction to the processor.

Getting Started

The language mostly used to write bootloaders is Assembly Language. I used NASM assembler in this project, so go ahead and download the NASM assembler if you haven’t done that already. NASM can be downloaded from https://www.nasm.us/. Now that you have NASM downloaded and installed, let’s get started writing our bootloader.

The bootloader being created in this article is a simple bootloader, it does nothing more than print a message ‘Hello, there!’ out to the screen.

The Code

bits 16         ; tell NASM to use 16 bits, at this point computer is running in 16 bit real mode

org 0x7C00      ; set the start address for this code

_start:

    mov si, message  ; point SI register to ‘message’ label memory location

    mov ah, 0x0e     ; set higher bits to the display character command 'Writing in TTY Mode'

.loop:

    lodsb        ; loads the current byte from SI into AL and increments the address in SI

    cmp al, 0    ; compares AL to zero (null byte)

    je _stop     ; if AL == 0, end of string, jump to '_stop'

    int 0x10     ; runs BIOS interrupt 0x10 - video services

    jmp .loop    ; repeat with next byte

_stop:

    hlt                     ; stop execution

message:

    db "Hello, there!", 0   ; 0 (string terminator)

times 510-($-$$) db 0       ; pad remaining 510 bytes with zeroes

dw 0xAA55                   ; magic number - marks this 512 byte sector bootable!

Assembling and testing our bootloader

Let's save the code above as boot.asm and assemble it using this command:

nasm -f bin boot.asm -o boot.bin

We can now run our bootloader using an emulator by issuing the following command, considering we already have QEMU installed on our machines, and if not you can download the emulator here https://www.qemu.org/, QEMU is a generic and open source machine emulator and virtualizer. We are not going to be using a real machine, just an emulator instead.

Now run qemu-system-x86_64 -fda boot.bin

After that command runs without errors we should see a message, 'Hello, there!' on the screen.  That's it! To learn more about Assembly Language, visit https://dragonzap.com/course/x86-assembly-language.

 

You can learn how to create a 32-bit kernel here: https://dragonzap.com/course/developing-a-multithreaded-kernel-from-scratch

  • Share

Previous Post

Programmer Dan Voice Assistant For Programming Questions

Next Post

Creating A Linked List In C

Comments

No Profile Photo

Lloyd

I found this article very interesting thanks


Leave a comment