Module 02 · OS fundamentals · Lesson 4 of 4
From power-on to login
What happens when a machine starts: UEFI and Secure Boot, the bootloader, kernel init and initramfs, systemd as PID 1 and its target graph, networking and login, how VMs and containers skip stages, and what each stage's failure looks like.
Why it matters
A server that does not come back after a kernel upgrade, a cloud VM stuck at "booting", a laptop that says "No bootable device": each stops at a different stage of the same sequence, and each stage leaves a different fingerprint. Knowing the sequence turns "it will not boot" into "it reached the initramfs and could not find root", and it is the classic infrastructure interview question.
The idea
Booting is a chain of ever-larger programs, each loading, verifying and starting the next. Power on, and the CPU executes from a fixed address in a flash chip; a minute later an API server is running.
Firmware
The firmware is code in flash on the motherboard. Legacy BIOS read the first 512-byte sector of the disk and jumped into it. UEFI, standard since about 2012, reads GPT partition tables and loads a .efi executable from the EFI system partition, such as /boot/efi/EFI/ubuntu/shimx64.efi. Secure Boot adds signature checking: the firmware holds Microsoft's and the vendor's keys, refuses an unsigned loader, and each stage verifies the next, shim to GRUB to kernel to modules.
Bootloader, kernel and initramfs
The bootloader finds the kernel and starts it with a command line. GRUB reads ext4, LVM and encrypted volumes and offers a menu of kernels, which lets you pick an older kernel after a bad upgrade; systemd-boot loads the kernel from the EFI partition directly. Either passes arguments such as root=UUID=... and console=ttyS0, the first things to inspect when a boot fails. The kernel decompresses itself, sets up page tables, probes CPUs, timers and built-in drivers, then faces a circular problem: root lives on a device whose driver, LVM layout or encryption key may not be built in. The initramfs solves it: a small archive loaded beside the kernel with just enough user space (udev, cryptsetup, modules) to find the real root, mount it and switch_root into it.
PID 1 and the dependency graph
The kernel then starts one program, /sbin/init, as PID 1: default signals cannot kill it, it reaps orphans, and if it exits the kernel panics. Today that is systemd. Instead of running scripts, it reads units (.service, .mount, .socket, .timer, .target), each declaring what it needs (Requires=, Wants=) and in which order (After=), and walks the dependency graph in parallel towards a target: multi-user.target for servers, graphical.target for desktops, rescue.target and emergency.target as fallbacks. Networking is one branch: systemd-networkd or NetworkManager bring up interfaces, and units ordered After=network-online.target wait for an address. Then daemons such as sshd start, each with a restart policy and logs in journalctl -u. Last, getty@tty1 prints login: on a console (serial-getty@ttyS0 on a cloud VM) or a display manager draws the graphical login, and PAM checks the password and starts a session.
How VMs and containers shorten the chain
A cloud VM has no self-test and uses firmware the hypervisor supplies; Firecracker skips firmware and bootloader entirely and boots a microVM in about 125 milliseconds, then cloud-init injects keys as a unit. A container skips everything up to and including the kernel: it is a process on the host, started as PID 1 of a new PID namespace, which is why it starts in milliseconds and why its entrypoint inherits PID 1's duties (see the Process lifecycle and signals lesson).
What failure looks like at each stage
| Stage | Symptom | Usual cause | Where to look |
|---|---|---|---|
| Firmware | No bootable device | Disk order, missing EFI partition | Firmware setup |
| Bootloader | grub rescue prompt | Broken config, wrong UUID | GRUB console, grub.cfg |
| Kernel and initramfs | Panic: unable to mount root fs | Missing driver, stale initramfs | Serial console, older kernel |
| systemd | Emergency mode | Failed fstab mount, dependency loop | journalctl -xb, systemctl --failed |
| Login | Login fails or hangs | PAM, full disk, NSS timeouts | Rescue shell, journalctl, df |
Debugging a machine that will not boot
- 1
Get a console
Attach the serial console (addconsole=ttyS0to the kernel line) or a screen. - 2
Place the last message
A firmware menu means no loader; a GRUB prompt means no kernel; a panic means the kernel ran; an(initramfs)prompt means no root;emergency.targetmeans a unit failed. - 3
Boot the old kernel or edit the command line
In GRUB pick the older kernel, or presseand addsystemd.unit=rescue.targetorinit=/bin/bash, and dropquiet. - 4
Inspect, then repair from outside
blkidin the initramfs shell,journalctl -xbandsystemctl --failedin emergency mode; failing that, boot a rescue image,chrootin, fixfstaborgrub.cfg, rerunupdate-initramfs -u.
Trade-offs
Each stage makes the next possible and adds a place to fail. Secure Boot blocks tampered loaders and also your own unsigned module. The initramfs lets one kernel image mount any disk layout, and a stale one leaves the machine unbootable. systemd's parallel graph starts a server in seconds and lets ordering bugs appear only on the slower machine. Containers remove whole stages, which is why they start fast and why they inherit the host's kernel bugs.
In an interview
Walk the pipeline in order, then place a failure on it. "Firmware loads the bootloader, the bootloader loads the kernel and initramfs, the initramfs mounts the real root, the kernel starts systemd as PID 1, and systemd walks its unit graph to the target that includes networking and getty." Then: "VFS: unable to mount root fs means the kernel ran but could not find root, so I check root= and the initramfs."
Check yourself
After adding a volume and editing /etc/fstab, a server reboots into emergency mode: root is mounted, and journalctl shows the new volume's mount job timed out. Likely cause and fix?