Target audience: Absolute beginners – no prior Linux knowledge required.
Goal: Walk you through every step that happens from the moment you press the power button until the Ubuntu login screen appears, explaining the role of BIOS/UEFI, CMOS, hardware tests, the bootloader, the kernel, systemd, and device detection.
Table of Contents
- Introduction – Why Understanding the Boot Process Matters
- Stage 0 – The Power Button, PSU, CMOS & Firmware
- Stage 1 – POST (Power-On Self Test) and Memory Checks
- Stage 2 – BIOS/UEFI Initialization & Boot Device Selection
- Stage 3 – Firmware to Bootloader Handoff (UEFI → GRUB)
- Stage 4 – The GRUB Bootloader
- Stage 5 – Loading the Linux Kernel & initramfs
- Stage 6 – Early Userspace and Device Discovery
- Stage 7 – systemd Takes Over (PID 1)
- Stage 8 – Target Units and Services Until Graphical Login
- Stage 9 – Login Managers & Desktop Session
- Diagnostics, Logs & Commands to Inspect Boot
- Best Practices for Troubleshooting Slow Boots
- References (a.k.a. “The Treasure Map for Those Who Actually Read the Manual”)
Introduction – Why Understanding the Boot Process Matters
Let’s Be Honest
Of course, I fully realize that in this manual I’m descending to a level of detail so low it’s practically invisible to the modern attention span. But, you know, someone has to talk about it — apparently basic understanding of how a system actually works is now an endangered species.
Then you get people who have no clue what a bus even is, how power flows through a computer, and still ask me, “Will my PC turn on and show a screen if I haven’t even put the CPU in yet?” Or my personal favorite: “Why does my computer magically turn on after a power outage?”
This chapter exists so that, by the time you’ve read the rest of the manual, you’ll never ask those questions — you’ll be the one smirking quietly when somebody else does.
What We Mean by “Boot Process”
In normal human language:
- You press a button.
- Electricity flows.
- Circuits, firmware, bootloaders, kernels, services and finally the desktop all start playing their part.
To an engineer, that’s five or six distinct stages with different software and hardware players:
- Firmware (UEFI or BIOS)
- POST and hardware enumeration
- Bootloader (GRUB)
- Kernel and initramfs
- systemd targets
- Display manager
Understanding the boundaries between these stages is like knowing the difference between the engine, transmission, and wheels in a car. Sure, the car “just goes” — but if it stops going, you’ll want to know which part broke.
Why Bother?
- Troubleshooting:
Without this knowledge, you’re stuck staring at a frozen splash screen. With it, you know how to drop to a GRUB shell, inspect kernel messages, or boot to single-user mode. - Performance Tuning:
Slow boots? You’ll know whether to rebuild initramfs, disable a slow service, or tweak systemd targets. - Security:
Understanding firmware and bootloader stages is the first step to enabling Secure Boot properly or protecting against boot-kits. - Confidence:
Once you know the flow, you can add disks, swap GPUs, or install new kernels without the nervous “will it even boot” feeling.
Common Myths We’ll Bust
| Myth | Reality |
|---|---|
| “If it’s plugged in, it must turn on.” | The power button just signals a controller; nothing boots until firmware runs POST. |
| “Linux boots as one monolithic thing.” | It’s a hand-off between firmware, bootloader, kernel, initramfs, and init (systemd). |
| “systemd is the bootloader.” | No. systemd is PID 1 — it starts after the kernel and initramfs finish their part. |
How This Manual Helps
This whole series takes you, step by step, through:
- What the firmware does before Linux is even in memory.
- How the bootloader chooses a kernel and passes parameters.
- How systemd brings up devices, networking and finally your login screen.
By the end you’ll be able to:
- Reconfigure GRUB safely:
sudo vim /etc/default/grub
sudo update-grub
- Check which services slow down boot:
systemd-analyze blame
*Read boot logs like a pro:
journalctl -b
The Big Picture – What “Booting” Means
Power button → Power supply → Firmware (BIOS/UEFI) → Bootloader (GRUB)
→ Linux kernel + initramfs → systemd → Services → Login screen
Think of a boot as a relay race. Each “runner” (firmware, bootloader, kernel, init system) hands off control to the next one after it has finished its job.
- Firmware: the very first code stored on the motherboard; it knows how to talk to the CPU, memory, and basic devices.
- Bootloader: a tiny program that selects the OS kernel and hands it over.
- Kernel: the core of Linux; it starts managing hardware and provides the foundation for everything else.
- initramfs: a temporary filesystem that prepares the real root filesystem.
- systemd: the modern init system that starts all the background services (network, graphics, printers, …).
- Display manager (e.g., GDM, LightDM): draws the graphical login screen.
Final Word
Think of this chapter as the map at the entrance to a theme park. We haven’t gone on any rides yet — but you can already see where the rollercoaster drops, where the snack stands are, and where the exit is in case of panic.
Once you understand why the boot process matters, the next chapters will show you what actually happens at each stage and how to tweak it. After that, when someone asks “Why doesn’t my PC magically turn on after a power outage?” you can smile and, very politely, explain why.
Stage 0 – The Power Button, PSU, CMOS & Firmware
Welcome to Stage 0: the moment before Linux even knows it exists. This is the world of electrons, capacitors and little firmware gremlins working inside your motherboard.
0.1 The Power Button – The “Doorbell” of Your PC
Despite its name, the power button does not “inject” power into your system. It’s a momentary switch sending a low-voltage signal to the motherboard’s Embedded Controller (EC) or Power Management IC.
- In ATX-style systems, the PSU always supplies a 5 V “standby” rail (5VSB) to the motherboard even when “off.”
- Pressing the button pulls the PS_ON# line low, telling the PSU to turn on the main rails (3.3 V, 5 V, 12 V).
Example check from Linux (after boot):
cat /sys/class/power_supply/*/online
Shows whether AC or battery power is present.
Common myth: “If the power button is broken, my PC won’t work.”
Truth: you can start most motherboards by shorting the two “PWR_SW” pins with a screwdriver — the button is just a doorbell.
0.2 The PSU – More Than a Fancy Box with a Fan
Your Power Supply Unit (PSU) converts wall AC (110/230 V) to multiple DC rails.
It also:
- Provides over-current/over-voltage protection
- Sends a “Power Good” signal to the motherboard only after voltages are stable
- Keeps 5VSB alive for wake-on-LAN, USB charging, etc.
You can check PSU health indirectly from Linux sensors:
sudo apt install lm-sensors
sudo sensors
Typical output:
Vcore: 1.10 V
+3.3V: 3.31 V
+5V: 5.02 V
+12V: 12.10 V
If you see +12 V reading as 8 V, your PSU isn’t meditating — it’s dying. Same with your Battery.
0.3 CMOS & RTC – The Tiny Battery Nobody Thinks About
The CMOS chip holds BIOS/UEFI settings and the RTC (real-time clock). A small coin-cell battery (CR2032) keeps it alive when the PC is unplugged from any power source.
Why it matters:
- Wrong date/time can break SSL certificates and apt updates.
- Reset BIOS settings to defaults when the battery dies.
Check the hardware clock from Ubuntu:
sudo hwclock --show
Example:
2025-10-05 13:47:00.123456+03:00
Sync RTC to system time:
sudo hwclock --systohc
or use timedatectl in modern Linux:
timedatectl show0.4 Firmware: BIOS vs UEFI – The Invisible Ringleader
Your motherboard stores firmware in a flash chip. Legacy BIOS used 16-bit real mode; modern UEFI is a full 32/64-bit environment with drivers, a shell, and NVRAM variables.
It:
- Initializes CPU, RAM, and buses
- Scans for boot devices
- Runs Power-On Self-Test (POST) and only then jumps to the bootloader.
From Ubuntu you can see some firmware variables:
sudo efibootmgr -v
Example output:
BootCurrent: 0000
BootOrder: 0000,0001
Boot0000* ubuntu HD(1,GPT,...)/File(\EFI\ubuntu\grubx64.efi)
Boot0001* UEFI: USB Drive
Update UEFI firmware the Ubuntu way:
sudo fwupdmgr get-devices
sudo fwupdmgr get-updates
sudo fwupdmgr update
0.5 The “Power Good” Sequence
All these pieces coordinate like a relay race:
- PSU sends 5VSB to the board.
- You press the button → EC signals PSU to turn on main rails.
- PSU stabilizes voltages → asserts “Power Good.”
- Firmware starts executing from flash at the CPU’s reset vector.
- POST runs, memory trained, devices enumerated.
- Firmware finds and executes the bootloader.
You can visualize this sequence with systemd-analyze plot (later stages) but at Stage 0 it’s mostly invisible — unless you hook up an oscilloscope.
0.6 Common Stage 0 Problems
| Symptom | Likely Cause | Quick Check |
|---|---|---|
| No lights, no fan | Dead PSU or not plugged in | Try paperclip test on PSU, or measure 5VSB |
| Loses BIOS settings | CMOS battery dead | Replace CR2032, check with hwclock |
| Won’t power on after outage | PSU latched into protection mode | Flip switch off, unplug 30 s, then retry |
| Random boot order | NVRAM corruption | Reset BIOS/UEFI, update firmware |
0.7 For the Curious: Forcing Power & Testing Outside the Case
- Short “PWR_SW” pins to start board manually.
- Short “RESET” pins to force a reset.
- Many boards have an onboard “Power” button — it’s not just decoration.
Key Takeaways
- The power button is just a signal, not a magic energy injector.
- The PSU’s 5 V standby rail keeps firmware features alive even when “off.”
- CMOS/RTC battery stores settings and time — a cheap part that causes weird issues when dead.
- Firmware (BIOS/UEFI) orchestrates POST and boot before Linux is even loaded.
Stage 1 – POST (Power-On Self-Test) and Memory Checks
We’ve left the “electron plumbing” stage and finally reached the point where the machine begins to speak. This is where the firmware starts checking if the CPU, RAM and peripherals are actually there — and no, it still won’t boot without a CPU, sorry.
This is the part most users vaguely recognise as “the BIOS screen” or “those beeps before Windows.” It’s the firmware running a miniature diagnostic routine called POST before handing control to any operating system.
1.1 CMOS – Your Motherboard’s Tiny Brain
A small piece of CMOS RAM (about 64 KB) stores your:
- Boot order
- Secure Boot keys
- SATA/AHCI mode
- Virtualization enable/disable flags
- Fan curves, wake-on-LAN settings, etc.
It’s powered by the little CR2032 coin cell so settings survive power loss. If this battery dies:
- Your clock resets to 2001
- Secure Boot keys vanish
- Boot order returns to defaults
How to Check from Ubuntu:
List current hardware clock time:
sudo hwclock --show
Force sync system time to RTC:
sudo hwclock --systohc
Entering Setup:
During the first second or two after power-on, hammer Del, F2, or Esc like a caffeinated gamer. That’s how you enter the firmware setup screen and see all these settings.
Pro-tip: If you’re too slow, you’ll end up at the OS bootloader. Don’t worry, we’ve all been there.
1.2 Power-On Self-Test (POST)
Once the PSU says “voltages are good,” the CPU starts executing firmware from a reset vector.
The firmware then runs POST:
| Step | What Happens | Typical Output |
|---|---|---|
| CPU & Cache | Verifies CPU can execute basic instructions, checks microcode, L1/L2 cache. | Often invisible, sometimes “CPU Test.” |
| Memory Test | Quick RAM checksum or pattern test. UEFI can run its own memory test; legacy BIOS might just count up MB. | “Memory Test” text or progress bar. |
| Peripheral Init | Detect and initialize chipset, PCIe bus, USB controllers, SATA/NVMe. | “Initializing USB…”, “Detecting NVMe SSD.” |
| Video | Initialize basic VGA/UEFI graphics so you can see messages or a splash screen. | Vendor logo or “Press F2 to enter Setup.” |
| Check Boot Devices | Scan the boot order list stored in CMOS and look for a bootable device. | “Booting from …” |
If any step fails, the firmware usually halts and either:
- Emits beep codes (classic BIOS)
- Displays an error code
- Flashes a diagnostic LED
Real-World Example – Beep Codes
- 1 long, 2 short = VGA not detected
- Continuous beeps = RAM failure
(These vary by vendor; check your board manual.)
1.3 Peripheral & Memory Initialisation in Detail
ACPI Tables:
During POST the firmware builds ACPI tables – giant data structures describing every device, its power states, interrupts, and more.
Linux later reads these tables from /sys/firmware/acpi/tables:
ls /sys/firmware/acpi/tables
SMBIOS/DMI Data:
Firmware collects manufacturer info, model numbers, and serials (the stuff tools like dmidecode show):
sudo dmidecode -t system
Sample output:
System Information
Manufacturer: Dell Inc.
Product Name: XPS 15 9550
Serial Number: ABCD123
UEFI Drivers:
Modern UEFI can load mini drivers:
- NVMe support to read bootloader off an NVMe SSD
- USB support to boot from flash drives
- Network PXE for booting over LAN
List UEFI boot entries from Ubuntu:
sudo efibootmgr -v
1.4 Troubleshooting POST Failures
| Symptom | Likely Cause | What You Can Do |
|---|---|---|
| Long beep, no display | RAM not seated or incompatible | Reseat RAM, test one stick at a time |
| Stuck on logo | USB device blocking POST | Unplug all peripherals, retry |
| “No boot device” | Wrong boot order or dead drive | Check CMOS settings, run lsblk in Linux later |
| Random crashes during boot | Unstable overclock or bad PSU | Reset BIOS to defaults, test PSU |
1.5 For the Enthusiasts: Watching POST Like a Pro
Some motherboards have a 2-digit POST code display. Cross-reference codes with your board manual to know exactly where it fails.
If you want to capture ACPI tables or DMI data to examine after POST:
sudo acpidump > acpi-tables.txt
sudo dmidecode > dmi-info.txt
Key Takeaways
- CMOS stores your firmware settings; the coin cell keeps them alive.
- POST is the firmware’s pre-flight check for CPU, RAM, and devices.
- Modern firmware builds ACPI and SMBIOS data for Linux.
- UEFI drivers allow reading bootloaders from NVMe, USB, or the network.
- Beep codes and POST LEDs are your friend when the screen stays black.
Stage 2 – BIOS/UEFI Initialization & Boot Device Selection
Now, assuming everything passed, the firmware (BIOS or UEFI) begins the process of initialization and boot device selection. This is where the system decides which drive or medium to load an operating system from — and eventually hands control to GRUB.
2.1 BIOS vs. UEFI in Plain English
| Feature | Legacy BIOS | UEFI (Modern) |
|---|---|---|
| Storage for settings | Tiny CMOS RAM | NVRAM (built into firmware) |
| Boot code location | Master Boot Record (MBR) | EFI System Partition (ESP) |
| Disk size limit | 2 TiB | 9.4 ZB (virtually unlimited) |
| Interface | Text menu | Graphical with mouse support |
| Drivers | Minimal | Extensible (UEFI drivers & apps) |
Tip: You can almost always press Del, F2, or Esc immediately after power-on to open the firmware setup. This is where the boot order is defined.
2.2 Boot Device Selection
Boot Order:
- The firmware stores a boot order list (for example:
1. USB,2. SSD,3. CD-ROM) in CMOS/NVRAM. - At boot time, it scans each entry:
| Device Type | What Firmware Looks For |
|---|---|
| Removable media | An EFI System Partition (ESP) or a BIOS-boot sector |
| Internal drive | EFI System Partition (UEFI) or Master Boot Record (MBR) (legacy) |
| Network (PXE) boot | A DHCP/TFTP server providing a boot image |
If multiple bootable entries exist, a boot manager menu may appear (“Select boot device”).
2.3 The EFI System Partition (ESP)
On a UEFI system, the ESP is a small FAT32 partition (≈200 MiB).
It contains .efi files — small executable programs that the firmware can run directly.
For Ubuntu, this usually looks like:
/EFI/ubuntu/shimx64.efi ← signed loader (Secure Boot)
/EFI/ubuntu/grubx64.efi ← actual GRUB binary
You can inspect it from Ubuntu itself:
sudo ls /boot/efi/EFI/ubuntu
Typical output:
grubx64.efi shimx64.efi MokManager.efi
Stage 3 – Firmware to Bootloader Handoff (UEFI → GRUB)
At this point in the boot process, the hardware has passed POST, memory has been checked, devices have been enumerated, and the firmware (BIOS/UEFI) has successfully identified a bootable device.
Now comes the crucial moment where control moves from the firmware to the bootloader.
On Ubuntu systems with UEFI, this means executing grubx64.efi — GRUB’s UEFI binary — from the EFI System Partition (ESP).
3.1 The ESP and grubx64.efi
On a UEFI system, your Ubuntu boot files live on a small FAT32 partition called the EFI System Partition (ESP). The path looks like this:
/boot/efi/EFI/ubuntu/grubx64.efi
That .efi file is an executable the firmware can run directly.
When the firmware chooses your Ubuntu boot entry (based on the boot order), it:
- Reads
grubx64.efifrom the ESP. - Loads it into memory.
- Hands over CPU control to it.
This handoff is the official start of GRUB.
You can see which boot entries your firmware knows about from within Ubuntu:
sudo efibootmgr -v
Typical output:
BootCurrent: 0002
Boot0000* Windows Boot Manager HD(1,GPT,...)/EFI/Microsoft/Boot/bootmgfw.efi
Boot0002* ubuntu HD(1,GPT,...)/EFI/ubuntu/grubx64.efi
This confirms where your firmware will jump next.
3.2 How GRUB Is Structured (Refresher)
GRUB isn’t a single blob; it’s a chain of stages.
Here’s the diagram again, because this is the handoff point:
+---------------------------+ +----------------------------+
| 1️⃣ Stage 1 (MBR/ESP) | | 2️⃣ Stage 1.5 (optional) |
| – tiny (≈ 512 B) | | – core.img (≈ 30 KB) |
| – loads Stage 2 | → | – contains modules, |
+---------------------------+ | drivers, file system |
+----------------------------+
↓
+---------------------------+ +----------------------------+
| 3️⃣ Stage 2 (grub.cfg) | → | 4️⃣ Linux kernel + initramfs|
| – full GRUB menu | | – loaded by GRUB |
| – reads /boot/grub.cfg | +----------------------------+
+---------------------------+
- Stage 1 (MBR or ESP) is what the firmware executes — on UEFI that’s
grubx64.efi. - Stage 1.5 (
core.img) contains modules to read filesystems like ext4 or Btrfs. - Stage 2 is the full GRUB environment, which reads
/boot/grub/grub.cfgand shows the menu.
At Stage 3 in our boot sequence, the system is moving from firmware → GRUB Stage 1.
3.3 Step-by-Step: What Happens During the Handoff
- Firmware Locates Entry
Looks up “ubuntu” in its NVRAM boot list (set withefibootmgr). - Read & Load
grubx64.efi
From\EFI\ubuntu\grubx64.efion the ESP. - Transfer Control
The CPU’s instruction pointer now jumps from firmware code to GRUB’s first instruction. - GRUB Initializes Itself
Loadscore.img(if present) and its modules, enabling it to read/boot. - Stage 2 Menu Appears
GRUB reads/boot/grub/grub.cfg, builds the menu, and awaits user selection.
3.4 Exploring It from Ubuntu
List the contents of your ESP:
sudo ls /boot/efi/EFI/ubuntu
Output:
grubx64.efi shimx64.efi MokManager.efi
Display the GRUB version currently installed:
grub-install --version
3.5 Why This Step Matters
This handoff is the first time non-firmware code runs during boot.
If grubx64.efi is missing, corrupted, or the boot entry is wrong, you’ll see “No bootable device found” or you’ll drop into the UEFI shell.
Repair example (reinstall GRUB’s EFI files):
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu
sudo update-grub
This re-creates grubx64.efi and updates the boot entry.
3.6 Summary
- Firmware chooses a boot entry (Ubuntu).
- Loads
grubx64.efifrom the ESP. - Hands control to GRUB Stage 1 (the beginning of the bootloader).
- GRUB then loads Stage 1.5 and Stage 2, reads
/boot/grub/grub.cfg, shows the menu, and eventually launches the Linux kernel.
This is the invisible but crucial bridge between “hardware world” and “software world.”
Stage 4 – The GRUB Loads Bootloader
At this point we’ve done the firmware dance, picked a boot device, executed grubx64.efi and landed inside GRUB.
This is the first time you see something recognizably “Linuxy” happening — the boot menu.
GRUB’s job from here is deceptively simple: show a menu, load two files, and pass a few strings. But under the hood, this is where Ubuntu Linux actually begins to wake up.
4.1 GRUB’s Job in a Nutshell
When you power on your Ubuntu machine and GRUB appears, it’s doing four main things:
- Display a menu if more than one OS or kernel is installed.
- Load the selected kernel image (e.g.
vmlinuz-5.xx-generic). - Load the initramfs (e.g.
initrd.img-5.xx-generic). - Pass kernel parameters to the kernel (such as
quiet splash).
Those two — kernel image and initramfs — are what actually get Linux off the ground.
4.2 The GRUB Menu & Kernel Parameters
If you’ve ever seen the purple GRUB screen with Ubuntu at the top and “Advanced options” underneath, that’s Stage 2 reading /boot/grub/grub.cfg. Each entry corresponds to a kernel+initramfs pair.
Typical kernel line in /boot/grub/grub.cfg:
linux /boot/vmlinuz-5.15.0-78-generic root=UUID=4e8b... ro quiet splash
initrd /boot/initrd.img-5.15.0-78-generic
vmlinuz= compressed kernel image.initrd.img= initial RAM filesystem.root=UUID=…= which disk/partition will become/.ro= mount root read-only first.quiet= suppress verbose kernel messages.splash= show Ubuntu logo + progress bar.
Remove quiet splash from this line and you’ll see a wall of text scrolling by — invaluable for troubleshooting.
4.3 Loading the Linux Kernel & initramfs
Once you pick an entry (or GRUB boots the default), it:
- Loads
vmlinuz-<version>into RAM. - Loads
initrd.img-<version>into RAM. - Builds the kernel command line from GRUB’s config.
- Jumps into the kernel’s entry point with the command line and the initramfs address.
You can list your installed initramfs images in Ubuntu:
ls /boot/initrd.img-*
And regenerate the current one if needed:
sudo update-initramfs -u
This will rebuild /boot/initrd.img-$(uname -r).
4.4 What the Kernel Does First (5.1 Early Kernel Init)
The kernel image (vmlinuz) is a compressed “bzImage”. It decompresses itself into memory before running any real code.
Here’s a table of the earliest phases:
| Phase | What Happens | Typical dmesg Output |
|---|---|---|
| Decompression | Kernel decompresses vmlinuz into RAM. |
Booting Linux on physical CPU 0x0 |
| Architecture Setup | Enable CPU features (MMU, caches, SIMD, page tables). | x86/fpu: supporting … |
| Command-line Parsing | Reads boot parameters passed by GRUB (root=UUID=… ro quiet splash). |
Kernel command line: root=UUID=… ro quiet splash |
The kernel now has enough of a brain to initialize memory management, the scheduler, basic drivers, and set up the environment for the next stage.
4.5 Device Description – ACPI & Device Tree
The kernel needs to know what devices exist and how to talk to them:
- On x86/UEFI, firmware passes ACPI tables. These describe CPUs, power domains, IRQ routing, sleep states, and hardware IDs.
- On ARM boards, the firmware passes a Device Tree Blob (DTB) which serves the same purpose.
The kernel parses these tables to build an internal map of your hardware before touching any devices.
4.6 The initramfs (Initial RAM Filesystem)
The initramfs is a compressed cpio archive that gets unpacked into a tiny RAM-based root filesystem (/).
It contains just enough to get the real root filesystem mounted.
Contents typically include:
- Essential drivers (dm-crypt, lvm2, mdadm, NVMe modules) to reach storage.
- Utilities like
busybox,udevadm,mount,fsck. - Scripts such as
/initthat perform the root-filesystem switch.
You can inspect your initramfs by unpacking it (for debugging):
mkdir /tmp/initrd
cd /tmp/initrd
zcat /boot/initrd.img-$(uname -r) | cpio -idmv
You’ll see directories like bin, sbin, scripts, and a file called init.
4.7 Typical Flow Inside initramfs/init
/init script:
├─ runs udev to populate /dev
├─ probes for the real root device (e.g., /dev/sda2, LVM LV, cryptsetup)
├─ runs fsck if needed
├─ mounts the real root as /new_root
└─ switches root (exec switch_root /new_root /sbin/init)
This is the handoff from a RAM-based mini-system to your actual on-disk Ubuntu root filesystem.
4.8 Visualising the Whole Step
GRUB menu →
Load vmlinuz + initrd into RAM →
Jump to kernel entry point →
Decompress kernel →
Parse command line, ACPI tables →
Unpack initramfs →
Locate real root →
switch_root → /sbin/init (systemd)
After this, the kernel’s init process (systemd on Ubuntu) takes over, mounts all filesystems, starts services, and eventually presents you with the login screen.
4.9 Tips for Beginners
- If your system hangs before showing the splash screen, remove
quiet splashfrom GRUB to see what’s happening. - Rebuild initramfs if you’ve changed storage drivers, encryption, or LVM setup.
- Use
dmesgafter boot to review the early kernel messages and spot errors. - ACPI errors in
dmesgare common but often harmless; still worth checking.
4.10 Summary
Stage 4 is where Linux actually starts running:
- GRUB loads the kernel and initramfs into memory.
- Kernel decompresses, initializes CPU and memory, parses firmware data.
- Initramfs provides the minimal environment to locate and mount your real root filesystem.
- When the switch happens,
/sbin/init(systemd) takes over and user space begins.
This stage bridges “bootloader world” and “kernel world”. Once you’re here, you’re officially running Linux.
Stage 5 – Kernel Hands Off to systemd & User Space
When the Linux kernel has finished its early initialization (loaded drivers, mounted the initramfs, and switched to the real root file system), it hands control over to the init process.
On Ubuntu (and almost all modern Linux distros), that init process is systemd located at /sbin/init (PID 1).
From this point on, we are officially in user space — the kernel is running in the background, and userland programs start shaping the system into a usable environment.
5.1 systemd Units
| Unit type | File extension | Purpose |
|---|---|---|
| Service | .service |
Long‑running daemons (e.g., networkd.service). |
| Target | .target |
Collection of units (e.g., graphical.target). |
| Socket | .socket |
On‑demand activation via socket activation. |
| Device | .device |
Represents a kernel device node. |
| Mount | .mount |
Filesystem mount points. |
| Timer | .timer |
Scheduled activation (cron‑like). |
| Path | .path |
Watches filesystem changes. |
All unit files live under /etc/systemd/system/ (admin overrides) or /lib/systemd/system/ (distribution defaults).
5.2 systemd – The Userspace Init System
Systemd replaces the old SysVinit. It starts as PID 1 and:
- Mounts remaining filesystems.
- Starts udev (device management).
- Spawns services in parallel.
- Reaches a target (a modern equivalent of runlevels).
Think of it as the traffic controller that decides which services, daemons, and graphical interfaces appear on your system.
5.2.1 Targets (High-Level Runlevels)
A target groups together units (services, sockets, mounts, timers…).
It’s systemd’s way of saying “boot into this state.”
| Target | What it Represents | Typical Units Pulled In |
|---|---|---|
| graphical.target | Full desktop environment (default on workstations). | gdm.service, plymouth-quit-wait.service, snapd.service |
| multi-user.target | Server-style boot (no graphical UI). | ssh.service, systemd-networkd.service |
| basic.target | Minimal system – earliest point after systemd itself. | sysinit.target, systemd-modules-load.service |
| rescue.target | Single-user mode (like legacy runlevel 1). | systemd-logind, systemd-ask-password-console.path |
Check the default target:
ls -l /etc/systemd/system/default.target
On Ubuntu 25.04:
ls -l /lib/systemd/system/default.target
This will show a symlink like:
/etc/systemd/system/default.target -> /lib/systemd/system/graphical.target
On Ubuntu 25.04:
/lib/systemd/system/default.target -> graphical.target
Change default target to console-only boot:
sudo systemctl set-default multi-user.target
sudo reboot
Revert to graphical:
sudo systemctl set-default graphical.target
sudo reboot
5.3 Core Services Started by systemd
Below are key systemd services you’ll encounter right after the kernel’s handoff. Each one plays a critical role.
| Service | Purpose | Config Location |
|---|---|---|
| systemd-modules-load.service | Loads static kernel modules defined in /etc/modules-load.d/*.conf. |
/etc/modules-load.d/ |
| systemd-udevd.service | Device manager – detects hardware and populates /dev. |
/lib/udev/ |
| systemd-journald.service | Central logging daemon. | /etc/systemd/journald.conf |
| systemd-networkd.service (or NetworkManager.service) | Network configuration. | /etc/systemd/network/ or /etc/NetworkManager/ |
| systemd-resolved.service | DNS resolver stub (127.0.0.53). | /etc/systemd/resolved.conf |
| systemd-timesyncd.service | Lightweight NTP client for time sync. | /etc/systemd/timesyncd.conf |
| snapd.service | Manages snap packages (including Ubuntu Desktop snap). | /etc/systemd/system/snapd.service |
| plymouth-start.service / plymouth-quit-wait.service | Controls the splash screen. | /etc/plymouth/ |
| gdm.service (or lightdm.service) | Display manager – shows login screen. | /usr/share/gdm/ |
5.3.1 Device Management (udev)
systemd-udevd listens to kernel events for new hardware.
Example: You plug in a USB drive → kernel reports event → udev creates /dev/sdX.
List current udev rules:
grep -r '' /etc/udev/rules.d/
Trigger udev manually:
sudo udevadm trigger
sudo udevadm settle
5.3.2 Logging (journald)
System logs are collected by systemd-journald.
View logs since boot:
journalctl -b
Follow logs in real time:
journalctl -f
5.3.3 Networking
On servers, systemd-networkd manages interfaces. On desktops, NetworkManager takes over.
List network units:
systemctl list-units --type=service | grep network
5.3.4 Time Sync
Ubuntu uses systemd-timesyncd by default.
Check status:
timedatectl status
Configure:
sudo nano /etc/systemd/timesyncd.conf
sudo systemctl restart systemd-timesyncd
5.4 systemd Units for Desktop Boot
When booting to a graphical session, systemd pulls in a series of units:
| Unit | Description |
|---|---|
| gdm.service | GNOME Display Manager – starts the login screen. |
| plymouth-quit-wait.service | Waits for Plymouth to finish before showing the login UI. |
| gnome-shell.service (via GDM) | Runs the GNOME desktop session. |
| pulseaudio.service (per-user) | Audio server. |
| xorg.service (managed by GDM) | X server (or Wayland). |
Check the boot order of graphical target:
systemctl list-dependencies graphical.target
Check status of GDM:
systemctl status gdm.service
5.5 Boot Flow Summary: Kernel → systemd → Login
Here’s how Stage 5 fits into the whole boot process:
- Kernel finishes init, mounts real root filesystem.
- Executes
/sbin/init→ systemd (PID 1). - systemd reads unit files from
/lib/systemd/systemand/etc/systemd/system. - systemd starts low-level services (
systemd-modules-load,udev,journald, etc.). - systemd reaches the default target (usually
graphical.target). gdm.servicestarts the display manager.- The login screen appears, waiting for the user.
5.6 Hands-On Examples
Check What’s Running:
systemctl
See Boot Performance:
systemd-analyze
systemd-analyze blame
This shows which services took the longest to start.
Rescue Mode (Single-User):
sudo systemctl isolate rescue.target
5.7 Key Directories
/lib/systemd/system/→ default unit files from packages./etc/systemd/system/→ admin overrides/custom units./etc/systemd/system/default.target→ symlink to current default target.
5.8 Visualizing Stage 5
Kernel (initramfs) ── switch_root ──> /sbin/init (systemd PID1)
│
├─ Loads modules, mounts fs
│
├─ systemd-modules-load, udev, journald
│
├─ Reach default.target (graphical)
│
├─ gdm.service starts login screen
│
└─ User logs in → user session (systemd --user)
5.9 Putting it all together
┌──────────────────────────────────────────────────────────────────────┐
│ Power Button Press → PSU → Power‑Good │
│ ─────────────────────────────────────────────────────────────────── │
│ Firmware (BIOS/UEFI) runs POST → ACPI tables │
│ ─────────────────────────────────────────────────────────────────── │
│ Stage‑1 bootloader (MBR or EFI) loads core.img (Stage‑1.5) │
│ ─────────────────────────────────────────────────────────────────── │
│ GRUB menu (if present) → selects Ubuntu kernel │
│ ─────────────────────────────────────────────────────────────────── │
│ Kernel (decompresses) → parses ACPI → mounts initramfs (RAM) │
│ ─────────────────────────────────────────────────────────────────── │
│ initramfs /init script → discovers real root FS → switch_root │
│ ─────────────────────────────────────────────────────────────────── │
│ /sbin/init (PID 1) = systemd │
│ ├─ sysinit.target → mounts, loads modules, udev │
│ ├─ basic.target → essential services (systemd‑journald, …) │
│ ├─ multi‑user.target → networking, console, sound │
│ └─ graphical.target → gdm.service → login screen │
└──────────────────────────────────────────────────────────────────────┘
5.10 Conclusion
Stage 5 marks the handover from the kernel to user space.
Systemd orchestrates everything — hardware initialization, logging, network setup, splash screen, and finally the graphical login.
By understanding systemd’s targets and services, you can troubleshoot boot issues, optimize startup time, or customize your Ubuntu boot experience.
Learn more about systemd and its role in the boot process in the following chapter here.
Stage 6 – Early Userspace and Device Discovery
After the Linux kernel has initialized its core subsystems, mounted the temporary initramfs, and launched the first user-space process, the system enters what’s known as the early userspace stage.
This phase bridges the gap between the kernel’s low-level hardware initialization and the moment when the full user environment begins to load. It’s a critical stage where the system discovers, configures, and activates your hardware — ensuring that storage devices, network interfaces, and input/output peripherals are properly recognized and ready for the next stage of the boot process.
6.1 What Happens in Early Userspace
When the kernel has successfully mounted the initial RAM filesystem (initramfs), it executes its init script. From this point on, a minimal Linux environment is available in memory, containing only essential tools and drivers.
During this stage, the following steps occur:
- udev (userspace device manager) starts running.
- It listens for kernel events related to hardware detection.
- As devices are discovered, it dynamically loads the required kernel modules.
- It populates
/devwith the appropriate device files.
- Kernel loads modules for detected hardware.
- For example, it loads storage drivers for disks, GPU drivers, USB controllers, and so on.
- These drivers may be built into the kernel or dynamically inserted as
.komodules.
- Root filesystem is mounted.
- The kernel temporarily runs from the
initramfs(a RAM-based root filesystem). - Once the proper drivers are loaded, it can mount the real root filesystem (usually on disk, SSD, or network storage).
- The kernel temporarily runs from the
- System switches from initramfs to the real root filesystem.
- Using the command
switch_root, control is transferred to the real system environment (e.g.,/sbin/initon/). - From here,
systemd(PID 1) takes over and begins managing the system as a whole.
- Using the command
This transition is seamless for the user but involves a lot of background orchestration — primarily handled by udev and related systemd services.
6.2 Understanding udev – The Userspace Device Manager
udev is the userspace component responsible for managing /dev dynamically. Unlike the old days when /dev contained thousands of static device files, modern Linux systems create these files on the fly whenever new hardware is detected.
udev’s responsibilities include:
- Listening for kernel uevents (notifications when hardware is added or removed).
- Loading the appropriate kernel modules (
modprobe) for each detected device. - Creating or removing device nodes under
/dev/. - Applying permissions and names to devices using rules from
/etc/udev/rules.d/and/lib/udev/rules.d/.
You can observe this behavior live:
udevadm monitor
This command shows real-time device events, for example:
KERNEL[123.456789] add /devices/pci0000:00/0000:00:14.0/usb1 (usb)
UDEV [123.457101] add /devices/pci0000:00/0000:00:14.0/usb1 (usb)
KERNEL[124.562812] add /devices/.../block/sda (block)
UDEV [124.563112] add /devices/.../block/sda (block)
Each line shows a hardware event being handled first by the kernel, and then by udev in user space.
6.3 Checking Which Drivers Are Loaded
To see what kernel modules (drivers) are currently active, use:
lsmod
Typical output:
Module Size Used by
snd_hda_codec_hdmi 57344 1
i915 258048 3
btusb 45056 0
usbcore 278528 8 btusb,usbhid,ehci_hcd,xhci_hcd
Explanation:
- Module – The name of the loaded kernel module.
- Size – The size of the module in bytes.
- Used by – Number of references (how many other modules or processes are using it).
You can get detailed information about a specific module:
modinfo i915
Example output:
filename: /lib/modules/6.8.0-35-generic/kernel/drivers/gpu/drm/i915/i915.ko
license: GPL and additional rights
description: Intel Graphics Driver
author: Intel Corporation
alias: pci:v00008086d0000A780sv*sd*bc03sc00i00*
depends: drm,drm_buddy,drm_kms_helper,video
This is especially useful when troubleshooting graphics or network driver issues.
6.4 Exploring udev Rules
udev rules determine how devices are named and configured when detected. Rules are plain-text files located in:
/etc/udev/rules.d/– Custom user-defined rules./lib/udev/rules.d/– Default system rules (do not edit directly).
Example: /lib/udev/rules.d/60-cdrom_id.rules
ACTION=="add|change", SUBSYSTEM=="block", ENV{ID_CDROM}=="1", SYMLINK+="cdrom"
This rule ensures that when a CD-ROM device is added, it gets a /dev/cdrom symlink.
You can test rule processing using:
udevadm test /sys/class/block/sda
This will show how udev interprets the event for the given device path.
6.5 Switching from initramfs to the Real Root Filesystem
At some point, once all necessary device drivers are loaded (especially storage and filesystem drivers), the system is ready to mount the real root filesystem.
This process typically involves:
- Locating the root device (e.g.,
/dev/sda2, UUID, or LVM volume). - Checking filesystem integrity (via
fsckif required). - Mounting the root filesystem on
/new_root. - Transferring control to the new root with
switch_root.
You can observe this step in the system log:
dmesg | grep "switch_root"
Example output:
[ 2.310000] switch_root: Switching to root on /dev/sda2
After this, the kernel hands over full control to /sbin/init (which on modern Ubuntu systems is a symlink to systemd).
6.6 Key Commands for Debugging Early Userspace
| Command | Purpose |
|---|---|
lsmod |
Lists all loaded kernel modules (drivers). |
modinfo <module> |
Displays detailed info about a specific driver. |
udevadm monitor |
Monitors live device events (add/remove/change). |
udevadm info --query=all --name=/dev/sda |
Shows detailed udev information about a device. |
dmesg |
grep -i usb |
Example:
udevadm info --query=all --name=/dev/sda | grep ID_MODEL
Output:
E: ID_MODEL=Samsung_SSD_970_EVO
6.7 Common Issues During Early Userspace
| Symptom | Possible Cause | Solution |
|---|---|---|
| System drops into an initramfs shell | Root filesystem not found or missing drivers | Ensure the correct storage drivers are built-in or included in initramfs. Check /etc/fstab and update-initramfs -u. |
Devices not appearing under /dev |
udev not running or rule misconfiguration | Check udevadm monitor output and rule syntax. |
| Slow boot after kernel load | Timeout while waiting for disk or network devices | Adjust rootdelay= in GRUB or fix missing firmware. |
| USB or network devices not recognized | Missing kernel modules | Use modprobe <module> and verify with lsmod. |
6.8 Summary
At this stage, your system has moved from the kernel-only world into early userspace.
Here’s what has happened:
✅ The initramfs environment has been initialized.
✅ udev has started and populated /dev.
✅ All essential kernel modules for hardware have been loaded.
✅ The real root filesystem has been mounted.
✅ Control is about to pass to systemd (PID 1).
This smooth transition sets the stage for the next part of the journey — the moment when systemd officially takes over and begins orchestrating the rest of the boot process.
Stage 7 – systemd Takes Over (PID 1)
Once the kernel finishes its early initialization and hands off control from initramfs, systemd becomes the very first process in user space — assigned the Process ID (PID) 1. This moment officially marks the beginning of userspace initialization, when all higher-level services, mounts, devices, and targets are systematically brought online.
7.1 What is systemd (and why PID 1 matters)
In every Linux system, PID 1 is special. It’s responsible for:
- Bringing the system to a usable state.
- Starting and supervising all background services (daemons).
- Handling system shutdowns and reboots gracefully.
- Reaping zombie processes that have lost their parents.
Traditionally, the init process (from SysVinit) handled these tasks.
Ubuntu, like most modern Linux distributions, uses systemd — a more efficient and feature-rich replacement for the legacy init system.
You can confirm that systemd is indeed the first process:
ps -p 1 -o pid,comm,cmd
Example output:
PID COMMAND CMD
1 systemd /sbin/init splash
This shows that process 1 (systemd) is running and was started by the kernel as /sbin/init (often a symlink to /lib/systemd/systemd).
7.2 How systemd boots the system
Once in control, systemd starts executing a predefined chain of units (think of them as building blocks).
Each unit represents a component or a configuration item — like a service, mount point, device, or target.
Systemd organizes the startup process as follows:
- Reads its configuration from
/etc/systemd/system/and/lib/systemd/system/. - Determines the default target (the modern equivalent of the old “runlevel”).
- Starts essential units like device managers, mount points, logging, and networking.
- Activates higher-level targets — such as
multi-user.targetorgraphical.target.
You can check which default target is currently used:
ls -l /etc/systemd/system/default.target
Typical output:
/etc/systemd/system/default.target -> /lib/systemd/system/graphical.target
This means the system will boot into a graphical environment by default.
7.3 Anatomy of a systemd Unit
Each unit file defines how a service or resource should be started, stopped, and ordered.
Unit files live in /lib/systemd/system/ (default) or /etc/systemd/system/ (overrides).
Example: /lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
After=network.target auditd.service
[Service]
ExecStart=/usr/sbin/sshd -D
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
Explanation:
- [Unit]: Metadata and dependency information.
- [Service]: The command to run, how it behaves, and restart policies.
- [Install]: Which target this unit should start under.
To inspect a unit dynamically:
systemctl cat sshd.service
7.4 systemd Startup Order and Dependencies
Systemd doesn’t just start everything at once — it builds a directed dependency graph.
Each service declares when it should start, based on Before, After, and Wants/Requires directives.
You can visualize dependencies like this:
systemctl list-dependencies multi-user.target
Or see how far the boot process has progressed:
systemd-analyze blame
This command lists the startup time of each unit, helping diagnose slow boots.
Example output:
2.303s NetworkManager.service
1.876s systemd-logind.service
1.214s snapd.service
998ms systemd-udevd.service
7.5 systemd Logging and Monitoring
Systemd centralizes logs with its built-in service, journald.
All messages from early boot through shutdown are captured in memory or on disk.
Check recent boot messages:
journalctl -b
View logs for a specific service:
journalctl -u ssh.service
Follow logs in real-time:
journalctl -f
7.6 Managing Services
Once systemd is running, you interact with it using the systemctl command.
| Task | Command | Description |
|---|---|---|
| Check service status | systemctl status ssh |
Displays status, PID, logs |
| Start a service | sudo systemctl start ssh |
Starts immediately |
| Stop a service | sudo systemctl stop ssh |
Gracefully stops it |
| Enable on boot | sudo systemctl enable ssh |
Links unit to default target |
| Disable on boot | sudo systemctl disable ssh |
Removes startup link |
| Restart service | sudo systemctl restart ssh |
Useful after config changes |
You can verify all active services at any time:
systemctl list-units --type=service --state=running
7.7 systemd Targets and Runlevels
Systemd replaced SysVinit’s numeric runlevels with named targets:
| Target | Legacy Runlevel | Description |
|---|---|---|
poweroff.target |
0 | Shutdown |
rescue.target |
1 | Single-user (maintenance) |
multi-user.target |
3 | Multi-user (no GUI) |
graphical.target |
5 | Multi-user with GUI |
reboot.target |
6 | Reboot |
Switch between them easily:
sudo systemctl isolate multi-user.target
To make it permanent:
sudo systemctl set-default multi-user.target
Return to GUI mode:
sudo systemctl set-default graphical.target
7.8 Troubleshooting Common systemd Boot Issues
Service fails to start
Check logs for details:
systemctl status <service>
journalctl -u <service>
Slow boot time
Find bottlenecks with:
systemd-analyze blame
Stuck boot process
Switch to rescue mode:
sudo systemctl isolate rescue.target
Emergency shell
If even rescue.target fails, the system might fall back to an emergency shell, which allows manual recovery.
7.9 systemd in Context
By this stage, the system:
- Has loaded all drivers and devices.
- Mounted the root filesystem.
- Initialized core daemons (network, logging, time sync).
- Brought the system to its default operational target.
From here, the journey continues to the display manager (GDM) or the login prompt, depending on whether you’re running a desktop or server edition.
This transition — from systemd to a user session — marks the bridge between system initialization and user interaction, leading us to the next chapter.
Stage 8 – Target Units and Services Until Graphical Login
At this point, the Linux kernel has finished its job, the early userspace (initramfs) has handed off control to systemd, and the real root filesystem is now active.
This stage — “Target Units and Services Until Graphical Login” — is where the system blossoms from raw hardware and kernel processes into a structured, multi-service operating environment.
Let’s explore how systemd orchestrates everything: from mounting file systems and activating networking, all the way to starting the graphical login screen you see on Ubuntu Desktop.
8.1 What Are Targets and Units in systemd?
systemd is not just an init system — it’s a full service and dependency manager for Linux.
Everything it starts or manages is represented as a unit.
Types of systemd Units
| Unit Type | Description | Example |
|---|---|---|
.service |
Starts and manages background daemons or programs. | sshd.service, gdm.service |
.socket |
Listens for network or IPC connections. | cups.socket |
.mount |
Mounts a filesystem. | home.mount |
.target |
A grouping of units, similar to old runlevels. | multi-user.target, graphical.target |
.device |
Represents a hardware device. | /dev/sda |
.timer |
Triggers services periodically. | apt-daily.timer |
Targets: The Modern Runlevels
In classic SysV init, you had runlevels (0–6). In systemd, these have been replaced by targets — logical checkpoints that group services together.
| Traditional Runlevel | systemd Target | Description |
|---|---|---|
| 1 | rescue.target |
Single-user mode (maintenance). |
| 3 | multi-user.target |
Full text-based (non-graphical) system. |
| 5 | graphical.target |
Multi-user + graphical desktop environment. |
| 0 | poweroff.target |
System shutdown. |
| 6 | reboot.target |
System reboot. |
You can view the current target with:
systemctl get-default
Output (for Ubuntu Desktop):
graphical.target
This means your system boots directly into the full GUI environment.
8.2 The Boot Progression Through systemd Targets
Let’s break down the journey from kernel handoff to the login screen:
systemd (PID 1)
↓
basic.target
↓
multi-user.target
↓
graphical.target
Each target builds upon the previous one.
8.2.1 basic.target
This is the minimal system environment — the first significant milestone after systemd starts.
At this stage, systemd has mounted essential filesystems, loaded kernel modules, and started early logging.
Typical units under basic.target:
sysinit.target– initializes system settings (hostname, console, random seed, etc.)systemd-udevd.service– continues device management from early userspace.systemd-modules-load.service– loads configured kernel modules.systemd-journald.service– handles system logging.
You can see dependencies with:
systemctl list-dependencies basic.target
8.2.2 multi-user.target
Once basic initialization is complete, systemd moves to multi-user.target — equivalent to a fully functional server environment without a GUI.
At this point:
- Networking is configured (
systemd-networkd.serviceorNetworkManager.service). - Remote access becomes available (
sshd.service). - Time synchronization starts (
systemd-timesyncd.service). - Filesystems are mounted.
- User login via console (
getty@tty1.service) is possible.
Example command:
systemctl list-dependencies multi-user.target
Typical services:
| Service | Purpose |
|---|---|
systemd-networkd.service |
Configures network interfaces. |
systemd-resolved.service |
Handles DNS resolution. |
sshd.service |
Enables SSH access. |
cron.service |
Runs scheduled jobs. |
snapd.service |
Manages Snap packages. |
udisks2.service |
Manages disk mounting. |
If you set your system to boot in this mode, you’ll get a terminal login prompt instead of a graphical interface:
sudo systemctl set-default multi-user.target
sudo reboot
8.2.3 graphical.target
This is the default for Ubuntu Desktop systems — the point where the display manager (GDM3) is started.
graphical.target pulls in:
- Everything from multi-user.target.
gdm.service(GNOME Display Manager) — responsible for showing the graphical login screen.plymouth-quit-wait.service— gracefully hides the splash screen before the desktop session starts.
You can explore it with:
systemctl list-dependencies graphical.target
Typical services:
| Service | Purpose |
|---|---|
gdm.service |
Starts GNOME Display Manager (login screen). |
plymouth-quit-wait.service |
Manages the transition from splash screen. |
avahi-daemon.service |
Network service discovery (mDNS). |
colord.service |
Manages color profiles for displays and printers. |
accounts-daemon.service |
Handles user accounts for login. |
To set your system back to GUI boot:
sudo systemctl set-default graphical.target
sudo reboot
8.3 How systemd Knows What to Start
systemd uses unit dependencies to determine startup order.
Each unit file (in /lib/systemd/system/) declares:
Requires=– units that must be running.Wants=– optional dependencies.Before=andAfter=– startup ordering.Conflicts=– mutually exclusive services.
Example: /lib/systemd/system/graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
After=multi-user.target
This means:
graphical.targetdepends on (Requires=)multi-user.target.- It also wants (
Wants=) thedisplay-manager.service(which isgdm.serviceon Ubuntu). - It starts after
multi-user.targetis ready.
8.4 Viewing Boot Progress and Logs
To understand how your system reached its current state, you can check boot logs:
Show boot performance
systemd-analyze
Output example:
Startup finished in 3.625s (kernel) + 7.812s (userspace) = 11.437s
graphical.target reached after 7.812s in userspace
List all services and their startup times
systemd-analyze blame
Example output:
3.2s NetworkManager-wait-online.service
2.1s snapd.service
1.8s systemd-journald.service
Inspect logs for specific targets
journalctl -b -u gdm.service
8.5 Common Issues Before the Login Screen
| Symptom | Likely Cause | Fix |
|---|---|---|
| Stuck on splash screen | Problem with plymouth or graphics driver |
Try Ctrl + Alt + F3 to switch to console and check journalctl -xe. |
| Black screen after boot | GDM or GPU driver failure | Run sudo dpkg-reconfigure gdm3 or reinstall driver (sudo ubuntu-drivers autoinstall). |
| Boot hangs at “Waiting for network configuration” | systemd-networkd-wait-online.service timeout |
Disable with sudo systemctl disable systemd-networkd-wait-online.service. |
| Long boot time | Slow service startup | Check with systemd-analyze blame. |
8.6 Quick Reference Commands
| Action | Command |
|---|---|
| View default target | systemctl get-default |
| Change default target | sudo systemctl set-default <target> |
| List dependencies | systemctl list-dependencies <target> |
| Check graphical target status | systemctl status graphical.target |
| Restart display manager | sudo systemctl restart gdm.service |
8.7 Summary
Here’s what happens in Stage 8 – Target Units and Services Until Graphical Login:
✅ systemd takes control as PID 1 and begins processing targets.
✅ Essential system services start under basic.target.
✅ The system transitions into multi-user.target, enabling networking, logging, and shell access.
✅ Finally, graphical.target starts the display manager (GDM3) and prepares the login environment.
By the end of this stage, your Ubuntu system has fully initialized — all background services are running, devices are configured, and the display manager is waiting for your login.
Stage 9 – Login Managers & Desktop Session
At this point, the system has passed through all the heavy lifting of kernel initialization, hardware discovery, and user-space setup. The machine is alive, devices are recognized, and systemd has reached the graphical.target. Now it’s time for the user to finally interact with the system — through a login manager and a desktop session.
9.1 What Is a Login Manager?
A login manager (or display manager) is the bridge between the core system and the user’s graphical environment. It’s what you see when the system asks for your username and password before presenting your desktop.
On Ubuntu Desktop, this role is usually played by GDM3 (GNOME Display Manager), though alternatives like LightDM, SDDM, and XDM exist on other systems.
Key functions of a login manager:
- Starts the display server (Xorg or Wayland).
- Displays the greeter — the graphical login screen.
- Authenticates the user (username/password).
- Launches the user’s session (e.g., GNOME, KDE, XFCE).
9.2 How the Login Manager Starts
Once systemd reaches graphical.target, it activates the GDM service automatically:
systemctl status gdm.service
Typical output:
● gdm.service - GNOME Display Manager
Loaded: loaded (/lib/systemd/system/gdm.service; enabled)
Active: active (running) since Tue 2025-10-07 10:14:05 UTC; 2min ago
Main PID: 1342 (gdm3)
Tasks: 3 (limit: 4567)
Memory: 52.0M
CGroup: /system.slice/gdm.service
├─1342 /usr/sbin/gdm3
└─1350 /usr/libexec/gdm-wayland-session
You can restart it if you modify configuration or encounter issues:
sudo systemctl restart gdm.service
9.3 Configuration Files and Paths
| File / Directory | Purpose |
|---|---|
/etc/gdm3/custom.conf |
GDM configuration file. Controls automatic login, Wayland/Xorg preference, and greeter settings. |
/usr/share/gdm/greeter/ |
The graphical greeter’s UI files. |
/var/lib/gdm3/.Xauthority |
X session authentication cookie for the display manager. |
Example: enabling automatic login
# /etc/gdm3/custom.conf
[daemon]
AutomaticLoginEnable=true
AutomaticLogin=pavel
9.4 What Happens After Login
Once the user successfully logs in, GDM runs the user’s session script, usually launching:
gnome-sessionfor GNOME desktops, orstartplasma-x11for KDE, orstartxfce4for XFCE.
The session script sets up the desktop environment — window manager, panels, notification systems, background daemons, and startup applications.
Example process tree after login (simplified):
systemd (PID 1)
└─ gdm3
├─ gdm-session-worker
└─ gnome-session
├─ gnome-shell
├─ gnome-settings-daemon
├─ nautilus
└─ gnome-terminal
9.5 Troubleshooting Login Issues
| Symptom | Likely Cause | Remedy |
|---|---|---|
| Black screen after login | Missing or incompatible graphics driver | Install correct driver: sudo ubuntu-drivers autoinstall |
| GDM fails to start | Corrupted greeter theme or permission issue | sudo dpkg-reconfigure gdm3 |
| Stuck on text login | GDM service not starting automatically | sudo systemctl enable gdm.service --now |
You can also check GDM logs for clues:
journalctl -u gdm.service -b
9.6 Switching Between Display Managers
You can switch to another login manager if GDM is not your style:
sudo apt install lightdm
sudo dpkg-reconfigure gdm3
Choose LightDM (or another manager) when prompted, and restart:
sudo systemctl restart display-manager
Summary
| Component | Description |
|---|---|
| Display Manager (e.g., GDM3) | Manages graphical logins and sessions. |
| Session Manager (e.g., gnome-session) | Loads the user’s desktop environment. |
| Display Server (Xorg/Wayland) | Handles input/output and rendering. |
| Systemd (graphical.target) | Ensures the graphical environment is ready. |
Conclusion
By the time you reach Stage 9, your Ubuntu system has completed its entire boot chain — from firmware and kernel all the way to the smiling face of GDM. The display manager and session handler together form the gateway to the graphical world.
From this moment on, you’re no longer watching the system start — you’re inside it.
10. Diagnostics, Logs & Commands to Inspect Boot
By this stage, your Ubuntu system is fully operational — from firmware initialization to the graphical desktop. But every DevOps engineer, system administrator, or even curious Linux enthusiast knows: understanding the boot process is only half the battle — the other half is knowing how to troubleshoot it when something goes wrong.
This chapter dives into the tools, logs, and commands that reveal what actually happened during boot and where to look when it doesn’t go as planned.
10.1 Understanding the Boot Timeline
Linux systems powered by systemd make it incredibly easy to visualize and analyze boot performance.
To see how long your system took to boot and which services were slow, use:
systemd-analyze
Example output:
Startup finished in 3.482s (kernel) + 12.153s (userspace) = 15.635s
graphical.target reached after 12.003s in userspace
You can even get a detailed breakdown of which units took the most time:
systemd-analyze blame
Example:
10.241s NetworkManager-wait-online.service
4.301s snapd.service
3.825s dev-sda1.device
Or visualize it as a graphical SVG timeline (handy for deep inspection):
systemd-analyze plot > boot.svg
Then open boot.svg in a browser to view the boot sequence as a colored timeline.
10.2 Reading Boot Logs
Every systemd-managed service logs its output to the journal, which you can query with:
journalctl -b
This shows all logs for the current boot.
Add -b -1 for the previous boot, or -b -2 for earlier ones.
Example:
journalctl -b -1 | less
You can also focus on specific services:
journalctl -u gdm.service -b
journalctl -u systemd-logind.service -b
journalctl -u networkd-dispatcher.service -b
Or follow logs live as the system runs:
journalctl -f
10.3 Checking Kernel Messages
The kernel’s messages during boot — hardware initialization, driver loading, and system state — can be reviewed with:
dmesg | less
or:
journalctl -kTypical first lines show the firmware handoff and hardware detection sequence:
[ 0.000000] Linux version 6.8.0-31-generic (buildd@lcy02-amd64-027) ...
[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.8.0-31-generic root=UUID=...
[ 0.000000] e820: BIOS-provided physical RAM map:
To filter for specific events:
dmesg | grep -i error
dmesg | grep -i usb
dmesg | grep -i nvme
10.4 Inspecting Systemd Services
If your system hangs during boot, one of the services might be failing. To check:
systemctl --failed
Example:
UNIT LOAD ACTIVE SUB DESCRIPTION
● systemd-modules-load.service loaded failed failed Load Kernel Modules
Inspect its detailed logs:
systemctl status systemd-modules-load.service
journalctl -u systemd-modules-load.service -b
To manually restart or test a service:
sudo systemctl restart systemd-modules-load.service
10.5 Investigating Hardware & Device Detection
The udev subsystem manages device discovery during boot. You can monitor live events or review what was detected.
Check loaded kernel modules:
lsmod | head
Inspect a specific driver:
modinfo e1000e
Monitor live hardware events:
udevadm monitor
If you plug in a USB device or network card, udevadm shows real-time events from the kernel and udev.
10.6 Recovering from Boot Problems
If your system doesn’t boot into the graphical environment or hangs mid-way, these are your lifelines:
1. Enter GRUB and edit boot parameters temporarily
At the GRUB menu, press e and append systemd.unit=rescue.target to the kernel line to boot into single-user mode.
2. Boot into text-only mode
If your display manager fails, boot with:
systemd.unit=multi-user.target
This skips GDM and brings you to a command-line login.
3. Repair broken packages
sudo apt update
sudo apt install -f
4. Reconfigure broken services
sudo dpkg-reconfigure gdm3
5. Regenerate GRUB configuration
sudo update-grub
10.7 Useful Commands Summary
| Command | Purpose |
|---|---|
systemd-analyze |
Measure overall boot time |
systemd-analyze blame |
List slow services |
systemd-analyze plot > boot.svg |
Visualize boot sequence |
journalctl -b |
View logs from current boot |
dmesg |
Review kernel messages |
systemctl --failed |
Check failed services |
udevadm monitor |
Watch live device events |
systemctl status <service> |
Inspect a service’s status and logs |
sudo update-grub |
Regenerate GRUB configuration |
10.8 When Things Go Sideways
| Symptom | Possible Cause | Fix |
|---|---|---|
| System hangs after GRUB | Kernel or initramfs issue | Boot with previous kernel (Advanced Options in GRUB) |
| Black screen after boot | GDM or graphics driver issue | Boot to text mode, install drivers (sudo ubuntu-drivers autoinstall) |
| Network not available | Network service delay | systemd-analyze blame and disable NetworkManager-wait-online.service if unneeded |
| Boot takes too long | Unnecessary services or slow disks | systemd-analyze critical-chain |
Conclusion
Troubleshooting the Linux boot process doesn’t have to be a black art. With tools like systemd-analyze, journalctl, and dmesg, you can see exactly what’s happening during startup — and where it goes wrong.
By mastering these diagnostics, you can go beyond “it doesn’t boot” and instead say, “it doesn’t boot because the initramfs couldn’t mount the root filesystem due to a missing NVMe driver.”
That’s the difference between guessing and knowing.
11. Best Practices for Troubleshooting Slow Boots
You’ve pressed the power button, poured yourself a coffee, checked your messages, maybe fed the cat — and your Ubuntu desktop is still not ready. Welcome to the mysterious world of slow boots, where seconds stretch into eternities and “starting network service…” lingers longer than a Netflix cliffhanger.
In this chapter, we’ll go step-by-step through how to identify, analyze, and fix slow boot issues on Ubuntu Linux — and sprinkle a few jokes along the way to keep your sanity intact.
11.1 Step 1 – Measure Before You Guess
First, let’s stop guessing and start measuring. Linux gives you everything you need to time every part of the boot process.
Check Total Boot Time
systemd-analyze
Example output:
Startup finished in 4.102s (kernel) + 13.412s (userspace) = 17.514s
graphical.target reached after 13.112s in userspace
If your total is above ~20 seconds on SSD-based systems, something’s holding things up.
Find the Culprit
systemd-analyze blame
This lists services by how long they took to start:
10.214s NetworkManager-wait-online.service
6.832s snapd.service
3.721s dev-sda2.device
Pro tip:
If you see NetworkManager-wait-online.service at the top, you’ve already found a classic time thief — it waits for a network connection before continuing boot.
11.2 Step 2 – Visualize the Boot Sequence
Let’s see the big picture (literally).
systemd-analyze plot > boot.svg
Open boot.svg in your browser and scroll horizontally — each colored bar represents a service or phase of the boot.
Long bars = slow services.
Tiny bars = fast services (the ones that make you proud).
For a more compact text-based summary:
systemd-analyze critical-chain
This shows which services depend on others, and how long each one blocked the next stage.
11.3 Step 3 – Understand What’s Actually Happening
Slow boots typically fall into five categories:
| Category | Description | Example |
|---|---|---|
| Network delays | System waits for a network interface or DHCP timeout | NetworkManager-wait-online.service |
| Disk or filesystem delays | Drives slow to mount, fsck checks | dev-sda*.device, systemd-fsck@.service |
| Hardware initialization | Old BIOS, bad USB devices, missing drivers | dmesg shows delays |
| Startup scripts & daemons | Snapd, cloud-init, or heavy background services | snapd.service, apt-daily.service |
| Graphical stack delays | GDM, Wayland/Xorg, GPU initialization | Black screen before login |
11.4 Step 4 – Fix Common Slow Boot Culprits
NetworkManager-wait-online.service
This service waits for a network connection before finishing boot — useful for servers, but completely unnecessary on desktops.
Disable it:
sudo systemctl disable NetworkManager-wait-online.service
Or mask it entirely (for maximum “no-wait” effect):
sudo systemctl mask NetworkManager-wait-online.service
Filesystem & Drive Delays
Run:
systemd-analyze blame | grep fsck
If fsck (filesystem check) is taking ages, it might indicate:
- Old drives with SMART issues.
- Improper shutdowns or dirty partitions.
- Misconfigured fstab entries.
Check your /etc/fstab for devices that might not always exist (like old USB drives):
sudo nano /etc/fstab
Use nofail or x-systemd.device-timeout=5s options to skip missing drives quickly:
UUID=XXXX-XXXX /mnt/backup ext4 defaults,nofail,x-systemd.device-timeout=5s 0 2
Snap Daemons
snapd.service and snapd.seeded.service can take ages on first boots.
While you can’t fully disable them without breaking some system packages, you can limit their impact:
sudo systemctl disable snapd.seeded.service
sudo systemctl mask snapd.snap-repair.service
And optionally schedule updates to happen after boot:
sudo systemctl edit snapd.service
Add this override:
[Service]
ExecStartPre=/bin/sleep 30
11.5 Step 5 – Review Kernel & Hardware Initialization
Run:
dmesg --ctime | less
Look for long pauses ([ 10.123456] timestamps) — those are clues.
Common slow points:
- Missing GPU drivers (nouveau struggling with NVIDIA).
- BIOS USB timeouts (“new high-speed USB device number 2 using xhci_hcd”).
- Slow disk initialization (especially external drives).
If your GPU is proprietary (e.g., NVIDIA), install proper drivers:
sudo ubuntu-drivers autoinstall
11.6 Step 6 – Tune Services and Startup
See which services start automatically:
systemctl list-unit-files --state=enabled
Disable what you don’t need:
sudo systemctl disable cups.service
sudo systemctl disable bluetooth.service
Be careful — only disable services you’re sure about. You can always re-enable:
sudo systemctl enable <service>
11.7 Step 7 – Optimize GRUB
The bootloader can also add delay.
Edit:
sudo nano /etc/default/grub
Find and adjust:
GRUB_TIMEOUT=2
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
Reduce timeout or remove unnecessary parameters.
Then update:
sudo update-grub
If you want to see what’s happening (for debugging slow boots):
GRUB_CMDLINE_LINUX_DEFAULT="verbose"
11.8 Step 8 – Clean Up the System
Old kernels and unused services can pile up like digital dust bunnies.
Remove old kernels:
sudo apt autoremove --purge
Clean up snaps and apt cache:
sudo snap remove --purge $(snap list --all | awk '/disabled/{print $1, $2}')
sudo apt clean
11.9 Step 9 – Benchmark After Fixes
Reboot and compare:
systemd-analyze
systemd-analyze blame
Your boot time should shrink dramatically.
If not — well, at least you’ve earned the right to complain with data instead of vibes.
11.10 Quick Checklist
✅ Run systemd-analyze and blame to identify slow services
✅ Disable or mask unnecessary daemons
✅ Add nofail and timeouts in /etc/fstab
✅ Update drivers, especially GPU and NVMe
✅ Reduce GRUB timeout
✅ Clean old kernels and snaps
✅ Reboot and re-measure
Conclusion
Slow boots are like traffic jams — caused by too many things waiting on each other. The beauty of Linux is that you can see every car in that traffic jam, know who’s driving it, and kick it off the road if necessary.
Once you trim unnecessary services, fix fstab delays, and optimize GRUB, Ubuntu can boot faster than some people can find the “power” button.
So the next time someone says, “Linux boots slow,” you can smile, open your terminal, and whisper:
“Not on my system.” 😎
Would you like the next chapter to be
🧩 “Advanced Boot Debugging with systemd and Kernel Parameters” — covering debug, init=/bin/bash, and systemd.log_level for deep-dive troubleshooting?
12. References (a.k.a. “The Treasure Map for Those Who Actually Read the Manual”)
You’ve done it — from pressing the power button to landing on the Ubuntu login screen, through every mystical BIOS beep, kernel unpack, and systemd target.
Now it’s time to hand you the master key collection — the official docs, guides, specs, and tools used to create this manual and recommended for anyone brave enough to dig deeper.
💬 “Documentation is like broccoli — everyone knows it’s good for them, but they’d rather skip it.
Do yourself a favor: eat the broccoli.”
12.1 Official Documentation
Linux Kernel
- The Linux Kernel Archives – https://www.kernel.org/doc/html/latest/
The definitive, ever-updated source. Start here when you want to know what really happens under the hood. - Kernel Parameters Reference – https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
Explains every kernel command-line option (e.g.,quiet,nosplash,acpi=off, etc.). - Boot Parameters Explained (Ubuntu Wiki) – https://wiki.ubuntu.com/Kernel/KernelBootParameters
systemd
- systemd Official Documentation – https://www.freedesktop.org/software/systemd/man/
All man pages, fromsystemd-analyze(1)tosystemd.target(5).
GRUB (GRand Unified Bootloader)
- GNU GRUB Manual (v2.06) – https://www.gnu.org/software/grub/manual/grub.html
Covers installation, configuration, and all GRUB commands. - Ubuntu GRUB Customization – https://help.ubuntu.com/community/Grub2
Practical Ubuntu-specific tweaks and rescue procedures. - EFI System Partition and Bootloaders (UEFI.org) – https://uefi.org/specifications
For those who want to go full nerd on UEFI boot flow and the ESP layout.
BIOS / UEFI Firmware
- UEFI Specification (Version 2.10+) – https://uefi.org/specifications
The official firmware spec defining the interface between firmware and the OS. - ACPI Specification (Power Management and Device Tables) – https://uefi.org/specifications
Learn how firmware describes power states (S0–S5) and devices to Linux. - Intel UEFI BIOS Internals Whitepapers – https://www.intel.com/content/www/us/en/download/19352/uefi.html
Initramfs, Init Systems, and Early Boot
- initramfs Guide (Debian/Ubuntu) – https://wiki.debian.org/initramfs
Explains how/initworks and how the kernel switches to the real root filesystem. - BusyBox Documentation – https://busybox.net/downloads/BusyBox.html
The tiny Swiss Army knife inside your initramfs. - systemd-udevd & udevadm Manual – https://www.freedesktop.org/software/systemd/man/udevadm.html
Diagnostics & Logging
- journalctl(1) – https://manpages.ubuntu.com/manpages/jammy/en/man1/journalctl.1.html
- dmesg(1) – https://man7.org/linux/man-pages/man1/dmesg.1.html
- systemd-analyze(1) – https://www.freedesktop.org/software/systemd/man/systemd-analyze.html
12.2 Ubuntu-Specific References
- Ubuntu Manpages Search – https://manpages.ubuntu.com/
- Ubuntu Documentation Portal – https://help.ubuntu.com/
- Ask Ubuntu (Community Forum) – https://askubuntu.com/
- Launchpad Bugs and Blueprints – https://launchpad.net/ubuntu
12.3 Tools Used Throughout This Manual
| Tool | Purpose | Example |
|---|---|---|
systemd-analyze |
Boot time breakdown & profiling | systemd-analyze blame |
journalctl |
Read persistent boot logs | journalctl -b -1 |
dmesg |
Kernel boot messages | dmesg --level=err,warn |
lsmod |
List loaded kernel modules | `lsmod |
udevadm monitor |
Watch live hardware events | udevadm monitor --property |
update-initramfs |
Rebuild initramfs | sudo update-initramfs -u |
efibootmgr |
Manage UEFI boot entries | sudo efibootmgr -v |
systemctl |
Manage units & targets | systemctl list-dependencies graphical.target |
grub-mkconfig |
Rebuild GRUB configuration | sudo grub-mkconfig -o /boot/grub/grub.cfg |
12.4 Suggested Reading & Deep Dives
- “How Linux Boots” – IBM DeveloperWorks
A classic breakdown of BIOS → Bootloader → Kernel → Init. - “Understanding Systemd: The Modern Init” – Red Hat Developers Blog
A friendly and visual explanation of systemd internals. - “Inside the Linux Boot Process” – LWN.net
Excellent article for intermediate readers who want to trace each subsystem. - “GRUB, UEFI, and Secure Boot Explained” – Ubuntu Wiki
Great overview for modern Ubuntu installations. - “Power Management in Linux” – kernel.org documentation
Deep look into S-states, suspend/resume, and ACPI implementation.
12.5 Author’s Closing Notes
By now you’ve probably realized that the Linux boot process isn’t just a straight line — it’s a symphony of firmware, kernel, user-space, and services that must all play in perfect time.
Every log line you’ve seen, every systemd-analyze blame you’ve run, and every “mysterious 10-second delay” you’ve debugged — all part of the grand dance between hardware and software.
And yes, all of this happens in just a few seconds —
unless, of course, your system decides to “NetworkManager-wait-online” itself into a coffee break. ☕
12.6 License & Attribution
All command examples, tables, and descriptions in this guide are provided for educational use.
Documentation excerpts are referenced from Ubuntu, GNU, kernel.org, and freedesktop.org manuals under their respective open licenses.
End of the Ubuntu Boot Process Manual
(from “Stage 0 – The Power Button” to “Stage 10 – References”)
If your system now boots cleanly and predictably — congratulations!
If not… you now have enough knowledge to fix it yourself, which is the true Linux spirit. 🐧
Feel free to ask for clarification on any specific step or for commands to diagnose a particular problem you’re seeing on your Ubuntu machine. Happy booting!