The Boot Process
From power-on to login prompt, a Linux machine moves through firmware, a bootloader, the kernel, and finally the init system - knowing the order matters most when something fails partway through.
Boot problems are much easier to diagnose once you know which stage failed, because each stage hands off to the next and failures look very different depending on where they happen.
The stages, in order
- Firmware (BIOS or UEFI) - runs hardware self-tests (POST), then looks for a bootable device. UEFI is standard on any machine built in the last decade or so; legacy BIOS survives mostly in older hardware and some virtual machines.
- Bootloader - GRUB2 on most Linux distributions. Reads its
configuration (
/boot/grub/grub.cfg, generated - don't hand-edit it), presents a menu if configured to, and loads the selected kernel image plus its initial RAM filesystem into memory. - Kernel + initramfs - the kernel starts running, using the
initramfs(a minimal temporary root filesystem) to load the drivers needed to mount the real root filesystem - notably useful when root lives on RAID, LVM, or an encrypted volume, where the driver needed to even find the disk isn't built into the kernel itself. - Switch to real root, start init - once the real root filesystem is mounted, the kernel hands control to the init system, PID 1. On essentially every mainstream distribution today, that's systemd.
- systemd brings up targets - units (services, mounts, sockets) start
in dependency order, converging on a target such as
multi-user.target(no GUI) orgraphical.target. See systemd and Services for how units and targets work.
Distro/version notes
- GRUB2 is close to universal on BIOS and UEFI x86 Linux systems, but
some minimal or embedded distros use simpler bootloaders (
syslinux,systemd-boot). systemd-boot is the default on some Arch and Fedora IoT setups.sudo update-grubregenerates GRUB's config on Debian/Ubuntu.sudo grub2-mkconfig -o /boot/grub2/grub.cfgdoes the equivalent on Fedora/RHEL.
- systemd replaced SysV init and Upstart as the default init system across nearly all major distributions by the mid-2010s; a few (Alpine, Gentoo by choice, Devuan) deliberately use alternatives such as OpenRC.
Inspecting the boot on a running system
See how long each stage took:
systemd-analyze
Startup finished in 3.912s (firmware) + 2.230s (loader) + 4.108s (kernel) + 8.541s (userspace) = 18.792s
graphical.target reached after 8.481s in userspace.
See which units took the longest during startup:
systemd-analyze blame | head -5
3.201s NetworkManager-wait-online.service
1.884s snapd.seeded.service
0.912s systemd-udev-settle.service
0.501s docker.service
0.223s accounts-daemon.service
And read boot-time kernel and service logs together with journalctl:
journalctl -b