Boot#

The Linux boot sequence brings a powered-off machine to a running system in a small number of well-defined stages (firmware → bootloader → kernel → initramfs → init). Each stage hands control to the next. Understanding where it is in the chain is the first step in diagnosing a boot failure.

        flowchart LR
    FW["Firmware<br/>BIOS / UEFI"] --> BL["Bootloader<br/>GRUB / systemd-boot"]
    BL --> KR["Kernel<br/>vmlinuz"]
    KR --> IR["Initramfs<br/>/init"]
    IR --> IT["Init<br/>systemd, PID 1"]
    

Boot Sequence#

Linux boot runs in five standard stages, in order, each preparing the conditions the next depends on. Knowing which stage you are in narrows any failure to a handful of likely causes before you start digging into logs.

Stage

What happens

  1. Firmware

BIOS or UEFI runs, performs POST, finds a boot device

  1. Bootloader

Loaded from disk; locates and loads the kernel + initramfs

  1. Kernel

Decompresses, initializes hardware, mounts initramfs

  1. Initramfs

Provides drivers / decryption / LVM to mount the real root

  1. Init (PID 1)

systemd (or alternative) starts services and reaches a target

1. Firmware#

The firmware (BIOS or UEFI) is the first code to run after power-on. It performs POST, enumerates devices, and selects a boot source. UEFI loads a .efi from the ESP via NVRAM BootOrder. Legacy BIOS reads MBR boot code. Secure Boot verifies the loader’s signature when enabled.

Step

What happens

  1. Power-on / reset

CPU jumps to its reset vector and runs firmware ROM

  1. Firmware POST

BIOS/UEFI POST checks CPU, memory, integrated devices

  1. Firmware device enumeration

Buses are scanned; storage, NICs, USB are registered

  1. Boot-device selection

UEFI consults NVRAM BootOrder; BIOS reads MBR boot signature

  1. First-stage loader handoff

UEFI loads .efi from ESP; BIOS loads MBR/VBR boot code

The firmware is the first code that runs after power-on. Modern systems use UEFI; legacy systems used BIOS. Both probe attached devices, expose a small runtime to the OS, and hand control to a bootloader once a valid boot source has been selected.

Component

Purpose

BIOS

Legacy x86 firmware; looks for an MBR boot record

UEFI

Modern firmware; loads .efi from the EFI System Partition (ESP)

ESP (/boot/efi)

FAT32 partition holding bootloader .efi files

NVRAM boot entries

UEFI variables ordering boot candidates

Secure Boot

UEFI extension; verifies signed bootloaders

TPM

Trusted Platform Module; measures boot for attestation

/sys/firmware/efi/

Kernel-exposed EFI variables and tables

/sys/firmware/dmi/

DMI / SMBIOS information from firmware

Example.

