Search Knowledge

© 2026 LIBREUNI PROJECT

Operating Systems Internals / System Initialization & Booting

Bootloaders and the Kernel Entry

Bootloaders and the Kernel Entry

If the BIOS/UEFI is the “ignition,” the Bootloader is the “starter motor.” Its job is to find the Operating System kernel on the disk, load it into memory, and jump to its starting address.

1. Why do we need a Bootloader?

You might wonder: Why doesn’t the BIOS just load the kernel directly?

  1. Size: Kernels are Megabytes in size; the MBR is only 512 bytes.
  2. File Systems: The firmware doesn’t understand complex file systems (like NTFS, ext4, or APFS). The bootloader provides the “drivers” to read these.
  3. Multi-Boot: A bootloader allows the user to choose between different operating systems (e.g., Linux vs. Windows).

To demonstrate the size and address limitations, consider how a minimal 16-bit Stage 1 bootloader reads sectors from disk. It uses BIOS software interrupts because it cannot access filesystems directly:

; Load Stage 1.5/2 from disk using BIOS INT 0x13 in 16-bit Real Mode
mov ah, 0x02        ; BIOS Read Sectors function
mov al, 0x08        ; Read 8 sectors (4KB)
mov ch, 0x00        ; Cylinder 0
mov cl, 0x02        ; Sector 2 (sector 1 contains the MBR itself)
mov dh, 0x00        ; Head 0
mov dl, [boot_drv]  ; Drive number (passed by BIOS in DL register)
mov bx, 0x8000      ; Set buffer destination segment
mov es, bx          ; ES = 0x8000
xor bx, bx          ; BX = 0x0000 -> Address ES:BX = 0x80000 physical
int 0x13            ; Call BIOS disk service
jc disk_error       ; Carry flag set indicates disk read failure

2. The Grand Unified Bootloader (GRUB)

On Linux and many hobbyist OSs, GRUB 2 is the standard. It works in stages to bypass storage size constraints:

  • Stage 1 (boot.img): Stored in the MBR or the first sector of a partition. Its only job is to load Stage 1.5.
  • Stage 1.5 (core.img): Contains file system drivers. It is stored in the “gap” between the MBR and the first partition.
  • Stage 2: Loads the full GRUB interface, reads /boot/grub/grub.cfg, and allows you to select a kernel.

An example of a basic GRUB menu config entry /boot/grub/grub.cfg which points to a kernel image:

menuentry "LibreUni OS" {
    insmod ext2
    set root='hd0,msdos1'
    multiboot /boot/kernel.bin
    boot
}

3. The Multiboot Specification

To prevent every OS from needing its own custom bootloader, the Multiboot Specification was created. It provides a standard way for a bootloader to talk to a kernel.

A Multiboot-compliant kernel has a “Header” in its first 8KB that contains:

  • Magic Number: 0x1BADB002 (for Multiboot 1).
  • Flags: Telling the bootloader what it needs (e.g., page alignment, memory maps).
  • Checksum: Ensures the header is valid.

An example of a Multiboot header defined in NASM assembly:

; Multiboot Header (GNU Multiboot 1 Specification)
align 4
section .multiboot
dd 0x1BADB002           ; Magic number
dd 0x00000003           ; Flags: memory info + page alignment
dd -(0x1BADB002 + 0x00000003) ; Checksum (magic + flags + checksum = 0)

The Handover State

When the bootloader jumps to the kernel, it provides critical information in CPU registers:

  • EAX: Contains the magic value 0x2BADB002 (confirming a Multiboot boot).
  • EBX: A pointer to a Multiboot Information Structure (containing the memory map, command line, and list of loaded modules).
Code
participant "Bootloader (GRUB)" as boot
participant "CPU Registers" as regs
participant "Kernel Entry (_start)" as kernel

boot -> boot : Load Kernel File to RAM
boot -> boot : Setup GDT (Global Descriptor Table)
boot -> regs : EAX = 0x2BADB002
boot -> regs : EBX = &multiboot_info
boot -> kernel : Jump to Kernel Code
activate kernel
kernel -> kernel : Disable Interrupts
kernel -> kernel : Setup Stack
kernel -> kernel : Call kmain()
Bootloader .GRUB.CPU RegistersKernel Entry ._start.Bootloader (GRUB)CPU RegistersKernel Entry (_start)Bootloader (GRUB)CPU RegistersKernel Entry (_start)Load Kernel File to RAMSetup GDT (Global DescriptorTable)EAX = 0x2BADB002EBX = &multiboot_infoJump to Kernel CodeDisable InterruptsSetup StackCall kmain()

4. Kernel Initialization: PID 1

Once the kernel has control, it performs its own initialization:

  1. Memory Setup: Sets up the final Page Tables and Memory Management.
  2. Interrupts: Sets up the IDT (Interrupt Descriptor Table).
  3. Drivers: Initializes basic hardware (Timers, Keyboard, VGA/GOP).
  4. The First Process: The kernel finally spawns the first user-space process, known as init (or systemd, launchd). This process has a Process ID (PID) of 1.

A C pseudo-code example of the kernel initialization flow calling scheduler and launching the first thread:

void kernel_entry(unsigned long magic, unsigned long addr) {
    if (magic != 0x2BADB002) {
        halt_system("Invalid Multiboot signature");
    }
    setup_memory(addr);
    setup_idt();
    init_drivers();
    
    // Spawn the first process (PID 1)
    if (spawn_process("/sbin/init") == 1) {
        enable_interrupts();
        start_scheduler();
    }
}

5. Summary: The Chain of Trust

Every boot cycle follows a linear sequence, handing execution control from low-level hardware up to the final user-facing environment:

  1. Hardware -> Firmware (BIOS/UEFI)
  2. Firmware -> Bootloader (GRUB/BOOTMGR)
  3. Bootloader -> Kernel (Linux/XNU/NT)
  4. Kernel -> Init (PID 1)
  5. Init -> User Space (Login screen, Shell)

The transition from a raw bootloader to kernel space can be observed in a Linux kernel log boot buffer:

[    0.000000] Linux version 6.1.0-21-amd64 ...
[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.1.0-21-amd64 root=/dev/sda1 ro quiet
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
...
[    1.234567] Run /sbin/init as init process
[    1.250102] systemd[1]: systemd 252.22-1~deb12u1 running in system mode.

6. Interactive Practice: Multiboot Verification

When writing a kernel entry point in assembly, you must ensure the bootloader recognizes it. Verify the boot signature and handover values below.

Multiboot Verification

/* The bootloader places this magic value in EAX */\n0xBAD002

References & Further Reading

  • Multiboot Specification (GNU official specification manual)
  • GNU GRUB Manual (GNU GRUB manual)
  • Bootloader (CC-BY-SA 4.0)
  • Boot loaders (CC-BY-SA 4.0)
  • Silberschatz, A., Galvin, P. B., & Gagne, G. (2018). Operating System Concepts (10th ed.). John Wiley & Sons.
  • Tanenbaum, A. S., & Bos, H. (2015). Modern Operating Systems (4th ed.). Pearson.