Demystifying the Linux Boot Process: From Firmware to systemd
Trace a modern Linux boot across firmware, boot manager, kernel, initramfs, real root, and PID 1 with safe diagnostics for each handoff.
A Linux boot is a chain of trust and responsibility, not one program starting another in a fixed universal sequence. Firmware selects an executable, a boot manager or EFI stub prepares a kernel, early userspace discovers the real root, and an init system constructs normal userspace. Architecture, firmware mode, distribution, encryption, measured boot, and bootloader choice can change the chain.
The useful diagnostic question is therefore: which handoff completed, and what exact artifact was supposed to execute next?
Stage 0: preserve the known-good path
Before changing boot files, capture the current kernel command line, mounts, firmware mode, boot entries, block layout, and successful boot journal. These commands are read-only:
cat /proc/cmdline
findmnt / /boot /boot/efi
lsblk -o NAME,TYPE,FSTYPE,FSVER,SIZE,UUID,PARTUUID,MOUNTPOINTS
test -d /sys/firmware/efi && echo UEFI || echo legacy-or-other
journalctl -b -0 -p warning
Keep current rescue media and a verified backup of the EFI System Partition or /boot. Do not run grub-install, rewrite NVRAM, regenerate initramfs, or edit partition flags merely to explore the process.
Stage 1: firmware discovers a boot target
Legacy PC BIOS and UEFI are different protocols. A classic BIOS path commonly reads a boot sector and transfers control to small loader code, which then finds later stages. It is inaccurate to say every BIOS simply executes “the first 440 bytes”: sector layout, partitioning, embedding area, and bootloader stages vary.
UEFI implements a boot manager. NVRAM variables such as BootOrder and Boot#### identify device paths and EFI applications. On a running UEFI system, inspect them with:
efibootmgr -v
This usually needs elevated read access. Do not use -c, -b ... -B, or change BootOrder during diagnosis. Removable-media fallback names such as \EFI\BOOT\BOOTX64.EFI are architecture-specific, not the universal installed-OS path.
Stage 2: Secure Boot and measured boot alter trust
On Secure Boot systems, firmware verifies an EFI image according to platform policy. Many distributions use a signed shim that validates the next loader and kernel under their supported key chain. TPM measurements are evidence of components/configuration; they are not the same thing as signature enforcement.
Inspect current state through distribution-supported tools and firmware UI. Never disable Secure Boot as the first response to a failed update. Capture the rejected component and signature status, then restore the last signed package or boot entry.
Stage 3: bootloader or EFI stub selects the kernel
GRUB can read filesystems, present entries, load a Linux kernel and initramfs, supply a command line, or chainload another application. It is common, not mandatory: systemd-boot, firmware loading a Unified Kernel Image, U-Boot, zipl, and direct EFI-stub boot are legitimate alternatives.
GRUB’s generated configuration is an output. Distribution inputs and generation commands differ. Debian-family systems often wrap grub-mkconfig with update-grub; other layouts use different output paths. Never copy this command blindly:
grub-mkconfig -o /boot/grub/grub.cfg
First read the distribution’s current bootloader documentation and package hooks. Writing the wrong path may create an unused file while leaving the real loader broken.
Stage 4: kernel entry and early initialization
The loader supplies the kernel image, optional initramfs, and command line through the architecture’s boot protocol. The kernel decompresses, initializes memory management, interrupts, scheduling, built-in drivers, and enough virtual filesystems to start early userspace.
Parameters such as root=, rootflags=, rd.luks.*, or systemd.unit= are interpreted by different components; not every parameter belongs to the kernel itself. Inspect authoritative parameter documentation and the actual /proc/cmdline before modifying one at the boot menu.
Stage 5: initramfs becomes temporary root
An initramfs is generally one or more compressed cpio archives extracted into rootfs. If it supplies /init, the kernel executes that as PID 1 for early userspace. The image can contain storage modules, udev, LVM, MD RAID, networking, integrity tooling, and cryptsetup needed to discover the real root.
Inspect without modifying:
lsinitramfs /boot/initrd.img-"$(uname -r)" | less
# dracut-based systems may provide:
lsinitrd
Tool and filename availability are distribution-specific. A running kernel’s uname -r may not be the failed entry, so inspect the filename selected by that boot entry too.
Stage 6: early userspace resolves the root graph
Early userspace must turn identifiers from the command line into a mountable root. That may mean waiting for devices, loading a driver, unlocking LUKS, assembling RAID, activating LVM, checking integrity, or bringing up network storage. A timeout here is usually a discovery graph problem, not “systemd failed.”
Use UUID/PARTUUID evidence from blkid and lsblk; do not repair by replacing stable identifiers with whichever /dev/sdX name happened to appear today. Device enumeration is not a persistent contract.
Stage 7: switch to the real root
Once the real root is mounted, initramfs normally uses switch_root or an equivalent mechanism to make it /, discard or detach early userspace, and execute the real init program. Older initrd designs and pivot_root are related but not identical to modern initramfs behavior.
If /init cannot find or execute the target init, the emergency shell belongs to the initramfs environment. Its commands, binaries, mounts, and logs may differ radically from the installed system.
Stage 8: PID 1 constructs normal userspace
Many current distributions use systemd as PID 1, but Linux does not require it. OpenRC, runit, s6, BusyBox init, SysV-style init, and specialized init programs exist. The kernel ultimately attempts the configured init path and has documented fallbacks when no early /init handled boot.
On systemd, default.target pulls in a dependency transaction. Units can start concurrently according to ordering and requirement edges; a slow unit in blame is not automatically on the critical path.
ps -p 1 -o pid,comm,args
systemctl get-default
systemd-analyze time
systemd-analyze critical-chain
Stage 9: boot completion has multiple meanings
The kernel may be healthy while an encrypted root is unavailable; PID 1 may run while the display manager fails; multi-user.target may be reached while a network-online dependency waits. Define the expected milestone: emergency shell, local login, graphical session, application readiness, or externally reachable service.
systemd-analyze blame reports unit activation duration and can mislead when jobs wait in parallel. Use critical-chain, unit dependencies, and timestamps together. Firmware/loader timing is available only when the platform and loader expose it.
Stage 10: diagnose by the last trustworthy evidence
For completed systemd boots:
journalctl --list-boots
journalctl -b -1 -p warning..alert
journalctl -k -b -1
systemctl --failed
journalctl -k shows kernel messages captured by the journal, not firmware logs. Persistent previous-boot logs require persistent journal storage and a clean enough failure to save them. For earlier kernel output, earlycon is the current general mechanism where the architecture/console supports it; earlyprintk is older and architecture-specific.
Stage 11: recover with one reversible change
At the boot menu, temporarily remove only the suspected parameter or select the previous packaged kernel. Photograph the original entry first. If recovery succeeds, compare kernel, initramfs, command line, loader entry, and signatures before making the change permanent.
Regenerate initramfs only with the distribution’s supported tool (update-initramfs, dracut, mkinitcpio, or another), correct target version, sufficient free space, and a backup. Package hooks normally coordinate kernel, initramfs, and loader metadata; bypassing them can create a version mismatch.
Stage 12: treat the handoffs as an evidence chain
Record firmware mode and entry, EFI executable/hash/signature, bootloader entry, kernel and initramfs versions/hashes, exact command line, root identifiers, PID 1, failed unit, and recovery action. The process is understood when every transition identifies its producer, consumer, artifact, and failure evidence—without assuming GRUB, systemd, x86, or one distribution is universal.
Related:
- Fixing a Linux System Stuck at ‘grub rescue>’
- Fixing a Broken GRUB2 Configuration After a Failed Update
Sources: