When a machine powers on, the kernel does not exist yet. Something has to find it, load it, and hand over control before any of it can run.
This is the job of the bootloader.
Power-On State
When power reaches the motherboard, the CPU starts executing instructions. It does not start executing the operating system. It starts executing firmware — code stored in a read-only chip on the motherboard itself, at a fixed memory address the CPU is hardwired to jump to on reset.
At this point, on x86 hardware, the CPU is in real mode: a 16-bit execution environment inherited from the original IBM PC. No memory protection, no privilege levels, no virtual memory. The CPU can address only the first megabyte of RAM. There is one active core, executing one instruction at a time, starting from one fixed address.
The firmware's job is to do enough to hand off to something more capable.
BIOS and UEFI
For decades, that firmware was BIOS — Basic Input/Output System. BIOS initialised hardware, performed a power-on self-test, then searched for a bootable device by reading the first 512 bytes of each disk in order. If those 512 bytes ended with the signature 0x55AA, BIOS loaded them into memory at address 0x7C00 and jumped to them. That 512-byte region is the Master Boot Record.
The MBR contained a tiny first-stage bootloader — tiny because 512 bytes is almost nothing. Its job was purely to load a larger, more capable second stage from elsewhere on the disk.
BIOS worked, but it had hard limits. It could not read disks larger than 2 terabytes. It could not boot from the GPT partition scheme. It had no security mechanism — any code in the MBR would run, regardless of whether it had been tampered with. By the 2000s these limits were becoming real problems.
UEFI — Unified Extensible Firmware Interface — replaced BIOS on most hardware through the 2010s. UEFI is a full firmware specification: it runs in 32-bit or 64-bit mode from the start, supports disks beyond 2 terabytes, reads the GPT partition scheme natively, and includes a dedicated partition — the EFI System Partition — that contains bootloaders as ordinary files in a FAT32 filesystem.
UEFI does not search blindly for a boot sector. It maintains a list of boot entries, each pointing to a specific file on the EFI System Partition. On a Linux system that entry typically points to GRUB. UEFI finds the file, loads it, and transfers control.
Secure Boot
UEFI introduced something BIOS never had: a mechanism to verify that the bootloader is trustworthy before running it.
Secure Boot works through cryptographic signatures. The firmware holds a database of trusted public keys. Before loading any bootloader, UEFI checks its signature against this database. If the signature is valid — if the bootloader was signed with a private key corresponding to a trusted public key — it runs. If not, UEFI refuses to load it.
This creates a chain of trust. UEFI verifies the bootloader. The bootloader verifies the kernel. Each link in the chain checks the next before handing control forward. A tampered bootloader — one modified by malware, for example — will fail the signature check and the boot will stop.
The chain depends on the root of trust: the keys stored in firmware. On most consumer hardware, Microsoft's key is present by default, which is why Windows boots under Secure Boot without configuration. Linux distributions ship signed bootloaders — typically a shim, a small first-stage loader developed by the Linux community and signed by Microsoft, which then loads GRUB — so they work with default Secure Boot settings. On servers and developer hardware, Secure Boot can often be disabled or reconfigured with custom keys.
Secure Boot does not protect a running system. Once the kernel is loaded and verified, Secure Boot's job is done. It protects only the boot process — specifically, it prevents an attacker who has modified the bootloader from having that modification run silently on next boot.
GRUB
On most Linux systems, the file UEFI loads is GRUB — the Grand Unified Bootloader.
GRUB's job is to find the kernel on disk, load it into memory, and transfer control to it. This sounds straightforward, but at the point GRUB runs, there is no operating system to help. There is no filesystem driver in the kernel, because the kernel isn't loaded yet. GRUB has to read the filesystem itself.
GRUB contains its own implementations of common filesystem drivers — ext4, Btrfs, XFS, FAT32, and others. When GRUB starts, it reads its configuration file (/boot/grub/grub.cfg) to find out where the kernel is and what parameters to pass it. It then reads the kernel image directly from disk using its own filesystem code, loads it into RAM, and does the same for the initramfs.
The GRUB menu you see at boot — if it appears — is generated from this configuration. Each entry corresponds to a different kernel version or boot option. The configuration is generated automatically by update-grub on Debian-based systems or grub-mkconfig on others, reading from /etc/default/grub and scanning for installed kernels.
You can inspect your current GRUB configuration:
head -50 /boot/grub/grub.cfg
Each menuentry block is one boot option. The linux line specifies the kernel image path and parameters. The initrd line specifies the initramfs image.
The initramfs
GRUB loads two things into memory: the kernel image and the initramfs.
The initramfs — initial RAM filesystem — is a compressed archive that the kernel extracts into a temporary in-memory filesystem at boot. It contains a minimal root filesystem: enough tools and drivers to mount the real root filesystem.
This exists because of a circular dependency. The kernel needs drivers to read the disk the root filesystem lives on. Those drivers might be compiled as modules — separate files stored on that disk. But to load files from disk, you need the drivers. The initramfs breaks the cycle: it carries the necessary modules with it in RAM, loaded before any disk is touched.
On an encrypted disk, the initramfs is also where decryption happens. The kernel cannot mount an encrypted root filesystem without the key. The initramfs contains the tools to prompt for a passphrase, decrypt the volume, and hand off a usable block device to the rest of the boot process.
Once the real root filesystem is mounted, the initramfs is discarded. The kernel pivots to the real root and continues.
Inspect the contents of your initramfs:
lsinitramfs /boot/initrd.img-$(uname -r) | head -30
You will see a minimal filesystem: a few binaries, a lib directory with kernel modules, and scripts that run the early boot logic.
The Kernel Starts
With the kernel image and initramfs loaded into memory, GRUB transfers control to the kernel's entry point. The kernel starts executing.
The first thing it does is set up the environment it needs to run. The CPU is still in a relatively bare state — on UEFI systems GRUB hands off in 64-bit long mode, on legacy BIOS systems in 32-bit protected mode, but in either case the kernel needs to establish its own page tables, set up its own stack, configure the interrupt descriptor table, and bring the rest of the hardware into a known state. This early initialisation is architecture-specific assembly code that runs before any C code in the kernel executes.
Once the environment is ready, the kernel calls start_kernel() — a C function in init/main.c in the kernel source. This is the kernel's own main function. It initialises subsystems in order: memory management, the scheduler, the interrupt handling framework, the virtual filesystem layer, device drivers, the network stack. Each subsystem depends on the ones before it. The order matters.
The full list is in the kernel's own boot log:
dmesg | head -80
Each line is a kernel message from initialisation, in the order it happened. You will see memory detection, CPU feature detection, interrupt controller setup, PCI bus enumeration, storage driver initialisation, filesystem mounting. The timestamp on each line is seconds since boot — most of this happens in the first two seconds.
Kernel Panic
If anything in this sequence fails unrecoverably, the kernel panics.
A kernel panic is not a crash in the normal sense. It is a deliberate halt — the kernel has detected a condition it cannot recover from and has stopped execution rather than continue in an undefined state. Common causes during boot: the initramfs fails to mount the root filesystem, a required driver is missing, memory corruption is detected, the kernel image itself is damaged.
When a panic occurs, the kernel prints a stack trace and a message describing the cause, then stops. On most systems the screen freezes with the panic output visible. On headless servers the output goes to the serial console or is captured by a crash dump mechanism.
Unlike a process crash, which affects only that process, a kernel panic affects everything — because everything runs on top of the kernel. There is no recovery path. The machine must be restarted.
The most common panic during a fresh Linux installation is a missing initramfs or a misconfigured bootloader pointing at the wrong kernel image. The fix is always the same: boot from a live environment, correct the configuration, and rebuild the initramfs or reinstall GRUB.
End of Boot
Once start_kernel() finishes its initialisation sequence, the kernel spawns a single process: PID 1.
On modern Linux systems, PID 1 is systemd. The kernel hands control to it, and systemd takes over: starting services, mounting filesystems, bringing up the network, launching the processes that make the system usable.
At that point, the boot process is over. Everything from UEFI loading GRUB to the kernel calling start_kernel() ran before a single process existed. Now hundreds of processes are running, interrupts are firing, virtual memory is in place, the scheduler is switching contexts.
The next article goes one level deeper: the CPU privilege model that makes the boundary between user space and kernel space enforceable in hardware.
References
- GNU GRUB manual — full reference for GRUB configuration and commands
- Linux kernel source: init/main.c —
start_kernel()and the full initialisation sequence - UEFI specification — the full UEFI spec; the boot process section is readable without firmware engineering background
- Arch Linux wiki: Secure Boot — practical Secure Boot setup and key management, well-written regardless of distro