Sign in
← Linux: booting
10 min · intro · Lesson 1 of 7

How Linux boots: an overview

An overview of the whole boot chain: from firmware to PID 1.

Why know the boot chain

The server won't boot, and the console shows a black screen or a line about grub rescue. To fix it, you need to understand which step everything stopped at. Linux boot works like a chain of handoffs: each stage brings up the next one and steps aside. The problem always lives on one specific link, and there are only a few links total.

It's also a map of where each setting lives. Disk order gets configured in firmware, the kernel selection menu lives in the bootloader, drivers for the root disk get assembled in initramfs, and service autostart is described by init. Get the layer wrong, and you'll be editing the wrong config.

firmware BIOS or UEFI GRUB loads the kernel kernel memory, drivers initramfs root in memory systemd PID 1 disk order menu and parameters kernel modules root drivers unit files
Each link brings up the next one and steps aside. Below: what gets configured at that layer.

Firmware: checking hardware and finding the bootloader

Firmware is a program in a chip on the motherboard that starts first when the power comes on. It comes in two flavors: the older BIOS and the modern UEFI. Firmware checks memory and devices, then looks for who to hand control to.

BIOS reads the first 512-byte sector of the disk: this is the MBR (master boot record). The first 446 bytes hold the primary bootloader code. The next 64 bytes hold a partition table with four entries, and the last 2 bytes store the 55 AA signature. Without it, BIOS treats the disk as non-bootable. UEFI works differently: it reads a bootloader file from a separate EFI partition.

To check which mode the system booted in:

ls /sys/firmware/efi
config_table  efivars  fw_vendor  runtime  systab  ...

If the directory exists, the system booted through UEFI. No directory means BIOS (or a compatibility mode for it). The exact set of files inside depends on the kernel version.

Bootloader: GRUB loads the kernel into memory

The bootloader is a program that finds the kernel file on disk, loads it into memory and hands it control. On most systems that's GRUB (GRand Unified Bootloader). It also shows a menu when there's more than one kernel to pick from.

GRUB reads its own config, grub.cfg, and uses it to know where the kernel is and what parameters to pass it. The kernel and initramfs files usually live in /boot (example from Debian 12):

ls /boot
config-6.1.0-18-amd64  grub  initrd.img-6.1.0-18-amd64  System.map-6.1.0-18-amd64  vmlinuz-6.1.0-18-amd64

vmlinuz-* is the kernel itself, initrd.img-* is the initramfs image (more on that below), and the grub/ directory holds the bootloader's config.

On UEFI the bootloader is sometimes not needed at all: the kernel is built with an EFI stub, and firmware runs vmlinuz directly as an EFI application.

Kernel and initramfs

The kernel manages memory, processes and access to hardware. Once it's up, the kernel initializes the processor, memory and basic drivers. But it can't mount the root disk yet: the driver for the right controller, or an LVM/RAID module, isn't loaded.

That's where initramfs (initial RAM filesystem) comes in: a temporary root in RAM. The kernel unpacks this cpio archive into rootfs (tmpfs if the kernel has CONFIG_TMPFS enabled, ramfs otherwise) and runs the /init program from it. That program gets PID 1, loads the missing modules, mounts the real root from disk, and switches over to it.

On Debian and Ubuntu you can look inside the initramfs image like this (on Fedora and RHEL, lsinitrd does the same):

lsinitramfs /boot/initrd.img-6.1.0-18-amd64

In the file list you'll find an init script, a scripts/ directory with root-mounting scripts, and kernel modules under lib/modules/ or usr/lib/modules/.

PID 1: init and systemd

After mounting the real root, /init from initramfs doesn't exit; it replaces itself (via exec) with the real init from disk. That's why PID 1 stays the first userspace process, with every other process branching out from it. On most distributions, systemd plays the role of init.

systemd is a daemon that manages other daemons. It gets what to start, and in what order, from declarative unit files rather than a sequential script. That makes startup heavily parallel: independent services start at the same time.

Targets describe the state the system should reach. The graphical login depends on multi-user mode, which depends on the basic target, which depends on the initial sysinit: graphical -> multi-user -> basic -> sysinit. Dependencies are honored, but there's no strict queue of "finish one entirely, then start the next."

systemctl get-default
graphical.target

On servers without a GUI you'll more often see multi-user.target. To see how long boot took, run systemd-analyze (example from the systemd docs):

systemd-analyze
Startup finished in 2.584s (kernel) + 19.176s (initrd) + 47.847s (userspace) = 1min 9.608s
multi-user.target reached after 47.820s in userspace

Time breaks down by link: kernel, initramfs (initrd) and userspace, meaning systemd's own work. On UEFI machines the line can also start with (firmware) and (loader).

Common mistakes

"BIOS starts the operating system on its own." Firmware doesn't know what Linux or Windows are and doesn't start them. Its job is more modest: check the hardware and hand control to bootloader code from the MBR or an EFI partition. Everything after that is done by the bootloader, the kernel and init.

That's why the failure points differ too. If firmware couldn't find a bootloader, blame the boot order, an empty MBR, or a missing EFI entry. If GRUB started but the kernel didn't come up, check the kernel parameters and initramfs.

Checking the boot mode inside a container. Docker hides /sys/firmware from the container by default, so ls /sys/firmware/efi there answers No such file or directory even on a machine with UEFI. Check it on the host itself.

Mixing up initramfs messages with kernel messages. The (initramfs) prompt means the kernel and initramfs are already running, and the root disk wasn't found. Kernel panic with the words Unable to mount root fs is printed by the kernel itself, when it couldn't mount the root and has no one to hand control to.

What to remember

There's one chain: firmware -> bootloader -> kernel -> initramfs -> init (PID 1).

Firmware (BIOS or UEFI) only checks the hardware and hands control to the bootloader; it doesn't start the OS itself.

GRUB loads the kernel into memory; on UEFI, a kernel with an EFI stub can start without a bootloader.

initramfs is a temporary root in RAM, there to load drivers and mount the real root disk.

PID 1 is init, usually systemd; it brings up services from unit files in parallel, guided by targets.

In the next lessons of the track we'll go through each link separately, step by step.

What you'll need for the tasks

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 1 lab for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson linux-boot-01-boot-overview