The Linux Boot Process Explained
Trace the full Linux boot sequence from UEFI firmware through GRUB2, the kernel, initramfs, and systemd to your login prompt — with diagnostics at each stage.
Before you start
- ▸Basic familiarity with the Linux command line and sudo privileges
- ▸A running Linux installation (physical or virtual machine) to run diagnostic commands against
- ▸Understanding of filesystem concepts such as partitions and mount points
Every time you press the power button, your Linux system executes a precise, layered sequence before the login prompt appears. Understanding that sequence lets you diagnose slow boots, fix broken systems from rescue media, and make informed decisions about partitioning and init configuration. This guide walks each stage from firmware handoff to your first shell.
Stage 1: UEFI Firmware
Modern x86-64 systems use UEFI (Unified Extensible Firmware Interface) rather than the legacy BIOS. When power is applied, the CPU starts executing code from a fixed address in flash memory — that code is the UEFI firmware.
- POST (Power-On Self Test) — the firmware checks installed RAM, CPU, and critical hardware. Failures here produce beep codes or firmware-level error screens before Linux is ever involved.
- EFI System Partition (ESP) — UEFI reads its boot entries from NVRAM and looks for
.efiexecutables on a FAT32-formatted ESP, typically mounted at/boot/efi. You can inspect and edit these entries withefibootmgr. - Secure Boot — if enabled, the firmware verifies each executable's cryptographic signature before running it. Most major distros ship signed shim loaders for compatibility.
# List current UEFI boot entries
efibootmgr -v
Output will vary but shows boot order, each entry's label, and the path to its .efi binary on the ESP.
Stage 2: The Bootloader (GRUB2)
GRUB2 is the bootloader on the vast majority of Linux installations. The UEFI firmware hands control to /boot/efi/EFI/<distro>/grubx64.efi (or the shim that chainloads it).
GRUB's job is to locate the kernel and initramfs images — usually under /boot — present a menu if configured to do so, pass kernel parameters, and transfer control to the kernel.
Key GRUB2 Files
/boot/grub2/grub.cfgor/boot/grub/grub.cfg— the generated config. Never edit this directly./etc/default/grub— the human-editable settings file./etc/grub.d/— scripts that buildgrub.cfg.
After editing /etc/default/grub, regenerate the config:
# Debian/Ubuntu
sudo update-grub
# Fedora / RHEL / Rocky
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# Arch (GRUB installed to EFI)
sudo grub-mkconfig -o /boot/grub/grub.cfg
Kernel parameters you specify with GRUB_CMDLINE_LINUX in /etc/default/grub are passed verbatim to the kernel at this stage. Common examples: quiet splash, nomodeset, systemd.unit=rescue.target.
Stage 3: The Linux Kernel
GRUB decompresses and executes the kernel image (a compressed self-extracting binary named vmlinuz-<version>). The kernel takes over the machine entirely.
- Initialises the memory subsystem, CPU scheduler, and interrupt handling.
- Detects and configures hardware using built-in drivers and device tree data (on ARM) or ACPI tables (on x86).
- Mounts the initramfs as a temporary root filesystem in RAM so it can load additional drivers before the real root filesystem is accessible.
The kernel does not start user-space processes directly except for one: /init inside the initramfs.
Inspecting Kernel Messages
# Full kernel ring buffer from current boot
dmesg | less
# Filter for errors and warnings only
dmesg --level=err,warn
Stage 4: initramfs
The initramfs (initial RAM filesystem) is a compressed cpio archive embedded alongside the kernel in /boot. The kernel unpacks it into a tmpfs and runs its /init script.
Its sole responsibility is to prepare enough of the environment to mount the real root filesystem. This includes:
- Loading kernel modules for the storage controller, filesystem type, and encryption layer.
- Assembling software RAID (
mdadm) or LVM volume groups. - Prompting for a LUKS passphrase if full-disk encryption is configured.
- Performing a
pivot_rootorswitch_rootto hand off to the real filesystem.
The initramfs is rebuilt automatically when you install a new kernel. You can also rebuild it manually:
# Debian/Ubuntu — rebuild for the running kernel
sudo update-initramfs -u
# Fedora / RHEL / Rocky
sudo dracut --force
# Arch
sudo mkinitcpio -P
If the initramfs cannot mount root (wrong UUID, missing module, bad passphrase), you land in an emergency shell inside the initramfs itself. This is not systemd — it is a minimal busybox or dracut shell. From there you can load modules, run blkid, and diagnose the problem before re-attempting the mount.
Stage 5: systemd as PID 1
Once the real root filesystem is mounted and switch_root completes, the kernel executes /sbin/init, which on all major modern distros is a symlink to /usr/lib/systemd/systemd. This process becomes PID 1 and never exits for the lifetime of the system.
systemd reads its configuration from unit files in /usr/lib/systemd/system/ (vendor) and /etc/systemd/system/ (admin overrides). Boot proceeds by activating the default target, usually graphical.target or multi-user.target.
Targets Replace SysV Runlevels
| SysV Runlevel | systemd Target | Purpose |
|---|---|---|
| 1 / S | rescue.target | Single-user rescue shell |
| 3 | multi-user.target | Multi-user, no GUI |
| 5 | graphical.target | Multi-user + display manager |
| 0 | poweroff.target | Halt |
| 6 | reboot.target | Reboot |
# See the current default target
systemctl get-default
# Change default to console-only (no GUI)
sudo systemctl set-default multi-user.target
systemd activates units in parallel wherever dependency ordering allows, which is why modern Linux systems boot much faster than old SysV sequential scripts. The dependency graph is expressed through Wants=, Requires=, After=, and Before= directives in unit files.
Stage 6: Login
The final units to start under graphical.target are:
- getty units (
[email protected]throughtty6) — provide virtual console login prompts viaagetty. - Display manager (
gdm.service,sddm.service,lightdm.service) — launches the graphical login screen and, after authentication, starts the user's compositor session (Wayland-native on GNOME ≥ 42 and KDE Plasma ≥ 6, Xorg fallback otherwise).
The display manager hands authenticated users a systemd user session (systemd --user, also PID 1 within that slice), which manages user-level services like pipewire, dbus, and xdg-autostart applications.
Analysing Boot Performance
systemd records precise timestamps for every unit. Use these commands to find bottlenecks:
# High-level boot time summary
systemd-analyze
# Time each unit took, slowest first
systemd-analyze blame
# Generate an SVG timeline of all units (open in a browser)
systemd-analyze plot > boot.svg
Common culprits for slow boots: NetworkManager-wait-online.service (disable if not needed at boot), slow fsck on large filesystems, and misconfigured NFS mounts with long timeouts.
# Disable the network online wait (safe for desktops)
sudo systemctl disable NetworkManager-wait-online.service
Troubleshooting Boot Failures
GRUB Rescue Shell
If GRUB cannot find its configuration you land in a minimal grub> or grub rescue> prompt. Reinstall GRUB from a live environment by chrooting into your installed system, then running the appropriate grub-install command for your distro.
initramfs Emergency Shell
Check dmesg output, verify the root device UUID matches what is in /etc/fstab with blkid, and ensure required kernel modules are listed in your initramfs config. Rebuild the initramfs and reboot.
systemd Units Failing
# See which units failed
systemctl --failed
# Inspect a specific failing unit's journal
journalctl -u <unit-name> -b --no-pager
The -b flag limits output to the current (or most recent) boot, which keeps the output focused on the failure you are investigating.
Frequently asked questions
- What is the difference between initrd and initramfs?
- initrd (initial ramdisk) was a block device image mounted as a ramdisk; initramfs is a cpio archive the kernel unpacks directly into tmpfs. Initramfs has been the standard since kernel 2.6.13 and avoids an extra block device layer.
- How do I add a kernel parameter without permanently changing the config?
- Highlight the boot entry in the GRUB menu, press 'e', navigate to the linux line, append your parameter (e.g. nomodeset), then press Ctrl+X to boot. The change is temporary and lasts only for that boot.
- Can I still use SysV init scripts on a systemd system?
- Yes. systemd ships a compatibility layer that wraps SysV init scripts as service units. However, they run sequentially and lose the benefits of parallel activation, so converting them to native unit files is recommended.
- Why does boot sometimes pause waiting for a network timeout?
- NetworkManager-wait-online.service blocks boot until a full network connection is available. On desktops this is rarely needed; disable it with systemctl disable NetworkManager-wait-online.service to recover several seconds.
- What happens if the ESP gets corrupted?
- The UEFI firmware cannot find or execute the bootloader, and the system will not boot at all. Boot from a live USB, remount or reformat the ESP, reinstall GRUB, and restore EFI entries with efibootmgr.
Related guides
AI and Artificial-Life Tools on Linux
Set up open-source AI/ML and artificial-life toolkits on Linux: PyTorch, JAX, DEAP, Avida, NetLogo, and RL environments with GPU driver guidance.
Assembly Language on Linux: A Starter Guide
Write x86-64 assembly on Linux from scratch: install NASM and GAS, learn syscalls, assemble and link a working program, then inspect and debug it.
How to Benchmark Disk Performance with fio
Learn to benchmark Linux disk performance with fio: writing job files, testing latency and throughput, and interpreting IOPS and percentile output correctly.
Btrfs Basics and Snapshots
Learn Btrfs subvolumes, instant copy-on-write snapshots, and safe system rollback — with both manual btrfs commands and Snapper automation.