How a Linux Laptop Boots: From Power Button to Login Prompt
Introduction: The Hidden Complexity of Startup
You press the power button. A few seconds later, your laptop displays a login prompt. Firmware runs, bootloaders execute, the kernel loads, initialization systems start services, filesystems mount, daemons launch. Dozens of pieces of software (some old, some new, some you've never heard of) coordinate to bring your system to life.
This article traces the complete journey from power button to login.
Part One: The Boot Sequence Overview
Let's examine each stage.
Part Two: Stage 1 - Firmware (BIOS/UEFI)
What Firmware Does
Power-On Self Test (POST)
• Memory test
• CPU verification
• Disk detection
• PCI/USB device initialization
BIOS vs. UEFI
BIOS (1980s-2010s): The original firmware standard. 16-bit real mode execution. Limited to 1MB of addressable memory. Can load bootloader from first sector of disk (512 bytes). Simple but restrictive.
UEFI (2000s-present): Modern replacement. 32/64-bit execution. Larger boot partition. Can run EFI applications directly. More flexible and powerful. Has largely replaced BIOS on modern systems. UEFI also supports Secure Boot, a feature that verifies the digital signatures of bootloaders and kernels before executing them. Secure Boot prevents rootkits and bootkits from inserting malicious code early in the boot process by only allowing signed, trusted software to run.
Finding and Loading the Bootloader
After POST, firmware searches for bootable devices in order (configurable in BIOS/UEFI settings). On a BIOS system, it looks for the MBR (Master Boot Record), the first 512 bytes of the disk.
Complexity and History
Complexity: Firmware initialization is straightforward (run POST, find bootloader, load it) but hardware-specific. Different manufacturers implement BIOS/UEFI differently. Bugs in firmware are notoriously hard to fix (requires flashing ROM).
History: BIOS originated in 1981 with the IBM PC. It remained largely unchanged for decades despite technological progress. UEFI was developed starting in 1998 by Intel and became standard by the 2010s. Modern systems use UEFI almost exclusively.
Who wrote it: Firmware is written by manufacturers (Dell, Lenovo, HP, etc.), often based on reference implementations from chipset makers (Intel, AMD). Some open-source efforts exist (Coreboot, OVMF) but closed-source firmware remains dominant.
Part Three: Stage 2 - Bootloader (GRUB)
What the Bootloader Does
The bootloader's job: locate the kernel file, load it into memory, and transfer control to it. On modern systems using GRUB (GRand Unified Bootloader), the bootloader also displays the boot menu and can pass parameters to the kernel.
GRUB's Two-Stage Process
Stage 2 (core.img + modules): Larger code with filesystem drivers. Can locate and load kernel.
The Boot Menu
GRUB displays a menu (often with timeout). You can select which kernel to boot or edit boot parameters. This is the point where you'd boot into recovery mode or select a different OS if multi-booting.
GRUB Complexity
Complexity: GRUB is substantial (~10,000 lines of code). It needs to understand multiple filesystems (ext4, btrfs, XFS, NTFS, etc.) and boot protocols (BIOS, UEFI). Configuration lives in grub.cfg, which on most distributions is auto-generated by running update-grub (or grub-mkconfig). Users rarely write grub.cfg by hand; instead, they edit defaults in /etc/default/grub and scripts in /etc/grub.d/.
History: GRUB was created in the 1990s by Gordon Matzigkeit. GRUB 2 (released 2005) is the modern version, supporting UEFI and contemporary filesystems. It replaced LILO (LInux LOader) which was simpler but less flexible.
Alternatives: systemd-boot (simpler, UEFI-only), rEFInd (works with multiple OSes), SYSLINUX (for simpler use cases).
Loading the Kernel
GRUB loads the kernel (a file like `vmlinuz-5.15.0`) and the initramfs (initial ramdisk, an uncompressed cpio archive or compressed initrd) into memory. It then jumps to the kernel entry point, passing control to Linux.
Part Four: Stage 3 - Kernel Initialization
Kernel Startup Sequence
The kernel begins in assembly code (very low-level). It:
The Initramfs: Early Userspace
The initramfs (initial ramdisk) is a temporary filesystem containing essential tools. Its init script:
- Loads kernel modules needed to access the real root filesystem
- Detects hardware (especially disks and encryption hardware)
- Decrypts encrypted root filesystem if needed
- Mounts the real root filesystem
- Executes the real init system (systemd, init, etc.)
Kernel Complexity
Complexity: The Linux kernel is ~20-30 million lines of code. Boot code is relatively small (~100,000 lines) but critical. Any failure here causes complete boot failure with no recovery.
History: Linux kernel created by Linus Torvalds in 1991. Boot code has evolved from simple 16-bit real-mode code to sophisticated 64-bit initialization. Modern kernels support dozens of architectures (x86, ARM, RISC-V, PowerPC, etc.).
Who wrote it: Linux kernel is maintained by Linus Torvalds with thousands of contributors. Boot code is written by architecture maintainers (x86 maintainers: Thomas Gleixner, Ingo Molnar, etc.).
Part Five: Stage 4 - Init System and Userspace
PID 1: The Init System
Once the kernel has booted and mounted the real root filesystem, it executes the init system (PID 1, the first user process). Modern Linux uses systemd almost exclusively.
Systemd: The Modern Init
• Reads unit files (services, timers, mounts, etc.)
• Starts essential services in dependency order
• Manages logging (journald)
• Handles shutdown and reboot
Unit Files: Declarative Configuration
Systemd reads unit files and starts services in parallel respecting dependencies. Services can depend on each other ("After="), and systemd ensures correct ordering.
Boot Targets vs. Runlevels
Systemd uses "targets" instead of runlevels:
| Target | Purpose | Old Runlevel |
|---|---|---|
| graphical.target | Multi-user with GUI (login manager) | 5 |
| multi-user.target | Multi-user text mode (no GUI) | 3 |
| rescue.target | Single-user rescue mode | 1 or S |
| emergency.target | Minimal shell, read-only filesystem | 0 (halt) |
Essential Services That Start
During boot, systemd starts:
- Filesystems: Mount /dev, /sys, /proc, /run. Check and repair root filesystem.
- Networking: Bring up network interfaces. Start DNS resolver (systemd-resolved).
- Logging: journald starts, ready to accept log messages.
- Timekeeping: Set system clock (systemd-timesyncd or NTP).
- Device management: udev detects hardware and creates device files.
- Display manager: On graphical systems, GDM, LightDM, or SDDM starts, displaying login screen.
Init Systems: Historical Context
SysVinit (1980s-2010s): Original Unix init. Simple shell scripts in /etc/init.d/. Started services sequentially. Slow but transparent.
Upstart (2006-2014): Event-based init. Used by Ubuntu. Faster than SysVinit but less flexible than systemd.
Systemd (2010-present): Modern init system. Parallel starting, declarative units, integrated logging. Controversial due to scope creep but undeniably efficient and feature-rich.
Alternatives (still used): OpenRC, runit, dinit. These are simpler and suit embedded systems or minimalist setups.
Who wrote systemd: Created by Lennart Poettering and Kay Sievers. Now maintained by freedesktop.org. Controversial but highly influential.
Systemd Complexity
Complexity: Systemd is large (~500,000 lines of code). It does much more than just start services: device management (systemd-udevd), networking (systemd-networkd), container support, tmpfiles management, user sessions. Critics argue it's too complex and violates Unix philosophy. Defenders argue modern systems need these features.
Part Six: Display Manager and Login
Display Manager
On graphical systems, a display manager (SDDM, GDM, LightDM, XDM) is started. Its job: manage the display server and user login.
When you enter credentials and click login:
- Display manager authenticates against /etc/passwd and /etc/shadow
- If successful, forks a session
- Executes your shell or desktop environment (GNOME, KDE, Xfce, etc.)
Part Seven: Total Time and Optimization
Modern Boot Times
On modern SSDs, a typical Linux laptop boots in 5-15 seconds:
Optimizations
Fast storage: NVMe SSD is 10x faster than SATA SSD. Most boot time is I/O.
Parallel startup: Systemd starts services in parallel. SysVinit started sequentially.
Minimal services: Disable unnecessary services. Server systems need fewer services than desktops.
Compress kernel/initramfs: Gzip or xz compression reduces size, though decompression takes time (usually worth it).
systemd-analyze: Tool to profile boot time and find bottlenecks.
Part Eight: Boot Failure Recovery
Where Boots Fail
- Firmware: Usually means hardware failure. Can't do much without reflashing.
- GRUB: "GRUB>" prompt. Usually means grub.cfg is missing. Boot from USB and reinstall GRUB.
- Kernel: Kernel panic (unreadable error message). Usually kernel module missing or hardware failure.
- Initramfs: "emergency mode" or "initramfs prompt". Usually root device not found or encrypted volume can't unlock. Check crypttab and fstab.
- Systemd: "systemd[1]: Starting..." then hangs. Usually service dependency problem or timeout.
Recovery Tools
Modern systems have fallback mechanisms:
- emergency.target: Read-only root shell with minimal services.
- rescue.target: Single-user mode with filesystem check.
- systemd.unit=rescue.target on kernel command line: Boot into rescue mode instead of default target.
- USB recovery media: Boot from USB to repair system.
Conclusion
Understanding boot reveals layers of abstraction: firmware (hardware interface), bootloader (firmware interface), kernel (hardware abstraction), init system (kernel interface), and applications (system interface). Each layer does its job and passes control to the next.
This layered approach is what makes Linux portable to countless devices: you can replace firmware, bootloader, or init system without rewriting the kernel. It's modularity in action.
"The boot process is where abstraction meets reality. Below the kernel is electronics and physics. Above the kernel is software. The kernel is the translator, the thing that makes a generic OS able to run on any hardware."