$ [ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS / legacy"
$ sudo efibootmgr -v
$ sudo dmidecode -t bios
$ mokutil --sb-state

2. Bootloader#

Loaded by firmware, the bootloader (GRUB, systemd-boot, U-Boot) reads its config and locates vmlinuz and initramfs on disk, then copies them into RAM. It builds the kernel command line that becomes /proc/cmdline and jumps to the kernel’s entry point.

Step

What happens

  1. Bootloader main stage

Reads its config (grub.cfg / loader entries)

  1. Boot-menu / default

User picks an entry, or the default fires after a timeout

  1. Kernel + initramfs into RAM

Loader copies vmlinuz and initramfs.img from /boot

  1. Kernel command line passed

Args from the loader become /proc/cmdline

  1. Kernel handoff

Loader jumps into the kernel entry point

The bootloader is loaded by the firmware and is responsible for finding the kernel image, loading it and the initramfs into memory, and passing in the boot command line that the kernel will read back as /proc/cmdline.

Tool

Purpose

grub

GRUB 2, the dominant Linux bootloader

grub-install

Install GRUB into a target device or ESP

grub-mkconfig

Regenerate grub.cfg from /etc/default/grub + scripts

update-grub

Debian/Ubuntu wrapper around grub-mkconfig

grub2-mkconfig

Same on RHEL family

systemd-boot

Simple UEFI-only loader (bootctl)

bootctl

Manage systemd-boot entries

rEFInd

Graphical UEFI boot manager

syslinux

Lightweight loader (PXE, USB sticks)

isolinux

Syslinux variant for ISOs

pxelinux

Syslinux variant for PXE network boot

u-boot

Embedded / ARM bootloader

LILO

Legacy x86 loader (mostly retired)

Example.

$ sudo update-grub
$ sudo grub-install /dev/sda
$ sudo bootctl status
$ sudo bootctl list

3. Kernel#

The compressed kernel self-decompresses, sets up paging and the GDT/IDT, brings the CPU online, initializes the scheduler, and probes builtin drivers. The initramfs cpio archive is unpacked into a tmpfs rootfs and mounted as the temporary root filesystem.

Step

What happens

  1. Kernel decompression

The compressed kernel self-extracts in place

  1. Early kernel init

Memory management, IDT/GDT, page tables, console set up

  1. Subsystem init

Scheduler, VFS, networking stubs, drivers compiled in

  1. Initramfs unpacked

The cpio archive is unpacked into a rootfs tmpfs

The kernel is loaded by the bootloader and unpacks the initramfs into RAM. The initramfs provides whatever userland is needed to mount the real root filesystem (typically drivers, cryptsetup, LVM, and the network for NFS roots).

Path / tool

Purpose

/boot/vmlinuz-<ver>

Compressed kernel image

/boot/initramfs-<ver>.img

Initial ramdisk (Debian uses initrd.img-<ver>)

/boot/config-<ver>

Kernel build configuration

/boot/System.map-<ver>

Kernel symbol map

/proc/cmdline

Active kernel command line

/proc/version

Running kernel version string

uname -r

Running kernel release

mkinitcpio

Build initramfs (Arch family)

dracut

Build initramfs (RHEL / Fedora / openSUSE)

update-initramfs

Build initramfs (Debian / Ubuntu)

lsinitramfs

Inspect contents of an initramfs

lsinitcpio / lsinitrd

Distro-specific initramfs inspectors

Example.

$ uname -r
$ cat /proc/cmdline
$ sudo update-initramfs -u
$ lsinitramfs /boot/initrd.img-$(uname -r) | head

4. Initramfs#

PID 1 inside the initramfs is /init. It loads kernel modules via udev, unlocks LUKS volumes, assembles LVM/RAID arrays, and waits for the real root device. Once mounted, switch_root makes it / and the initramfs memory is freed.

Step

What happens

  1. Switch to userspace

Kernel execs /init inside the initramfs as PID 1

  1. Initramfs work

Loads modules, opens LUKS, assembles RAID/LVM, awaits root

  1. Real root mounted

Initramfs mount-s the real root read-only at /sysroot

  1. pivot_root

Real root becomes /; old initramfs is freed

After the kernel mounts the real root, it executes PID 1 (the init process). The init system then brings the rest of the system to a runtime state by starting services in dependency order until a target like multi-user or graphical is reached.

Init system

Notes

systemd

Dominant on Debian, Ubuntu, Fedora, RHEL, Arch, openSUSE

sysvinit

Classic SysV init scripts (/etc/init.d); legacy

OpenRC

Used by Alpine, Gentoo

runit

Minimal supervision-tree init (Void)

s6 / s6-rc

Process supervision suite

Upstart

Event-based init (Ubuntu 6.10–14.10); retired

BusyBox init

Minimal init for embedded / Alpine-style systems

launchd

macOS init (for cross-reference)

Example.

$ ps -p 1 -o comm=
$ ls -l /sbin/init
$ systemctl --version

5. Init (PID 1)#

The kernel execs /sbin/init (usually systemd) as the new PID 1. systemd resolves the default.target, computes the dependency graph, and starts units in parallel through sysinit.target and basic.target to either multi-user.target or graphical.target, ending with a getty or display manager.

Step

What happens

  1. Real init exec

/sbin/init (usually a symlink to systemd) replaces PID 1

  1. Read default.target

The boot-end-state target is resolved

  1. Dependency graph computed

All units required by the target are queued

  1. Units started in parallel

Sockets, mounts, services launch in dependency order

  1. sysinit.target reached

Sync point for fstab mounts, sysctl, modules, tmpfiles

  1. basic.target reached

Basic system is ready (sockets, slices, timers)

  1. Service targets reached

multi-user.target and (optionally) graphical.target

  1. getty / DM starts

A login prompt or display manager is presented to the user

  1. User logs in

PAM authenticates; user shell or session starts

Example.

$ systemd-analyze
$ systemd-analyze blame
$ systemd-analyze critical-chain
$ systemd-analyze plot > boot.svg

Systemd Boot Targets#

systemd replaces SysV runlevels with targets, named units that group other units. The default target determines the system’s boot end-state, and switching it (or one-shot isolating to another) is how you choose between graphical, console, and rescue postures without rebuilding anything.

Target

Purpose (rough SysV-runlevel equivalent)

poweroff.target

Halt and power off (runlevel 0)

rescue.target

Single-user with root shell + minimal services (runlevel 1)

multi-user.target

Non-graphical multi-user (runlevels 2/3/4)

graphical.target

Multi-user + display manager (runlevel 5)

reboot.target

Reboot (runlevel 6)

emergency.target

Emergency shell on the root filesystem only

default.target

Symlink → the boot target (usually graphical.target)

sysinit.target

Early-boot synchronization point

basic.target

Basic system ready

network-online.target

Network is up and reachable

halt.target

Halt without power off

Example.

$ systemctl get-default
$ sudo systemctl set-default multi-user.target
$ sudo systemctl isolate rescue.target
$ systemctl list-units --type=target

Boot-Time Files#

The configuration that shapes each stage of boot. Most boot misbehavior roots in one of these files (a stale GRUB config, a missing fstab entry, a forgotten crypttab line, or an initramfs that has not been rebuilt after a kernel or module change).

Path

Purpose

/etc/default/grub

GRUB user-facing settings (GRUB_CMDLINE_LINUX, etc.)

/boot/grub/grub.cfg

Generated GRUB configuration (do not edit by hand)

/boot/loader/entries/

systemd-boot per-entry config

/etc/fstab

Persistent mount config consulted after root is mounted

/etc/crypttab

LUKS volumes unlocked at boot

/etc/mkinitcpio.conf

Arch initramfs build config

/etc/dracut.conf

Dracut initramfs build config

/etc/initramfs-tools/

Debian initramfs build config

/etc/systemd/system/

Local systemd unit overrides

/etc/systemd/system.conf

systemd manager settings

/etc/modules-load.d/*.conf

Kernel modules to load at boot

/etc/modprobe.d/*.conf

Module options / blacklists

/etc/sysctl.d/*.conf

Sysctl values applied at boot

/etc/tmpfiles.d/*.conf

systemd-tmpfiles rules

/etc/os-release

Distribution identity (consumed by many boot tools)

Example.

$ sudo nano /etc/default/grub
$ sudo update-grub
$ sudo systemctl daemon-reload
$ sudo systemctl reboot

Diagnostics#

When the boot is slow, fails, or behaves oddly, these are the tools that show what happened. They reach into the systemd journal, the kernel ring buffer, and the unit graph to surface the slow units, the failed units, and the messages that explain why.

Tool

Purpose

systemd-analyze

Total boot time + per-stage breakdown

systemd-analyze blame

Slowest units

systemd-analyze critical-chain

Critical path of the boot

systemd-analyze plot

SVG plot of the boot timeline

systemd-analyze verify

Static unit-file lint

journalctl -b

Logs from this boot

journalctl -b -1

Logs from the previous boot

journalctl -k

Kernel messages from the journal

dmesg

Kernel ring buffer (live)

dmesg -T

With human-readable timestamps

last reboot

Reboot history

uptime

How long since last boot

systemctl --failed

Units that failed during boot

systemctl list-jobs

Units still running early in boot

cat /proc/cmdline

Kernel command line passed by the bootloader

efibootmgr -v

UEFI boot order / entries

Example.

$ systemd-analyze
$ systemd-analyze blame | head
$ journalctl -b -p err
$ dmesg -T | tail -50
$ systemctl --failed

Common Tasks#

Identify the firmware mode. BIOS or UEFI decides which loader path is in use.

$ [ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
$ sudo dmidecode -t bios | head

Check Secure Boot and MOK trust. The signed-loader chain that gates kernels and modules.

$ mokutil --sb-state
$ mokutil --list-enrolled | head
$ sudo dmesg | grep -i 'secure ?boot'

Enumerate UEFI boot entries. .efi loaders the firmware knows about, in priority order.

$ sudo efibootmgr -v
$ sudo efibootmgr -v | grep ^BootCurrent       # which entry booted us
$ ls /boot/efi/EFI/

Read the kernel command line. Ground truth for what the bootloader actually passed in.

$ cat /proc/cmdline
$ grep -E '^GRUB_CMDLINE' /etc/default/grub
$ ls /boot/

Profile the boot timeline. Find which stage and which units cost the time.

$ systemd-analyze
$ systemd-analyze blame | head -20
$ systemd-analyze critical-chain
$ systemd-analyze plot > boot.svg

Triage a failed boot. Failed units, error-priority logs, and the kernel ring buffer.

$ systemctl --failed
$ journalctl -b -p err --no-pager
$ journalctl -b -1 -p err --no-pager           # the previous boot
$ dmesg -T | tail -50

Walk reboot history. When the box last came up and whether any boots were unclean.

$ last reboot | head -20
$ journalctl --list-boots
$ uptime -s

Hunt boot-path persistence. Bootloader hooks, initramfs hooks, autoloaded modules.

$ ls -la /etc/grub.d/ /etc/default/grub.d/ 2>/dev/null
$ ls -la /etc/initramfs-tools/hooks/ /etc/dracut.conf.d/ 2>/dev/null
$ ls -la /etc/modules-load.d/ /etc/modprobe.d/
$ lsmod | head -20

Reboot, power off, or halt. Graceful shutdown, optionally scheduled.

$ sudo systemctl reboot
$ sudo systemctl poweroff
$ sudo shutdown -r +5 'patching kernel'
$ sudo shutdown -c                              # cancel a pending shutdown

Change the default boot target. Pick the end-state without rebuilding the image.

$ systemctl get-default
$ sudo systemctl set-default multi-user.target
$ sudo systemctl isolate rescue.target          # one-shot, no reboot

Rebuild bootloader and initramfs. After a kernel, module, or crypto change.

$ sudo update-grub                              # Debian/Ubuntu
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg   # RHEL family
$ sudo update-initramfs -u -k all               # Debian/Ubuntu
$ sudo dracut -f                                # RHEL/Fedora

Recover from a bad boot. One-shot cmdline edits and rescue targets.

# at the GRUB menu: press 'e', edit the linux line, Ctrl-X to boot
# add 'systemd.unit=rescue.target' or 'init=/bin/bash' for recovery
$ sudo grub-reboot 'Advanced options...'        # one-shot next boot
$ sudo systemctl rescue                         # drop running system to rescue

References#

  • man bootup (the same sequence in systemd’s own words).

  • man systemd, man init, man openrc (init systems).

  • man systemd-analyze, man systemd.target, man systemd.special, man systemd.unit (boot targets and unit semantics).

  • man journalctl, man dmesg (boot logs and kernel ring buffer).

  • man efibootmgr, man mokutil, man dmidecode (firmware, Secure Boot, hardware tables).

  • man grub-mkconfig, man update-grub, man bootctl (bootloader configuration).

  • man initramfs-tools, man dracut, man mkinitcpio (initramfs build tooling).

  • man 5 fstab, man 5 crypttab (mounts and encrypted volumes consulted at boot).

  • Services for systemd unit and service management and inspecting failed services.

  • Filesystem for /etc, /boot, and /boot/efi layout.

  • Linux for the command quick-reference.

  • UEFI Specification

  • GRUB manual

  • systemd-boot

  • kernel.org bootconfig

  • Linux Insides, Booting

  • Arch Wiki, Arch Boot Process