From power button to shell
Why this matters
Section titled “Why this matters”A few seconds pass between pressing the power button and the login prompt, and in that time control passes through four owners in turn. As long as everything works, you will never need to know this chain.
The need comes when something breaks. The system won’t boot after a kernel
update. You get emergency mode instead of a desktop. A service starts fine
by hand but not at boot. Each of these maps to a specific link in the chain,
so half of the diagnosis is figuring out which link the system reached at all.
Prerequisites. Execution modes (module 2), PID 1 and the process tree (module 6).
The chain
Section titled “The chain”It all starts with the firmware. The CPU fetches its first instruction from a fixed address, and that is where the firmware sits. It checks and initializes memory, buses and controllers, then looks for what to boot next.
Modern firmware is UEFI. It understands the FAT32 file system and reads the
bootloader as an ordinary file from a separate partition called the ESP
(EFI System Partition). The list of boot entries lives in the motherboard’s
non-volatile memory, and you can edit it from the running system
with efibootmgr.
The old BIOS + MBR scheme works completely differently: the BIOS reads the first 512 bytes of the disk and executes them. Those 512 bytes also hold the partition table, which leaves so little room for code that the bootloader had to be split into stages. The limits of MBR come from the same place: four primary partitions and 2 TiB, both of which GPT removes.
The bootloader, GRUB or systemd-boot, shows a menu, finds the kernel image and the initramfs, and passes the kernel its command-line parameters. That command line decides what the kernel does next: where to look for the root, whether to turn on debug output, which drivers to disable.
The kernel decompresses itself, initializes its subsystems, discovers the CPUs and memory, starts drivers and mounts the initramfs.
The last thing the kernel does is start the first user-mode process, PID 1. It is special in several ways at once: an ordinary signal can’t kill it, it adopts every orphan process (module 6), and if it exits, the kernel halts the system.
systemd
Section titled “systemd”The classic init ran scripts one after another by number. Simple,
but slow: every service waited for the previous one, even when the two
had nothing to do with each other.
systemd instead describes the system as a dependency graph and starts
in parallel everything that can run in parallel.
The thing it manages is called a unit. There are several types: .service
for a process, .socket for a socket that starts a service when someone
connects to it, .timer in place of cron, .mount for a mount point
and .target for a group of units.
Think of a target not as a runlevel but as a point in the graph.
multi-user.target means the system is ready to work at the console,
and graphical.target adds a graphical environment on top.
Socket activation deserves its own mention. systemd opens the socket right away and starts the service only on the first connection. The client sees no difference, because the connection is accepted and waits, but boot is no longer held up by services nobody uses.
How it actually works in Linux
Section titled “How it actually works in Linux”[ -d /sys/firmware/efi ] && echo 'UEFI' || echo 'BIOS (legacy)'Whether the system booted through UEFI. The directory exists only in UEFI mode.
efibootmgr -v 2>/dev/null | head; lsblk -o NAME,PARTTYPENAME,MOUNTPOINT | headThe boot entries in the motherboard’s memory and the ESP partition,
usually mounted at /boot/efi.
cat /proc/cmdlineThe parameters the running kernel was booted with, that is, what the bootloader passed. This shows where the root came from and which options apply.
lsinitramfs /boot/initrd.img 2>/dev/null | head -20 || lsinitrd 2>/dev/null | head -20The contents of the initramfs: the set of modules needed to reach the root.
This deliberately uses /boot/initrd.img, a symbolic link to the image of the
default kernel. If you use /boot/initrd.img-$(uname -r), the command fails
exactly when things get interesting: after a kernel update, when the new image
already exists but the system is still running the old kernel, which may have
no image. It’s worth comparing both.
systemd-analyze; systemd-analyze blame | head -10How long boot took, broken down into firmware, bootloader, kernel and user space, and which units took the most time.
systemd-analyze critical-chainThe critical chain: the sequence that actually determined boot time. Only what is in it is worth optimizing.
systemctl list-units --type=target --state=activesystemctl get-defaultActive targets and the default target.
journalctl -b -p err --no-pager | tail -10Errors from the current boot. -b -1 shows the previous one,
which is invaluable when the system crashed and managed to reboot.
Common misconceptions
Section titled “Common misconceptions”“BIOS and UEFI are the same thing, just a new name.” They are different
schemes. The BIOS executes the first 512 bytes of the disk, while UEFI reads
an .efi file from a FAT32 partition and keeps its list of entries in the
motherboard’s memory.
“initramfs is there for speed.” It is there to break a circle: mounting the root needs drivers that live on the root itself.
“systemd is just init.” It is a service manager with a dependency graph, socket activation, timers, mount points and a journal. The sheer amount it took on is exactly why it is controversial.
“A target is a runlevel.” Targets aren’t ordered by number and don’t exclude each other. They are just synchronization points in the graph.
“The service works by hand, so the unit is correct.” The unit has a
different environment: none of your variables, a different working directory,
stdout going to journald. The mismatch is usually there.
“The system won’t boot, I’ll reinstall.” First look at
journalctl -b -1 -p err and the parameters in /proc/cmdline. Two things
are to blame most often: an initramfs not rebuilt after a kernel update
and a wrong root UUID in /etc/fstab.
Check yourself
B1: installing the system. GPT partitioning, an ESP partition, booting
through UEFI and your own .service unit with dependencies. The mandatory part
is to break the boot on purpose and fix it from emergency mode.
Sources
Section titled “Sources”- Nemeth et al., UNIX and Linux System Administration Handbook, chapter 2
man 7 boot,man 1 systemd,man 5 systemd.unit,man 5 systemd.service- systemd for Administrators: a series by the author
- UEFI Specification: if you need the format details