Skip to content
daniel@cosenza:~/blog
LinuxDeep Dive May 11, 2026 4 min read

Demystifying the Linux Boot Process: From Firmware to systemd

A stage-by-stage tour from power-on firmware through GRUB, the kernel, initramfs, and systemd reaching a running system.

A Linux boot involves more distinct handoffs than most people realize — firmware to bootloader, bootloader to kernel, kernel to a temporary root filesystem, temporary root to the real one, and finally to PID 1. Each stage exists to solve a specific chicken-and-egg problem the previous one couldn’t.

Stage 1: firmware (BIOS or UEFI)

Firmware’s only job is to initialize just enough hardware to find and execute a bootloader. Legacy BIOS reads the Master Boot Record’s first 440 bytes and jumps to it; UEFI instead reads .efi executables directly from a dedicated EFI System Partition (ESP), a FAT-formatted partition firmware understands natively.

efibootmgr -v              # list UEFI boot entries and their target .efi files

Stage 2: the bootloader (GRUB)

GRUB’s job is to locate a kernel image and an initramfs, load both into memory, and jump to the kernel with the right command-line parameters. Its configuration is generated, not hand-written directly, from /etc/default/grub and /etc/grub.d/ scripts:

# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
grub-mkconfig -o /boot/grub/grub.cfg

The generated grub.cfg contains explicit linux and initrd directives per boot entry, pointing at specific kernel and initramfs files under /boot — which is exactly why a kernel update needs a grub-mkconfig re-run (usually automated by the package manager’s post-install hook) to actually become bootable.

Stage 3: the kernel and initramfs

The kernel image GRUB loads is self-contained but doesn’t yet know how to access the real root filesystem — it might be on an encrypted volume, a RAID array, or behind a driver not compiled into the kernel itself. The initramfs (initial RAM filesystem) is a small, temporary root filesystem, loaded into memory alongside the kernel, containing just enough tooling (kernel modules, cryptsetup, LVM tools) to assemble and mount the real root.

lsinitramfs /boot/initrd.img-$(uname -r) | head
# Regenerate after adding a kernel module or changing disk configuration
update-initramfs -u
# or, on dracut-based distributions:
dracut --force

Once the initramfs’s /init script has done its job — unlocking an encrypted volume, assembling an LVM volume group, loading a storage driver — it calls switch_root to hand off execution to the real root filesystem, discarding the temporary one.

Stage 4: PID 1

On the real root, the kernel executes /sbin/init — on essentially every mainstream distribution today, a symlink to systemd. This is where the boot process shifts from a fixed, linear sequence into systemd’s dependency-graph model, starting from default.target and pulling in whatever units that target (transitively) requires.

systemctl get-default
systemd-analyze

Measuring where boot time actually goes

systemd-analyze breaks the whole boot down into firmware, bootloader, kernel, and userspace phases, and systemd-analyze blame ranks individual units by how long they took to become ready — the standard starting point for any boot-time optimization work:

systemd-analyze
# Startup finished in 2.1s (firmware) + 1.8s (loader) + 3.4s (kernel) + 4.9s (userspace) = 12.2s

systemd-analyze blame
# 2.803s NetworkManager-wait-online.service
# 1.245s systemd-udev-settle.service

Debugging a failed boot

journalctl -b reads the systemd journal scoped to a specific boot (with -b -1 for the previous boot, invaluable after a crash), and appending systemd.log_level=debug to the kernel command line (editable at the GRUB menu with e) gets far more verbose output for a boot that’s failing before the journal is even reliably capturing it. For failures earlier than that — before the kernel has even initialized — the kernel parameter earlyprintk and firmware-level logs (journalctl -k -b, or the firmware’s own boot log where available) are usually the next place to look.

Why the layering matters

Each of these stages solves one problem: firmware finds a bootloader without knowing anything about filesystems or kernels; the bootloader finds a kernel and initramfs without needing to understand encryption or RAID; the initramfs assembles whatever complex storage stack the real root needs without that logic having to live in the kernel image itself; and systemd takes over process supervision only once a real, stable root filesystem exists to run services from. Any boot failure can almost always be pinned to exactly one of these stages, which is what makes “where did it stop” the right first question rather than “what’s wrong with Linux.”