Skip to content

The Linux Boot Process

The boot process is the sequence of events that takes a powered-off machine to a fully running Linux system. Each stage hands control to the next.

Boot process overview

StageComponentResponsibility
1Firmware (BIOS/UEFI)POST hardware check; locate and launch bootloader
2Bootloader (GRUB)Load kernel + initramfs into RAM
3KernelInitialize hardware; mount root filesystem
4initramfsTemporary root; discover real root filesystem
5init / systemdStart all services; bring up multi-user environment

When the computer is powered on, the firmware chip on the motherboard runs first:

  • BIOS (Basic Input Output System): Stored on a ROM chip. Runs POST (Power-On Self Test) to verify RAM, keyboard, and attached devices are functional.
  • CMOS: A battery-backed chip that stores the system clock and basic hardware settings (date, time, boot device order).

After POST passes, the firmware locates a bootable device and hands control to the bootloader.

FeatureLegacy BIOS/MBRModern UEFI/GPT
Boot code locationFirst 512 bytes of disk (MBR)EFI System Partition (FAT32, ~100-512 MB)
Partition limit4 primary partitions max128 partitions (GPT)
Disk size limit2 TB9.4 ZB
SecurityNo Secure BootSecure Boot (verifies kernel signature)
Boot speedSlowerFaster (parallel init possible)
StandardDecades old; widely compatibleModern standard since ~2010

Bootloader diagram

The bootloader is a small program whose sole job is to get the kernel into RAM. Linux uses several bootloaders:

BootloaderUse Case
GRUB 2Default for most desktop/server Linux distributions
ISOLINUXBooting from removable media (USB, DVD)
DAS U-BootEmbedded systems and appliances
systemd-bootLightweight UEFI-only alternative

GRUB can present a menu for choosing between different kernels or even different operating systems (dual boot).

MBR boot diagram

Stage 1 (tiny stub - fits in the MBR or EFI partition):

  • BIOS/MBR systems: Only 446 bytes available in the MBR for code. GRUB’s stage 1 just locates and loads the larger stage 2 from the boot partition.
  • UEFI systems: Firmware reads the EFI partition directly and loads grubx64.efi from there. More sophisticated than MBR; no 446-byte constraint.

Stage 2 (full GRUB, lives under /boot):

  • Reads /boot/grub2/grub.cfg (or /boot/grub/grub.cfg)
  • Displays the OS selection menu
  • Loads the selected kernel image (vmlinuz-...) and initial RAM disk (initramfs-...) into memory
  • Passes control to the kernel

GRUB configuration:

Terminal window
cat /boot/grub2/grub.cfg # auto-generated; never edit directly
# Edit this instead, then regenerate:
sudo vim /etc/default/grub # kernel args, timeout, default entry
sudo grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/Fedora
sudo update-grub # Debian/Ubuntu

Once GRUB loads the compressed kernel (vmlinuz) into RAM, the kernel:

  1. Decompresses itself into memory
  2. Detects hardware: Scans and configures CPUs, memory controllers, I/O subsystems, and storage controllers
  3. Initializes device drivers built directly into the kernel (.ko modules come later)
  4. Mounts initramfs as a temporary root filesystem in RAM
  5. Starts udev (from within initramfs) to detect and load remaining device drivers

initramfs diagram

The initramfs (initial RAM-based filesystem) is a tiny temporary root filesystem embedded in a compressed cpio archive. It exists to solve a chicken-and-egg problem:

The kernel needs filesystem driver and storage controller modules to mount the real root filesystem - but those modules are on the real root filesystem.

The initramfs ships with enough tools and drivers to:

  • Load any kernel modules needed to access the root partition (LVM, LUKS encryption, RAID, exotic filesystems, etc.)
  • Run udev to discover and initialize block devices
  • Mount the real root filesystem
  • Execute /sbin/init (or systemd) from the real filesystem

Once the real root is mounted, the initramfs is cleared from RAM and control transfers to PID 1 on the real filesystem.


Kernel, init, and services

The last stage: PID 1 takes over and starts everything else.

SystemEraApproach
SysVinit1980s - 2010sSequential runlevels; shell scripts run in order
UpstartUbuntu 2006, RHEL 6Event-driven; some parallelism
systemdFedora 2011; now universalAggressive parallelization; dependency graph; socket activation

Today, /sbin/init on virtually every major distro is a symlink to /lib/systemd/systemd. systemd makes boot faster by:

  • Starting services in parallel (determined by a dependency graph, not a serial queue)
  • Using socket activation (open the socket immediately; start the service lazily when something connects)
  • Using D-Bus activation (start services on-demand)
SysV Runlevelsystemd TargetMeaning
0poweroff.targetHalt/shutdown
1rescue.targetSingle-user recovery mode
3multi-user.targetFull multi-user, text/CLI only
5graphical.targetFull multi-user with GUI
6reboot.targetReboot
Terminal window
systemctl get-default # show current default target
sudo systemctl set-default multi-user.target # boot to text mode (no GUI)
sudo systemctl isolate rescue.target # switch to rescue mode NOW

Text mode login

Near the end of the boot process, getty processes start on virtual terminals (VTs) and present login prompts. By default, 6 text VTs are available:

Key combinationEffect
Ctrl-Alt-F1 through F6Switch to text terminal 1-6
Ctrl-Alt-F7 (or F1 on some distros)Switch back to graphical session
Alt-F2 through F6Switch VTs from within a text session