Back to the map

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.

CoreShould-knowMid 11 min Updated Nov 2026

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.

FirmwareUEFI or BIOSBootloaderGRUB, systemd-bootKernelinit, driversinitramfsmount rootsystemd (PID 1)units and targetsLogingettycontainers start at PID 1
The boot pipeline: the top row runs before the kernel exists.

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

StageSymptomUsual causeWhere to look
FirmwareNo bootable deviceDisk order, missing EFI partitionFirmware setup
Bootloadergrub rescue promptBroken config, wrong UUIDGRUB console, grub.cfg
Kernel and initramfsPanic: unable to mount root fsMissing driver, stale initramfsSerial console, older kernel
systemdEmergency modeFailed fstab mount, dependency loopjournalctl -xb, systemctl --failed
LoginLogin fails or hangsPAM, full disk, NSS timeoutsRescue shell, journalctl, df
The last message you can see names the stage you reached.

Debugging a machine that will not boot

  1. 1

    Get a console

    Attach the serial console (add console=ttyS0 to the kernel line) or a screen.
  2. 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.target means a unit failed.
  3. 3

    Boot the old kernel or edit the command line

    In GRUB pick the older kernel, or press e and add systemd.unit=rescue.target or init=/bin/bash, and drop quiet.
  4. 4

    Inspect, then repair from outside

    blkid in the initramfs shell, journalctl -xb and systemctl --failed in emergency mode; failing that, boot a rescue image, chroot in, fix fstab or grub.cfg, rerun update-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?

From power-on to login · Backplane