Linux Administration #10: Boot Management and System Start

Linux boot management and system start for administrators: BIOS/UEFI, GRUB2 configuration, kernel parameters, initramfs, systemd targets, chroot recovery environments, and emergency recovery.

Reading time: 88 min

In Article #9 of our Linux Administration series you already learned how to systematically monitor your Linux system, diagnose performance problems, and create automated monitoring scripts. Now we dive deeper and look at what actually happens before all these tools are even available:

How does your Linux system start, and how do you configure the boot process professionally?

This is exactly where boot management comes in — a critically important area of Linux administration that you as an aspiring administrator must understand.

Important note: This article is aimed at technically interested Linux beginners, learners with the goal of understanding and implementing Linux administration, and readers who value practical, understandable, and thoroughly explained content.

Why is this important?

Imagine you come into the office in the morning and your important Linux server won't start. The screen only shows cryptic error messages or remains completely black.

Without solid knowledge of the boot process, you are helpless:

  • Is this a hardware problem?
  • Is there a bootloader error?
  • Are the kernel parameters wrong?
  • Is the filesystem corrupted?

💡 You will need this later to: solve critical boot problems as a Linux administrator, perform system updates safely, and manage boot configurations professionally.

How this article is structured

We start with the basics of the boot process — you will learn what happens from pressing the power button to the finished desktop. Then we work through bootloader configuration with practical GRUB2 and systemd-boot examples.

In the second part of the article, I show you how to set kernel parameters, understand init systems, and create initramfs configurations for complex storage setups.

🔧 Practice focus / example:

Practical focus: Every section contains concrete examples and realistic configuration scenarios. You don't just learn the theory — you apply everything in practical situations.

⚠️ Note: Boot management is not just theory — a misconfigured bootloader can make your system unusable. That's why you learn not only the concepts here, but also safe practices and backup strategies.

💡 You will need this later to: manage boot configurations professionally as a Linux administrator, resolve hardware compatibility problems, set up encrypted systems, and pass the LPIC-1 exam (boot management is a central topic).

Understanding the Linux boot process

From power-on to the login prompt

The moment you press the power button of your computer starts a fascinating chain of events. In just a few seconds, a "dead" computer transforms into a fully functional Linux system. This complex process runs through six clearly defined phases that you as an aspiring Linux administrator must understand.

Without this basic understanding, you will be helpless when boot problems occur. You would try various solutions at random instead of systematically narrowing down the problem. Each boot phase can cause specific problems that require different diagnostic tools and solution strategies.

Understanding the six boot phases in detail

Phase 1: Hardware initialization and Power-On Self-Test (POST)

Immediately after powering on, the motherboard takes the first control of the system. The integrated microcontroller on the mainboard starts a built-in test program called the Power-On Self-Test (POST). This test systematically checks all critical hardware components for basic functionality.

First, the system tests the main memory (RAM).

The motherboard sends defined test patterns to various memory addresses and checks whether they can be correctly read back. Defective memory modules are detected in this phase and prevent further booting.

The processor (CPU) is tested for its basic functions.

The motherboard checks whether the CPU correctly executes the most important machine instructions and its registers function properly. Additionally, the CPU temperature is monitored — overheating would immediately stop the boot process.

The most important components such as graphics card, hard drive controller, and USB controller are tested for their presence and basic responsiveness. The system creates an internal list of all detected hardware components.

You can recognize this phase by characteristic signals: Most motherboards emit a single, short beep when POST completes successfully. Multiple beeps or a continuous beep signal hardware problems. Modern systems also show LED status indicators or numeric error codes on small displays.

💡 The typical POST duration is 2-8 seconds, depending on the amount of memory and hardware complexity. Servers with lots of RAM need correspondingly longer for the memory test.

Phase 2: Firmware start and boot device detection (BIOS/UEFI)

After successful POST, the system firmware takes control.

This firmware is either the traditional BIOS (Basic Input/Output System) or the more modern UEFI (Unified Extensible Firmware Interface). The firmware is a special program permanently stored in a flash memory on the motherboard.

The firmware initializes additional hardware components needed for the boot process. It configures the memory controllers, activates the hard drive interfaces, and prepares the basic input/output functions.

Now the firmware searches for bootable devices.

It works through a predefined list of storage media: typically first USB sticks, then CD/DVD drives, then the internal hard drive or SSD. You can configure this order in the BIOS/UEFI setup.

For each potential boot device, the firmware checks whether there is a valid boot sector on it. For traditional BIOS systems, it looks for a special data pattern at the end of the first sector (512 bytes) of the hard drive. UEFI systems look for a special partition with boot files.

Once the firmware has found a bootable device, it loads the first sector (Master Boot Record for BIOS or EFI boot files for UEFI) from the storage medium into main memory. It then transfers control to this loaded code.

💡 The firmware phase typically takes 1-3 seconds. You often see the motherboard manufacturer's logo or a simple text menu with hardware information in this phase.

Phase 3: Bootloader execution and kernel preparation (GRUB2)

The loaded boot code now starts the actual bootloader. On Linux systems, this is almost always GRUB2 (GRand Unified Bootloader Version 2). GRUB2 is a complex program consisting of multiple stages that progressively loads more functionality.

First, the minimal boot code from the Master Boot Record starts.

This code is only a few hundred bytes in size and has a single task: it loads the larger GRUB2 core from the hard drive. The GRUB2 core already contains the most important filesystem drivers and can read various partition types.

GRUB2 now reads its configuration file /boot/grub/grub.cfg from the boot partition. This file contains all available boot options: different kernel versions, recovery modes, and possibly other operating systems like Windows.

You see the characteristic GRUB menu with boot options.

By default, GRUB2 waits five seconds for your input before the default entry is automatically started. You can use the arrow keys to select a different option or use the Tab key to edit boot parameters.

GRUB2 now loads two critical files from the filesystem into main memory: the Linux kernel (usually at /boot/vmlinuz-) and the initramfs image (usually at /boot/initrd.img-). The kernel is the actual operating system, while initramfs provides a minimal Linux environment for the early boot phase.

💡 Loading the kernel and initramfs takes 2-10 seconds depending on hard drive speed. SSD systems are significantly faster than traditional hard drives.

Phase 4: Kernel start and hardware detection

GRUB2 hands over control to the loaded Linux kernel. The kernel is now the "master" of the entire system. First, the kernel decompresses itself in main memory — modern kernels are stored compressed to save space.

The kernel initializes its internal data structures and starts the memory management. It takes complete control of the main memory and sets up virtual memory areas. From this moment on, the system runs in protected mode — no program can directly access the hardware anymore.

Now the extensive hardware detection begins. The kernel systematically loads all needed hardware drivers. It detects hard drives, network cards, USB controllers, graphics hardware, and other peripheral devices. You can see this information later in the output of dmesg.

The kernel unpacks the initramfs image into a virtual RAM disk. The initramfs contains important programs and drivers for the early boot phase, especially for encrypted systems or complex RAID configurations. It also provides basic programs like mount, modprobe, and shell commands.

With the help of the tools in the initramfs, the kernel mounts the correct root filesystem. For simple systems, this is directly a partition on the hard drive. For encrypted or LVM-based systems, these layers must first be activated.

💡 Note: Kernel initialization typically takes 3-15 seconds, depending on hardware complexity and the number of drivers to load.

Phase 5: Init system start and service management (systemd)

After the root filesystem has been successfully mounted, the kernel starts the first user-space process with process ID 1 (PID 1). On modern Linux distributions, this is systemd. This process is the "father" of all other processes in the system.

systemd reads its configuration from various directories like /etc/systemd/ and /lib/systemd/. It creates a complex dependency graph of all system services: which services depend on others, which can start in parallel, and which must be started sequentially.

The init system now systematically starts all configured services. It works through the so-called "boot target" — usually multi-user.target for server systems or graphical.target for desktop systems. Each target defines which services are needed for that operating mode.

Services are started in parallel as much as possible to reduce boot time. systemd monitors the dependencies: a web server can only start after the network is available. A database service must be running before the web application starts.

Typical services in this phase are:

  • Network configuration (NetworkManager or systemd-networkd)
  • SSH daemon for remote access
  • Cron daemon for scheduled tasks
  • Log services like rsyslog or systemd-journald
  • Hardware-specific services like audio system or Bluetooth

💡 Note: The systemd phase usually takes 5-25 seconds, depending on the number and complexity of configured services.

Phase 6: User space and login readiness

After successfully starting all system services, systemd activates the user interface. On server systems, the Getty service starts, which provides the text-based login prompt on consoles. On desktop systems, a display manager like GDM, SDDM, or LightDM also starts.

The display manager is responsible for the graphical login interface. It starts the X11 server or Wayland compositor, loads the login window, and waits for user input. After successful login, it starts the selected desktop environment like GNOME, KDE, or XFCE.

In parallel, user-specific services are started. systemd supports user services that are automatically activated when the respective user logs in. These can be applications like email clients, cloud sync tools, or development services.

The system is now fully operational. All services are running, the network is configured, and users can log in and work.

The complete boot process visualized


Power-On                                                       
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 1. Power supply stabilizes (12V, 5V, 3.3V)                  │
│    Duration: 0.1 - 0.5 seconds                              │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 2. POST microcontroller starts & takes control               │
│    Duration: ~0.1 seconds                                   │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 3. CPU test (registers, ALU, FPU, cache, thermal protection)│
│    Duration: 0.2 - 0.5 seconds                              │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 4. RAM test (address/data bus, bit pattern memory check)    │
│    Duration: 1.0 - 8.0 seconds (depends on RAM size)       │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 5. Hardware detection (PCIe bus, GPU, controller, storage)  │
│    Duration: 0.5 - 3.0 seconds                              │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 6. POST completed successfully (1x beep / LED OK)           │
│    Hardware table created -> Handover to BIOS / UEFI        │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
                     BIOS / UEFI takes over                    

💡 You will need this later to: distinguish hardware problems from software problems, systematically diagnose boot failures, select the right hardware for Linux servers, and quickly identify the cause during critical system failures. POST understanding is fundamental for every Linux administrator, since all software-based diagnostic tools are useless if the system does not survive the hardware phase.

⚠️ Important note: POST runs completely without an operating system. No Linux tool, no diagnostic program, and no recovery software can help you with POST problems. You rely on hardware diagnostic methods and systematic component tests.

Understanding and configuring the bootloader

GRUB2 — the standard bootloader

GRUB2 (GRand Unified Bootloader Version 2) is the bootloader used by virtually all modern Linux distributions. After successful POST and the firmware phase, GRUB2 takes control of the boot process and loads the actual Linux kernel. As a Linux administrator, you will regularly work with GRUB2 configurations — whether during new system installation, kernel updates, or fixing boot problems.

GRUB2 is far more than a simple boot program. It is a complete mini operating system with its own command line, script support, and the ability to read various filesystems. This complexity makes GRUB2 very powerful, but also error-prone. A misconfigured GRUB2 can make your entire system unbootable.

Understanding GRUB2 architecture and multi-stage loading

The three stages of GRUB2:

GRUB2 works in a multi-stage process that spans different memory areas. This design is necessary because the available space in the Master Boot Record is only 446 bytes — far too little for a complete bootloader.

Stage 1 — MBR boot code (boot.img):

The first GRUB2 code is tiny and fits into the 446 bytes of the Master Boot Record. This boot.img has only one task: it loads the next stage from the hard drive. The code is so minimal that it has no filesystem knowledge and can only read raw sectors.

Stage 1.5 — Core image (core.img):

The core image is the actual GRUB2 kernel and is stored directly after the MBR partition. This image already contains basic filesystem drivers and can understand various partition types. The size varies between 25-100 KB depending on needed modules.

Stage 2 — GRUB2 modules:

The complete GRUB2 modules are in the /boot/grub/ directory and are loaded by stage 1.5. Here you find all advanced features like the graphical user interface, network boot support, and complex script functions.

GRUB2 directory structure and important files


# GRUB2 directories and their functions
ls -la /boot/grub/
total 2048
drwxr-xr-x 5 root root    4096 Jan 15 10:30 .

# Fonts for boot menu
drwxr-xr-x 2 root root    4096 Jan 15 10:30 fonts      
-rw-r--r-- 1 root root    1024 Jan 15 10:30 grub.cfg   

# Main configuration file
-rw-r--r-- 1 root root   30720 Jan 15 10:30 grubenv    

# Environment variables
drwxr-xr-x 2 root root    4096 Jan 15 10:30 i386-pc    

# BIOS-specific modules
drwxr-xr-x 2 root root    4096 Jan 15 10:30 locale     

# Language files

💡 Note: The central configuration file /boot/grub/grub.cfg contains all boot entries and GRUB2 settings. It is automatically generated and should never be edited directly.


# Example structure of a grub.cfg (simplified)
sudo head -20 /boot/grub/grub.cfg

# DO NOT EDIT THIS FILE
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub

set default="0"
set timeout="5"
set timeout_style="menu"

menuentry 'Ubuntu, with Linux 5.15.0-74-generic' --class ubuntu {
	recordfail
	load_video
	gfxmode $linux_gfx_mode
	insmod gzio
	insmod part_gpt
	insmod ext2
	linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro quiet splash
	initrd  /boot/initrd.img-5.15.0-74-generic
}

Understanding and correctly editing configuration files

The main configuration file /etc/default/grub:

This file contains the global GRUB2 settings and is the only place where you as an administrator should change GRUB2 parameters.


# Important parameters in /etc/default/grub
cat /etc/default/grub

# How long the boot menu is displayed
GRUB_TIMEOUT=5

# Default boot entry (0 = first entry)
GRUB_DEFAULT=0

# Kernel parameters for all boot entries
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

# Additional kernel parameters
GRUB_CMDLINE_LINUX=""

# Show or hide boot menu
GRUB_TIMEOUT_STYLE=menu

# Boot menu resolution
GRUB_GFXMODE=640x480

Configuration templates in /etc/grub.d/:

GRUB2 generates the final grub.cfg from various template scripts. These scripts are processed in numerical order:


ls -la /etc/grub.d/
total 72
drwxr-xr-x 2 root root  4096 Jan 15 10:30 .
drwxr-xr-x 3 root root  4096 Jan 15 10:30 ..
-rwxr-xr-x 1 root root  9792 Jan 15 10:30 00_header          

# GRUB2 basic configuration
-rwxr-xr-x 1 root root  6258 Jan 15 10:30 05_debian_theme    

# Design and graphics
-rwxr-xr-x 1 root root 12693 Jan 15 10:30 10_linux           

# Linux kernel entries
-rwxr-xr-x 1 root root 11298 Jan 15 10:30 20_linux_xen       

# Xen hypervisor entries
-rwxr-xr-x 1 root root  1992 Jan 15 10:30 20_memtest86+      

# Memory test entries
-rwxr-xr-x 1 root root 11692 Jan 15 10:30 30_os-prober       

# Detect other operating systems
-rwxr-xr-x 1 root root   216 Jan 15 10:30 40_custom          

# Custom boot entries
-rwxr-xr-x 1 root root   214 Jan 15 10:30 41_custom          

# Additional custom entries

🔧 Practical example: Changing GRUB2 configuration step by step

Scenario: You want to reduce the boot time from 5 to 2 seconds and disable the splash screen.

Step 1: Back up current configuration


# Create backup of current configuration
sudo cp /etc/default/grub /etc/default/grub.backup
sudo cp /boot/grub/grub.cfg /boot/grub/grub.cfg.backup

# Backup timestamp for later reference
ls -la /etc/default/grub*
-rw-r--r-- 1 root root 1234 Jan 15 10:30 /etc/default/grub
-rw-r--r-- 1 root root 1234 Jan 15 10:35 /etc/default/grub.backup

Step 2: Edit configuration


# Edit main configuration
sudo nano /etc/default/grub

# Make changes:
# Before: GRUB_TIMEOUT=5
# After: GRUB_TIMEOUT=2
# Before: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
# After: GRUB_CMDLINE_LINUX_DEFAULT="quiet"

Step 3: Regenerate configuration


# Regenerate GRUB2 configuration
sudo update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-5.15.0-74-generic
Found initrd image: /boot/initrd.img-5.15.0-74-generic
Found linux image: /boot/vmlinuz-5.15.0-72-generic
Found initrd image: /boot/initrd.img-5.15.0-72-generic
Found Windows Boot Manager on /dev/sda1
done

# Alternative (on Red Hat/Fedora systems):
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Step 4: Verify changes


# Check new grub.cfg for changes
sudo grep -E "(timeout|quiet)" /boot/grub/grub.cfg
set timeout="2"
	linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro quiet

# Restart system and test
sudo reboot

Understanding and structuring boot menu entries

Structure of a GRUB2 menu entry:


menuentry 'Ubuntu, with Linux 5.15.0-74-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.15.0-74-generic-advanced-12345678-1234-1234-1234-123456789abc' {
	recordfail                                    

# Enable error logging
	load_video                                    

# Load graphics modules
	gfxmode $linux_gfx_mode                     

# Set graphics resolution
	insmod gzio                                   

# Load compression module
	insmod part_gpt                              

# Load GPT partition module
	insmod ext2                                   

# Load ext2/3/4 filesystem module
	search --no-floppy --fs-uuid --set=root 12345678-1234-1234-1234-123456789abc  

# Find root partition
	linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro quiet splash  

# Load kernel
	initrd  /boot/initrd.img-5.15.0-74-generic  

# Load initramfs
}

Parameter meanings in detail:

Parameter Function Why important?
recordfail Logs boot errors Shows boot menu automatically on errors
load_video Loads graphics drivers Enables graphical boot menu
insmod Loads GRUB2 modules Filesystem and hardware support
search Finds root partition Works even with changed device names
linux Loads kernel image Defines kernel path and parameters
initrd Loads initial RAM disk Provides early boot environment

Advanced GRUB2 configurations

Managing multiple kernel versions:

Linux systems often keep multiple kernel versions for fallback purposes. GRUB2 detects these automatically and creates corresponding boot entries.


# List installed kernels
ls -la /boot/vmlinuz*
-rw-r--r-- 1 root root 8.9M Jan 10 09:15 /boot/vmlinuz-5.15.0-74-generic
-rw-r--r-- 1 root root 8.8M Dec 15 08:20 /boot/vmlinuz-5.15.0-72-generic
-rw-r--r-- 1 root root 8.7M Nov 20 07:45 /boot/vmlinuz-5.15.0-70-generic

# Currently running kernel
uname -r
5.15.0-74-generic

# GRUB2 automatically creates sub-menus for older kernels
sudo grep -A 5 "submenu" /boot/grub/grub.cfg
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-12345678-1234-1234-1234-123456789abc' {
	menuentry 'Ubuntu, with Linux 5.15.0-74-generic' --class ubuntu {

# ... kernel parameters
	}
	menuentry 'Ubuntu, with Linux 5.15.0-74-generic (recovery mode)' --class ubuntu {

# ... recovery parameters
	}
}

Adding custom boot entries:

For special requirements, you can create your own boot entries in /etc/grub.d/40_custom:


sudo nano /etc/grub.d/40_custom

#!/bin/sh
exec tail -n +3 $0

# Add custom boot entries here

menuentry 'Ubuntu Debug Mode' {
	load_video
	insmod gzio
	insmod part_gpt
	insmod ext2
	search --no-floppy --fs-uuid --set=root 12345678-1234-1234-1234-123456789abc
	linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro debug nosplash
	initrd  /boot/initrd.img-5.15.0-74-generic
}

menuentry 'Memory Test (memtest86+)' {
	insmod part_gpt
	insmod ext2
	search --no-floppy --fs-uuid --set=root 12345678-1234-1234-1234-123456789abc
	linux16 /boot/memtest86+.bin
}

Default boot entry and fallback mechanisms

Understanding the GRUB_DEFAULT parameter:


# Numeric selection (0 = first entry)
GRUB_DEFAULT=0

# Selection by name
GRUB_DEFAULT="Ubuntu, with Linux 5.15.0-74-generic"

# Remember last successfully started entry
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

Fallback on boot errors:


# Automatic fallback after boot errors
GRUB_DEFAULT="0"
GRUB_FALLBACK="1"
GRUB_RECORDFAIL_TIMEOUT=30

# Meaning:
# - Normally boot entry 0
# - On errors: boot entry 1 with 30s timeout
# - Boot menu is displayed automatically on errors

Warning: Why you should never edit grub.cfg directly

The fundamental GRUB2 principle:

GRUB2 follows a strict configuration management approach. The /boot/grub/grub.cfg is completely automatically generated and completely overwritten with every update-grub call.

Dangerous editing of grub.cfg:

  • System doesn't boot and you need immediate change
  • Live system repair without persistence
  • One-time boot parameters for hardware debugging

⚠️ Important: Such direct changes are always temporary and are lost with the next update-grub.

Avoiding common GRUB2 configuration errors

Error 1: Wrong UUID references


# Problem: Wrong or outdated UUID in grub.cfg
# Cause: Hard drive cloned or partitions changed
# Determine current UUIDs:
sudo blkid
/dev/sda1: UUID="12345678-1234-1234-1234-123456789abc" TYPE="ext4"
/dev/sda2: UUID="87654321-4321-4321-4321-cba987654321" TYPE="swap"

# Use correct UUID in /etc/default/grub
# Then: sudo update-grub

Error 2: Missing kernel images


# Problem: grub.cfg references non-existent kernels
# Check available kernels:
ls -la /boot/vmlinuz* /boot/initrd*

# Fix broken kernel installation:
sudo apt install --reinstall linux-image-generic
sudo update-grub

Error 3: Inconsistent timeout configuration


# Problem: GRUB_TIMEOUT=0 hides menu completely
# When boot problems occur, you can no longer reach the menu
# Safer configuration:
GRUB_TIMEOUT=2              

# At least 2 seconds
GRUB_TIMEOUT_STYLE=menu     

# Always show menu
GRUB_RECORDFAIL_TIMEOUT=10  

# Wait longer on errors

GRUB2 performance and optimization

Boot time optimization:


# Faster GRUB2 configuration:
GRUB_TIMEOUT=1                    

# Shorter wait time
GRUB_GFXMODE=text                

# Text mode instead of graphics
GRUB_TERMINAL=console            

# Use console output
GRUB_DISABLE_SUBMENU=y           

# Disable sub-menus

Optimize module loading:


# Only load needed modules
GRUB_PRELOAD_MODULES="part_gpt part_msdos ext2 fat"

# Disable unnecessary features
GRUB_DISABLE_RECOVERY="true"     

# Hide recovery entries
GRUB_DISABLE_OS_PROBER="true"    

# Disable other OS detection

GRUB2 boot flow


GRUB2 Bootloader Start                                         
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Stage 1: boot.img (MBR / GPT Partition Header)              │
│ Loads first code block and refers to core.img               │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Stage 1.5: core.img (filesystem drivers: ext4, xfs, btrfs) │
│ Enables reading of /boot/grub/                              │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Stage 2: grub.cfg & modules (/boot/grub/grub.cfg)           │
│ Display boot menu / select default kernel entry             │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Load kernel & initramfs (/boot/vmlinuz + /boot/initrd.img)  │
│ Pass kernel parameters -> Start Linux kernel init           │
└─────────────────────────────────────────────────────────────┘

💡 You will need this later to: perform Linux installations, manage kernel updates safely, diagnose and fix boot problems, configure multi-boot systems, and adjust boot configuration when hardware changes. GRUB2 knowledge is essential for every Linux administrator and a frequent exam topic in Linux certifications.

Critical security note: Always create a backup of your working GRUB2 configuration before making changes. A broken GRUB2 makes your system completely unusable. Keep a Linux live system ready so you can repair GRUB2 in an emergency.

GRUB command line and recovery

When your Linux system won't boot, the GRUB command line is often your last resort. This powerful emergency environment allows you to boot your system even with a broken GRUB configuration, or at least access your data. As a Linux administrator, you must master the GRUB command line — it is indispensable for boot recovery situations.

The GRUB command line is a complete mini operating system with its own shell, filesystem support, and a variety of commands. You reach it when the normal boot menu doesn't work or when you need to temporarily change boot parameters. This environment runs completely independently of the installed Linux system and can therefore also be used with severe system damage.

Understanding and reaching GRUB rescue mode

Automatic rescue mode:

The GRUB rescue mode activates automatically when GRUB2 cannot load its normal configuration file or critical modules are missing. You recognize this state by the characteristic prompt:


grub rescue>

This situation typically occurs when:

  • The /boot/grub/grub.cfg has been deleted or corrupted
  • The /boot directory cannot be found
  • Critical GRUB2 modules are missing in /boot/grub/
  • The partition table has been corrupted
  • A hard drive has failed or been moved

Manual access to the GRUB command line:

Even if your system boots normally, you can reach the GRUB command line for diagnostic or testing purposes:

  • 1. In the GRUB boot menu: Press c for the command line
  • 2. Edit boot entry: Press e on a boot entry, then Ctrl+C
  • 3. Via kernel parameters: Add break=init to the kernel parameters

The normal GRUB command line shows the prompt:


grub>

Understanding important GRUB command line commands

Filesystem navigation and access:


# List available devices and partitions
grub> ls
(hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3) (cd0)

# Display partition contents
grub> ls (hd0,gpt2)/
./ ../ boot/ etc/ home/ usr/ var/

# Determine filesystem type of a partition
grub> ls -l (hd0,gpt2)
		Partition hd0,gpt2: Filesystem type ext2 - Label 'root' - UUID 12345678-1234-1234-1234-123456789abc

# Display file contents
grub> cat (hd0,gpt2)/etc/fstab

# Shows the contents of the fstab file

Managing environment variables:


# Display all variables
grub> set
cmdpath=(hd0,gpt2)/boot/grub
prefix=(hd0,gpt2)/boot/grub
root=hd0,gpt2

# Set variable
grub> set root=(hd0,gpt2)

# Display variable
grub> echo $root
(hd0,gpt2)

Loading and managing modules:


# List available modules
grub> ls (hd0,gpt2)/boot/grub/i386-pc/
all_video.mod boot.mod configfile.mod ext2.mod linux.mod normal.mod

# Load module
grub> insmod ext2
grub> insmod linux
grub> insmod normal

# Display loaded modules
grub> lsmod

🔧 Practical example: Booting the system despite broken GRUB configuration

Scenario: Your Ubuntu system only shows grub rescue> after an interrupted update. The normal grub.cfg is no longer available.

Step 1: Analyze the situation and find the root partition


grub rescue> ls
(hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3)

# Check each partition for contents
grub rescue> ls (hd0,gpt1)/
error: unknown filesystem.

grub rescue> ls (hd0,gpt2)/
./ ../ boot/ etc/ home/ usr/ var/

# That looks like the root partition!
grub rescue> ls (hd0,gpt2)/boot/
grub/ vmlinuz-5.15.0-74-generic initrd.img-5.15.0-74-generic

Step 2: Load basic modules


# Set root variable
grub rescue> set root=(hd0,gpt2)

# Set prefix for GRUB files
grub rescue> set prefix=(hd0,gpt2)/boot/grub

# Load critical modules
grub rescue> insmod (hd0,gpt2)/boot/grub/i386-pc/normal.mod
grub rescue> insmod (hd0,gpt2)/boot/grub/i386-pc/linux.mod
grub rescue> insmod (hd0,gpt2)/boot/grub/i386-pc/ext2.mod

Step 3: Start normal GRUB environment


# Activate normal mode
grub rescue> normal

# Now you should see the normal GRUB command line:
grub>

Step 4: Boot manually


# List available kernels
grub> ls /boot/
vmlinuz-5.15.0-74-generic initrd.img-5.15.0-74-generic

# Determine root partition UUID
grub> ls -l (hd0,gpt2)
Partition hd0,gpt2: Filesystem type ext2 - UUID 12345678-1234-1234-1234-123456789abc

# Load Linux kernel
grub> linux /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro

# Load initial RAM disk
grub> initrd /boot/initrd.img-5.15.0-74-generic

# Boot system
grub> boot

Temporarily changing and testing boot parameters

Modifying kernel parameters at runtime:

The GRUB command line allows you to change boot parameters without affecting the permanent configuration. This is particularly useful for debugging or hardware compatibility tests.


# Standard boot with additional debug parameters
grub> linux /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro debug nosplash

# Work around graphics problems
grub> linux /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro nomodeset

# Single-user mode for repairs
grub> linux /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro single

# Disable network modules
grub> linux /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro blacklist=e1000e

Commonly used kernel parameters for recovery:

Parameter Function When to use?
single Single-user mode Forgotten password, repairs
init=/bin/bash Direct to shell Bypass all init scripts
ro Mount root filesystem read-only Avoid filesystem damage
nomodeset Disable graphics modesetting Graphics problems, black screen
acpi=off Completely disable ACPI Hardware compatibility problems
noapic Disable APIC interrupts Interrupt conflicts
debug Verbose kernel logging Detailed error diagnosis
break=init Stop before init system Initramfs debugging

Advanced GRUB recovery techniques

Chainloading other bootloaders:

GRUB2 can call other bootloaders to boot alternative operating systems:


# Chainload Windows bootloader (BIOS system)
grub> set root=(hd0,msdos1)
grub> chainloader +1
grub> boot

# Call UEFI Windows Boot Manager
grub> set root=(hd0,gpt1)
grub> chainloader /EFI/Microsoft/Boot/bootmgfw.efi
grub> boot

Memory diagnostics from GRUB:


# Start Memtest86+ (if installed)
grub> set root=(hd0,gpt2)
grub> linux16 /boot/memtest86+.bin
grub> boot

Network boot via GRUB:


# Activate network interface
grub> insmod net
grub> insmod efinet
grub> insmod tftp

# IP configuration (DHCP)
grub> net_bootp

# Load kernel over network
grub> linux (tftp,192.168.1.100)/vmlinuz root=/dev/nfs ip=dhcp
grub> initrd (tftp,192.168.1.100)/initrd.img
grub> boot

Fixing the typical "error: unknown filesystem" error

The most common GRUB recovery error:


grub rescue> ls (hd0,gpt2)/
error: unknown filesystem.

This error means GRUB does not recognize the filesystem of the partition.

The most common causes:

Cause 1: Missing filesystem modules


# Check available modules
grub rescue> ls (hd0,gpt2)/boot/grub/i386-pc/ | grep fs
ext2.mod fat.mod ntfs.mod

# Load matching modules
grub rescue> insmod (hd0,gpt2)/boot/grub/i386-pc/ext2.mod

Cause 2: Corrupted partition table


# Scan partitions again
grub rescue> ls

# If fewer partitions appear than expected, the partition table is corrupted

Cause 3: Wrong partition labeling


# Systematically check all partitions
grub rescue> ls (hd0,gpt1)/
grub rescue> ls (hd0,gpt2)/
grub rescue> ls (hd0,gpt3)/

# The correct partition should contain /boot/

Permanently repairing GRUB configuration after recovery

After a successful recovery boot, repair the system:


# After booting into the repaired system
# Regenerate GRUB configuration
sudo update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-5.15.0-74-generic
Found initrd image: /boot/initrd.img-5.15.0-74-generic
done

# Reinstall GRUB2 to the Master Boot Record
sudo grub-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.

# Both steps in one (Ubuntu/Debian)
sudo dpkg-reconfigure grub-pc

GRUB installation on UEFI systems:


# Mount EFI partition (if not automatically mounted)
sudo mount /dev/sda1 /boot/efi

# Install GRUB2 for UEFI
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu

# Check EFI boot entries
sudo efibootmgr -v
BootCurrent: 0001
Boot0001* ubuntu	HD(1,GPT,12345678-1234-1234-1234-123456789abc,0x800,0x32000)/File(\EFI\ubuntu\grubx64.efi)

GRUB rescue preparation and backup strategies

Collecting emergency information (before problems occur):


# Document important system information
sudo fdisk -l > ~/grub-backup/partition-table.txt
sudo blkid > ~/grub-backup/partition-uuids.txt
sudo cp /boot/grub/grub.cfg ~/grub-backup/grub.cfg.working
sudo cp /etc/default/grub ~/grub-backup/grub-defaults.backup

# Boot partition information
df -h /boot > ~/grub-backup/boot-partition-info.txt
ls -la /boot/ > ~/grub-backup/boot-contents.txt

Creating a rescue USB with GRUB tools:


# Use Super Grub2 Disk as rescue medium
# Download from: https://www.supergrubdisk.org/
# Or create your own rescue USB with grub-mkrescue
mkdir -p ~/rescue-grub/boot/grub
cp /boot/grub/grub.cfg ~/rescue-grub/boot/grub/
grub-mkrescue -o rescue-grub.iso ~/rescue-grub/

GRUB command line debugging and troubleshooting

Detailed error diagnosis:


# Verbose mode for detailed messages
grub> set debug=all

# Display memory information
grub> lsmmap

# Hardware information
grub> lspci
grub> lsusb

# Check filesystem integrity
grub> hashsum --hash md5 /boot/grub/grub.cfg

Common GRUB error messages and their meaning:

Error Message Cause Solution
error: file '/boot/grub/i386-pc/normal.mod' not found GRUB modules missing Reinstall modules
error: disk 'hd0,gpt2' not found Hard drive not detected Check hardware connection
error: no such partition Partition does not exist Check partition table
error: out of disk /boot partition full Free up space, delete old kernels
error: attempt to read or write outside of disk Defective hard drive Replace hardware

GRUB recovery workflow


System does not start                                           
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ grub rescue> prompt appears (minimal environment)            │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Diagnosis: 'ls' to identify partitions                       │
│ 'ls (hd0,gpt2)/' -> Finds /boot/vmlinuz and /boot/grub/     │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Set root & prefix:                                          │
│   set root=(hd0,gpt2)                                       │
│   set prefix=(hd0,gpt2)/boot/grub                           │
│   insmod normal && normal                                   │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ Manual boot or re-install:                                   │
│   linux /boot/vmlinuz-... root=/dev/sda2 rw                 │
│   initrd /boot/initrd.img-... && boot                       │
│   -> After boot: sudo update-grub && sudo grub-install       │
└─────────────────────────────────────────────────────────────┘

Important safety notes for GRUB recovery:

  • Data backup: Never perform GRUB repairs without a current backup
  • Keep live system ready: USB stick with Linux live system for emergencies
  • Don't panic: GRUB problems are almost always repairable as long as the hard drive works
  • Respect root privileges: Many recovery operations require administrator rights
  • Check hardware: Persistent GRUB problems can indicate hardware defects

💡 You will need this later to: solve boot problems independently without relying on external help, test various boot parameters for troubleshooting, repair broken GRUB installations, and quickly have a functional system in emergency situations. The GRUB command line is one of the most important recovery tools for Linux administrators and often saves the day when all other methods fail.

Practice tip: Practice the GRUB recovery commands in a safe environment (virtual machine) before using them on a production system. The command syntax takes some getting used to and small typos can cause additional problems.

Systemd-boot as an alternative

Systemd-boot (formerly gummiboot) is a modern, minimalist UEFI boot manager developed as a lean alternative to GRUB2. While GRUB2 is a complex, feature-rich system, systemd-boot focuses on simplicity and speed. As a Linux administrator, you should know systemd-boot, as it is available as an option on many modern distributions like Arch Linux, Fedora, and new Ubuntu variants.

Systemd-boot works exclusively on UEFI systems and uses native UEFI functions for boot management. It does not replace the entire boot process like GRUB2, but acts as an elegant mediator between the UEFI firmware and the Linux kernel. This philosophy makes systemd-boot significantly faster and less error-prone than traditional bootloaders.

What distinguishes systemd-boot from GRUB2

Understanding architectural differences:

Systemd-boot uses a completely different approach than GRUB2. Instead of a multi-stage loading process with various images, systemd-boot directly loads EFI applications from the EFI System Partition. It is itself an EFI application and uses standardized UEFI interfaces for hardware access and filesystem operations.

GRUB2 brings its own filesystem drivers and can read various partition types. Systemd-boot, on the other hand, relies completely on the UEFI firmware and can only directly read FAT32 filesystems (EFI System Partition). This makes systemd-boot simpler, but also less flexible.

Filesystem requirements:


# Systemd-boot requires specific partition structure
sudo fdisk -l /dev/sda
Device       Start      End  Sectors  Size Type
/dev/sda1     2048   1050623  1048576  512M EFI System      

# Systemd-boot runs here
/dev/sda2  1050624  69273599 68222976 32.5G Linux filesystem 

# Root partition (any FS)
# EFI System Partition must be FAT32
sudo file -s /dev/sda1
/dev/sda1: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "mkfs.fat", sectors/cluster 8, Media descriptor 0xf8, sectors/track 32, heads 64, hidden sectors 2048, sectors 1048576 (volumes > 32 MB), FAT (32 bit)

Advantages and disadvantages in direct comparison

Systemd-boot advantages:

Aspect Systemd-boot GRUB2
Boot speed 200-500ms 1-3 seconds
Complexity Minimal (~1000 lines of code) High (>100,000 lines of code)
Error-proneness Low Medium to high
UEFI integration Native Via compatibility layer
Configuration Simple text files Complex script generation
Memory usage <1 MB 2-5 MB
Maintenance effort Minimal Regular updates needed

Systemd-boot disadvantages:

Limitation Impact Workaround
UEFI only Does not work on BIOS systems Use GRUB2 for legacy systems
FAT32 only Kernels must be stored on ESP Create separate /boot partition
No script language No complex boot logics Configure boot entries statically
Limited recovery Fewer emergency options Keep external recovery medium ready

When systemd-boot is the better choice

Ideal use cases:

Modern desktop systems:

Systemd-boot is excellently suited for modern desktop installations with UEFI firmware. The fast boot times and simple configuration make it an attractive alternative for users who don't need complex multi-boot scenarios.

Servers with standardized images:

In containerized or cloud-native environments where servers are deployed with pre-configured images, systemd-boot offers advantages through its simplicity and reliability. The reduced complexity minimizes potential boot problems.

Embedded systems and IoT:

For embedded Linux systems, systemd-boot is often the better choice because it consumes fewer resources and requires less maintenance. Deterministic boot times are important in industrial applications.

Single-distribution systems:

If you only use one Linux distribution without Windows dual-boot, systemd-boot provides all needed functions without the complexity of GRUB2.

🔧 Practical example: Systemd-boot installation and configuration

Check prerequisites:


# Verify UEFI system
ls /sys/firmware/efi
config_table  efivars  fw_platform_size  fw_vendor  runtime  runtime-map  systab  vars

# Identify EFI System Partition
sudo fdisk -l | grep EFI
/dev/sda1  2048 1050623 1048576  512M EFI System

# Mount ESP (if not automatically mounted)
sudo mkdir -p /boot/efi
sudo mount /dev/sda1 /boot/efi

Install systemd-boot:


# Install systemd-boot to the EFI System Partition
sudo bootctl install
Created "/boot/efi/EFI/systemd".
Created "/boot/efi/EFI/BOOT".
Created "/boot/efi/loader".
Created "/boot/efi/loader/entries".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/efi/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/efi/EFI/BOOT/BOOTX64.EFI".

# Verify installation
sudo bootctl status
System:
	 Firmware: UEFI 2.70 (American Megatrends 5.17)
  Secure Boot: disabled
   Setup Mode: user
 Current Boot: BOOT0001 (Linux Boot Manager)

Boot Loader:
	  Product: systemd-boot 250.3-7ubuntu1
	 Features: ✓ Boot counting
			   ✓ Menu timeout
			   ✓ One-shot menu timeout
			   ✓ Default entry selection
			   ✓ One-shot entry selection
			   ✓ Support for XBOOTLDR partition
			   ✓ Support for passing random seed to OS
			   ✓ Load drop-in drivers

Understanding systemd-boot configuration

Loader main configuration:


# Create main configuration file
sudo nano /boot/efi/loader/loader.conf

# Example configuration:
default      ubuntu.conf
timeout      3
console-mode max
editor       no

Configuration parameters explained:

Parameter Values Meaning
default Entry name Default boot entry
timeout Seconds Menu wait time (0 = no menu)
console-mode keep/max/auto Terminal resolution
editor yes/no Boot parameters editable
auto-entries yes/no Automatic EFI detection
auto-firmware yes/no Show firmware setup option

Configure boot entries:


# Create boot entry for Ubuntu
sudo nano /boot/efi/loader/entries/ubuntu.conf

# Example boot entry:
title      Ubuntu 22.04 LTS
linux      /EFI/ubuntu/vmlinuz-5.15.0-74-generic
initrd     /EFI/ubuntu/initrd.img-5.15.0-74-generic
options    root=UUID=12345678-1234-1234-1234-123456789abc ro quiet splash

# Additional debug entry
sudo nano /boot/efi/loader/entries/ubuntu-debug.conf

title      Ubuntu 22.04 LTS (Debug)
linux      /EFI/ubuntu/vmlinuz-5.15.0-74-generic
initrd     /EFI/ubuntu/initrd.img-5.15.0-74-generic
options    root=UUID=12345678-1234-1234-1234-123456789abc ro debug nosplash systemd.log_level=debug

Copying kernel images to the EFI System Partition

Manual kernel installation:

Since systemd-boot can only read the EFI System Partition, kernels and initrd images must be copied there:


# Create directory structure
sudo mkdir -p /boot/efi/EFI/ubuntu

# Copy current kernel images
sudo cp /boot/vmlinuz-5.15.0-74-generic /boot/efi/EFI/ubuntu/
sudo cp /boot/initrd.img-5.15.0-74-generic /boot/efi/EFI/ubuntu/

# Set up kernel update hook (Ubuntu/Debian)
sudo nano /etc/kernel/postinst.d/zz-update-systemd-boot

#!/bin/bash
# Automatically copy kernels to ESP
version="$1"
cp "/boot/vmlinuz-${version}" "/boot/efi/EFI/ubuntu/"
cp "/boot/initrd.img-${version}" "/boot/efi/EFI/ubuntu/"

sudo chmod +x /etc/kernel/postinst.d/zz-update-systemd-boot

Systemd-boot management commands

Important bootctl commands:


# Display status and configuration
sudo bootctl status

# List boot entries
sudo bootctl list
Available boot entries:
		ubuntu.conf (default)
		ubuntu-debug.conf

# Update systemd-boot
sudo bootctl update
Updated "/boot/efi/EFI/systemd/systemd-bootx64.efi".
Updated "/boot/efi/EFI/BOOT/BOOTX64.EFI".

# Generate random seed for kernel
sudo bootctl random-seed

# ESP partition information
sudo bootctl --print-esp-path
/boot/efi

sudo bootctl --print-boot-path
/boot/efi

Migrating from GRUB2 to systemd-boot

⚠️ Important note: This migration should only be performed on UEFI systems and with a current backup.

Step-by-step migration:


# Step 1: Create system backup
sudo rsync -av /boot/ ~/boot-backup/
sudo cp /etc/fstab ~/fstab.backup

# Step 2: Identify and mount EFI System Partition
lsblk -f | grep vfat
└─sda1 vfat   FAT32 ESP    1234-5678    450,8M     7% /boot/efi

# Step 3: Install systemd-boot
sudo bootctl install

# Step 4: Remove GRUB from UEFI boot manager
sudo efibootmgr -v | grep -i grub
Boot0000* ubuntu	HD(1,GPT,12345678-1234-1234-1234-123456789abc,0x800,0x32000)/File(\EFI\ubuntu\grubx64.efi)

sudo efibootmgr -b 0000 -B  

# Delete GRUB entry
# Step 5: Configure boot entries (as shown above)
# Step 6: Perform test reboot
sudo reboot

Common systemd-boot problems and solutions

Problem 1: Boot entries not displayed


# Check cause: loader.conf syntax
sudo cat /boot/efi/loader/loader.conf

# Make sure no BOM (Byte Order Mark) is present
# Validate boot entries
sudo bootctl list

# Should show all .conf files from /boot/efi/loader/entries/

Problem 2: Kernel images not found


# Check paths in boot entries
ls -la /boot/efi/EFI/ubuntu/

# Kernel files must be here, not in /boot/
# Use relative paths (without leading /)
linux      /EFI/ubuntu/vmlinuz-5.15.0-74-generic  

# Correct
linux      /boot/vmlinuz-5.15.0-74-generic        

# Wrong for systemd-boot

Problem 3: Systemd-boot does not start


# Check UEFI boot order
sudo efibootmgr -v

# Systemd-boot should have first priority
# Check EFI System Partition for errors
sudo fsck.fat -v /dev/sda1

# Reinstall systemd-boot
sudo bootctl install --force

Systemd-boot vs. GRUB2 boot flow


UEFI Firmware Boot Decision                                    
                                │                              
                ┌───────────────┴───────────────┐              
                ▼                               ▼              
┌─────────────────────────────┐   ┌───────────────────────────┐
│ systemd-boot (Simple EFI)   │   │ GRUB2 (Modular / Complex) │
├─────────────────────────────┤   ├───────────────────────────┤
│ • Reads ESP (/boot/efi/)    │   │ • Own FS drivers          │
│ • Entries in /loader/       │   │ • /boot/grub/grub.cfg     │
│ • Fast (200-500ms)          │   │ • Multi-Boot & Themes     │
│ • Low-maintenance & minimal │   │ • High flexibility        │
└─────────────────────────────┘   └───────────────────────────┘

Systemd-boot for various distributions

Arch Linux:


# Arch Linux supports systemd-boot natively
sudo pacman -S systemd
sudo bootctl install

# Include microcode updates
sudo pacman -S intel-ucode  

# or amd-ucode
# Add to boot entry:
initrd     /intel-ucode.img
initrd     /initramfs-linux.img

Fedora:


# Fedora can use systemd-boot
sudo dnf install systemd-boot
sudo bootctl install

# Configure automatic kernel updates
sudo nano /etc/kernel/install.conf
layout=bls

Ubuntu/Debian:


# Ubuntu from 20.04 supports systemd-boot
sudo apt install systemd-boot
sudo bootctl install

# Integration with apt hooks for automatic updates

Important considerations before switching

Backup strategy is essential:

Before switching from GRUB2 to systemd-boot, make sure you have a complete recovery strategy:


# Complete system backup
sudo dd if=/dev/sda of=/backup/full-disk-backup.img bs=64K

# Save EFI variables
sudo efibootmgr -v > ~/efi-boot-entries.backup

# Save GRUB configuration
sudo cp -r /boot/grub/ ~/grub-backup/
sudo cp /etc/default/grub ~/grub-backup/

Check hardware compatibility:


# Check Secure Boot status (can cause problems)
sudo mokutil --sb-state

# Test UEFI features
sudo bootctl status | grep Features
Features: ✓ Boot counting
		  ✓ Menu timeout
		  ✓ One-shot menu timeout

💡 You will need this later to: optimally configure modern UEFI systems, minimize boot times, create low-maintenance boot environments, and choose the best boot solution for specific requirements. Systemd-boot is particularly valuable in containerized environments, embedded systems, and modern desktop installations where simplicity and speed are more important than maximum flexibility.

⚠️ Decision aid: Use systemd-boot if you run a modern UEFI system with a single Linux distribution and value fast boot times and simple maintenance. Stay with GRUB2 if you manage multi-boot systems, legacy hardware, or complex boot scenarios.

Kernel parameters and boot options

Understanding the kernel command line

The kernel command line is one of the most powerful interfaces for configuring your Linux system. Parameters are passed here that determine the kernel's behavior from the very first second — before any configuration files are read or services started. As a Linux administrator, you must understand how these parameters work, because they are often the key to solving hardware problems, performance optimizations, and boot repairs.

These parameters are passed directly from the bootloader (GRUB2 or systemd-boot) to the kernel and have immediate effect. Unlike configuration files that only affect the system after a complete start, kernel parameters take effect during hardware initialization and can change fundamental system behavior.

What are kernel parameters and how do they work

Basic understanding of the kernel command line:

Kernel parameters are text arguments passed to the Linux kernel at boot. They follow a simple scheme: parameter=value or just parameter for boolean values. The kernel parses these parameters during its initialization and adjusts its behavior accordingly.


# Display current kernel command line
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro quiet splash

# Kernel parameters in structured form
$ cat /proc/cmdline | tr ' ' '\n'
BOOT_IMAGE=/boot/vmlinuz-5.15.0-74-generic
root=UUID=12345678-1234-1234-1234-123456789abc
ro
quiet
splash

Understanding parameter categories:

The Linux kernel processes different types of parameters that affect different system components:

Boot parameters (early kernel phase):

These parameters are evaluated during kernel initialization and affect basic hardware detection and memory management.

Module parameters:

Parameters for specific kernel modules can be set via the command line before the modules are loaded.

Init parameters:

Parameters passed to the init system (systemd) that influence the behavior of the first user-space processes.

Important kernel parameters at a glance

Basic system parameters:

Parameter Function Examples When to use?
root= Define root filesystem root=/dev/sda1, root=UUID=... Hard drive problems
ro Mount root filesystem read-only ro Filesystem protection, repairs
rw Mount root filesystem read-write rw Normal system use
init= Start alternative init system init=/bin/bash Emergency recovery
single Activate single-user mode single Password reset, repairs

Hardware-related parameters:

Parameter Function Examples Problem solving
nomodeset Disable graphics modesetting nomodeset Graphics problems, black screen
acpi=off Completely disable ACPI acpi=off Hardware compatibility problems
noapic Disable APIC interrupts noapic Interrupt conflicts
pci=noacpi Disable PCI ACPI pci=noacpi PCI device problems
mem= Limit available RAM mem=2G Memory tests, defective RAM areas

Debug and diagnosis parameters:

Parameter Function Output level Purpose
debug Verbose kernel logging All debug messages Comprehensive problem diagnosis
loglevel= Set log level loglevel=7 (very detailed) Targeted debug output
ignore_loglevel Show all log messages Overrides quiet Complete boot diagnosis
initcall_debug Log init calls Function call tracing Kernel initialization problems

🔧 Practical example: Setting kernel parameters at boot time

Scenario: Your system doesn't start correctly due to graphics problems. You want to temporarily disable graphics modesetting and receive detailed debug information.

Step 1: Reach the GRUB boot menu

Show GRUB menu at system start:

  • - Press ESC key during boot (if menu is hidden)
  • - Or hold Shift key
  • - Select boot entry with arrow keys
  • - Press e to edit

Step 2: Temporarily add kernel parameters


# Original line:
linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro quiet splash

# Edited line (add parameters at end):
linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro nomodeset debug ignore_loglevel

Step 3: Perform temporary boot


# Press Ctrl+X or F10 to boot
# These changes are only valid for this boot

Step 4: Check success and configure permanently


# After successful boot, check
cat /proc/cmdline | grep nomodeset
linux   /boot/vmlinuz-5.15.0-74-generic root=UUID=12345678-1234-1234-1234-123456789abc ro nomodeset debug ignore_loglevel

# On successful boot: set parameters permanently
sudo nano /etc/default/grub

# Change GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" to:
# GRUB_CMDLINE_LINUX_DEFAULT="nomodeset quiet splash"

sudo update-grub

Setting boot parameters temporarily vs. permanently

Temporary parameter changes (GRUB editor):

Temporary changes are ideal for testing and emergency situations. They only affect the current boot process and are lost after a restart.

Advantages of temporary changes:

  • No risk to the system
  • Immediate testing possible
  • Automatic rollback on next boot
  • Ideal for experiments and diagnosis

Permanent parameter changes (GRUB configuration):


# Global parameters for all boot entries
sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX="parameter1 parameter2"

# Parameters only for normal boot entries (not recovery)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash parameter3"

# Apply configuration
sudo update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-5.15.0-74-generic
Found initrd image: /boot/initrd.img-5.15.0-74-generic
done

Difference between GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT:

Variable Scope Example parameters
GRUB_CMDLINE_LINUX All boot entries (including recovery) nomodeset acpi=off
GRUB_CMDLINE_LINUX_DEFAULT Only normal boot entries quiet splash

Understanding specific hardware parameters

Graphics-related parameters:


# Completely disable graphics modesetting
nomodeset

# Configure Intel graphics specifically
i915.modeset=0              

# Intel modesetting off
i915.enable_guc=0           

# Disable GuC firmware
i915.enable_psr=0           

# Panel Self Refresh off
# NVIDIA graphics parameters
nouveau.modeset=0           

# Disable Nouveau driver
nvidia-drm.modeset=1        

# NVIDIA DRM modesetting on
# General graphics fallbacks
vga=normal                  

# Standard VGA mode
video=1024x768              

# Set fixed resolution

Memory management parameters:


# RAM detection and management
mem=4G                      

# Limit RAM to 4GB
memmap=2G!4G                

# Reserve 2GB from 4GB address
hugepages=256              

# Reserve 256 Huge Pages
# NUMA configuration
numa=off                   

# Completely disable NUMA
numa_balancing=disable     

# Turn off NUMA balancing
# Memory corruption protection
slub_debug=FZP             

# SLUB allocator debug
page_poison=on             

# Enable memory poisoning

CPU and power management:


# CPU frequency scaling
intel_pstate=disable       

# Intel P-State driver off
processor.max_cstate=1     

# Limit C-states
idle=poll                  

# CPU never idle
# Power management
acpi=off                   

# Completely disable ACPI
apm=off                    

# APM (Advanced Power Management) off
nohz=off                   

# Disable NO-HZ kernel

Setting module parameters via kernel command line

Module parameter syntax:


# Syntax: modulename.parameter=value
e1000e.InterruptThrottleRate=3000    

# Configure network module
snd-hda-intel.model=generic          

# Set audio module model
usbcore.autosuspend=-1               

# Disable USB autosuspend

Example: Fixing network problems:


# Optimize Intel Ethernet adapter
e1000e.InterruptThrottleRate=0       

# Interrupt throttling off
e1000e.EEE=0                         

# Energy Efficient Ethernet off
# Stabilize Realtek WiFi adapter
rtw88_8821ce.disable_aspm=1          

# Disable ASPM for WiFi
rtw88_8821ce.ant_sel=2               

# Select antenna 2

Debug parameters for system diagnosis

Kernel panic analysis:


# Configure kernel panic behavior
panic=10                    

# Auto-reboot after 10 seconds
oops=panic                  

# Treat oops messages as panic
softlockup_panic=1          

# Soft lockups as panic
hung_task_panic=1           

# Hung tasks as panic

Boot process debugging:


# Detailed boot information
initcall_debug             

# Log kernel init calls
debug                      

# General debug logging
ignore_loglevel            

# Show all log levels
earlyprintk=serial         

# Early kernel messages via serial interface

Service and init debugging:


# systemd-specific parameters
systemd.log_level=debug    

# systemd debug logging
systemd.log_target=console 

# systemd logs to console
systemd.show_status=true   

# Show boot status
rd.systemd.show_status=true 

# initrd systemd status

Dangerous kernel parameters and security aspects

Parameters with security risks:

Parameter Risk Why problematic?
init=/bin/bash Root shell without password Bypasses complete authentication
single Single-user mode Root access without login
ro Read-only root System not fully usable
mem=512M Artificial RAM limit Performance degradation
acpi=off ACPI disabled No power management, overheating possible

Safe debug practices:


# Safe debug parameters (only logging, no functionality)
debug ignore_loglevel loglevel=7

# Avoid problematic parameters:
# NEVER in production environments:
init=/bin/bash              

# Security hole
root=/dev/ram0             

# Can damage system
mem=1M                     

# Makes system unusable

Kernel parameters for performance optimization

Server performance parameters:


# Optimize I/O scheduler
elevator=noop              

# Suitable for SSDs
elevator=deadline          

# For server workloads
# Optimize interrupt handling
irqpoll                    

# For interrupt problems
isolcpus=2,3               

# Reserve CPUs 2,3 for dedicated tasks

Desktop performance parameters:


# Responsive desktop experience
preempt=voluntary          

# Better desktop interactivity
transparent_hugepage=madvise 

# Optimize memory performance

Kernel parameter processing


Bootloader passes parameters to kernel                         
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 1. Kernel start: read parameters & create /proc/cmdline     │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 2. Hardware init: nomodeset, acpi=off, mem=..., console=... │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 3. Module drivers: apply module-specific options             │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 4. Init system: systemd.unit=..., single, emergency, init=  │
└─────────────────────────────────────────────────────────────┘

Common use cases for kernel parameters

Solving graphics problems:


# Black screen after boot
nomodeset video=1024x768

# NVIDIA problems with proprietary driver
nouveau.modeset=0 nvidia-drm.modeset=1

# Intel graphics instabilities
i915.enable_psr=0 i915.enable_fbc=0

Hardware compatibility problems:


# Older hardware without ACPI support
acpi=off apm=off

# USB problems on older systems
nousb usbcore.autosuspend=-1

# Interrupt conflicts on legacy hardware
noapic nolapic

Diagnosing performance problems:


# Analyze boot performance
initcall_debug printk.time=1

# Track memory leaks
slub_debug=FZPU page_poison=on

# CPU performance problems
processor.max_cstate=1 intel_idle.max_cstate=0

Common beginner mistakes with kernel parameters

Error 1: Parameters with spaces


# WRONG:
quiet splash = true

# RIGHT:
quiet splash

Error 2: Wrong syntax for module parameters


# WRONG:
e1000e:InterruptThrottleRate=3000

# RIGHT:
e1000e.InterruptThrottleRate=3000

Error 3: Non-existent parameters


# WRONG (parameter does not exist):
graphics=off

# RIGHT:
nomodeset

Error 4: Contradictory parameters


# PROBLEMATIC:
ro rw         

# Contradictory
quiet debug   

# Logically contradictory

Changing kernel parameters at runtime

Runtime parameters via /proc/sys:

Some kernel parameters can also be changed at runtime:


# Display current values
cat /proc/sys/kernel/printk
4       4       1       7

# Change temporarily
echo 7 | sudo tee /proc/sys/kernel/printk_ratelimit

# Permanently in /etc/sysctl.conf
echo "kernel.printk_ratelimit = 7" | sudo tee -a /etc/sysctl.conf

💡 You will need this later to: systematically solve hardware problems, optimize system performance, diagnose boot problems, and create specific hardware configurations. Kernel parameters are often the decisive difference between a functioning and a problematic Linux system, especially with newer or problematic hardware.

💡 Important practice tip: Keep a logbook of all kernel parameter changes you make on your systems. Note the parameters, reason for the change, and effect. This helps with future problems and when switching to new hardware.

Init systems and runlevels

The init system is the first process executed after kernel start and receives process ID 1 (PID 1). It is responsible for starting all other system services and managing the entire user space. As a Linux administrator, you must understand how init systems work, because they determine which services are started at boot and how the system switches between different operating modes.

Modern Linux distributions primarily use systemd as the init system, while older systems still use the traditional SysVinit. These two systems have fundamentally different philosophies and configuration approaches, but both serve the same purpose: they bring your system from a bare kernel to a fully functional operating system.

Systemd vs. SysVinit compared

The traditional SysVinit system:

SysVinit was the standard in Unix and Linux systems for decades. It works on a sequential principle: services are started one after another, based on their number in the runlevel directories. A service can only start after all services with lower numbers have been successfully started.

SysVinit organizes services in different runlevels (0-6), where each runlevel corresponds to a specific system state. The system can only be in one runlevel at a time, and switching between runlevels is done by stopping and starting corresponding services.

The modern systemd system:

Systemd revolutionized the init system through parallel service starts and an event-driven design. Instead of starting services sequentially, systemd analyzes dependencies between services and starts all independent services simultaneously. This significantly reduces boot times.

Systemd uses targets instead of runlevels. A target is a collection of services and other targets needed for a specific system state. Unlike runlevels, multiple targets can be active simultaneously, enabling more flexible system configurations.

Practical differences at a glance:

Aspect SysVinit systemd
Service start Sequential Parallel
Configuration Shell scripts Unit files
Dependencies Numerical order Explicit dependencies
Boot time Slow Fast
Logging Separate log files Central journal
Service management service command systemctl command

Understanding boot targets (multi-user, graphical, etc.)

The most important systemd targets:

Systemd targets roughly correspond to traditional runlevels, but offer more flexibility. Each target defines a specific system configuration with certain services.


# Display current target
systemctl get-default
graphical.target

# List all available targets
systemctl list-units --type=target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION
basic.target          loaded active active Basic System
bluetooth.target      loaded active active Bluetooth
cryptsetup.target     loaded active active Local Encrypted Volumes
graphical.target      loaded active active Graphical Interface
multi-user.target     loaded active active Multi-User System
network.target        loaded active active Network

Understanding target hierarchy:


poweroff.target (Runlevel 0)
	↑
rescue.target (Runlevel 1)
	↑
multi-user.target (Runlevel 3)
	↑
graphical.target (Runlevel 5)

Detailed target descriptions:

Target Corresponds to runlevel Description Typical services
poweroff.target 0 Shut down system Only shutdown services
rescue.target 1 Single-user mode Basic services, no network
multi-user.target 3 Multi-user system without GUI SSH, network, server services
graphical.target 5 Full desktop system Display manager, desktop environment
reboot.target 6 Restart system Reboot services

🔧 Practical example: Booting into single-user mode

Scenario: You have forgotten the root password and need to reset it. You need access to single-user mode for administrative repairs.

Method 1: Via GRUB boot parameters


# In GRUB menu press 'e' and navigate to the linux line
# Add at the end of the line:
linux [...] ro systemd.unit=rescue.target

# Or traditional parameter:
linux [...] ro single

# Or direct bash access:
linux [...] ro init=/bin/bash

Method 2: Switch target at runtime


# Check current target
systemctl get-default
graphical.target

# Immediately switch to rescue mode
sudo systemctl isolate rescue.target

# System will stop all running services and only keep basic services
# You get a root shell without login

Working in rescue mode:


# Mount root filesystem writable
# mount -o remount,rw /
# Set new root password
# passwd root
New password: [enter_new_password]
Retype new password: [confirm_new_password]
passwd: password updated successfully

# Return to normal multi-user mode
# systemctl isolate multi-user.target
# Or directly to graphical interface
# systemctl isolate graphical.target

Managing and configuring systemd targets

Changing the default target:


# Display current default target
systemctl get-default
graphical.target

# Change default target to server mode (no desktop)
sudo systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.

# Verify change
systemctl get-default
multi-user.target

# Back to graphical desktop
sudo systemctl set-default graphical.target

Understanding target-dependent services:


# Display services of a target
systemctl list-dependencies multi-user.target
multi-user.target
├─dbus.service
├─getty.target
├─systemd-ask-password-wall.path
├─systemd-logind.service
├─systemd-update-utmp-runlevel.service
└─basic.target
  ├─-.mount
  ├─tmp.mount
  ├─sysinit.target
  └─[further services...]

# Graphical target additional dependencies
systemctl list-dependencies graphical.target | head -10
graphical.target
├─accounts-daemon.service
├─gdm.service
├─systemd-update-utmp-runlevel.service
├─udisks2.service
└─multi-user.target
  ├─dbus.service
  ├─getty.target

Legacy runlevel compatibility

Runlevel commands in systemd:

Systemd provides compatibility for traditional runlevel commands, but translates them internally to targets.


# Traditional command (still works)
runlevel
N 5

# Systemd equivalent
systemctl get-default
graphical.target

# Change runlevel (traditional)
sudo init 3

# Systemd equivalent (recommended)
sudo systemctl isolate multi-user.target

Runlevel-to-target mapping:

Traditional runlevel Systemd target System state
init 0 systemctl poweroff Shut down system
init 1 systemctl rescue Single-user/rescue mode
init 2 systemctl isolate multi-user.target Multi-user without network
init 3 systemctl isolate multi-user.target Multi-user with network
init 5 systemctl isolate graphical.target Graphical multi-user mode
init 6 systemctl reboot Restart system

Pitfall: Mixing runlevel concepts

Common beginner mistake:

Many Linux beginners mix the concepts of traditional runlevels and modern systemd targets, leading to confusion and configuration errors.


# OUTDATED approach (works, but not recommended):
sudo update-rc.d my-service defaults 80 20  

# SysVinit style
sudo chkconfig my-service on                

# Red Hat SysVinit style
# MODERN systemd approach (recommended):
sudo systemctl enable my-service.service
sudo systemctl start my-service.service

Managing systemd services correctly:


# Check service status
systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2025-07-20 10:30:15 CEST; 1h 15min ago
	 Docs: man:sshd(8)
		   man:sshd_config(5)
  Process: 1234 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
 Main PID: 1235 (sshd)
	Tasks: 1 (limit: 4915)

# Enable service at boot
sudo systemctl enable ssh.service
Created symlink /etc/systemd/system/multi-user.target.wants/ssh.service → /lib/systemd/system/ssh.service.

# Start service immediately
sudo systemctl start ssh.service

# Stop service
sudo systemctl stop ssh.service

# Restart service
sudo systemctl restart ssh.service

Creating and using custom targets

Custom target for special use cases:


# Create custom target file
sudo nano /etc/systemd/system/kiosk.target

[Unit]
Description=Kiosk Mode
Requires=multi-user.target
Conflicts=rescue.service rescue.target
After=multi-user.target
AllowIsolate=yes

[Install]
WantedBy=multi-user.target

Define kiosk application as service:


sudo nano /etc/systemd/system/kiosk-app.service

[Unit]
Description=Kiosk Application
After=graphical-session.target
Wants=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/bin/chromium-browser --kiosk --no-sandbox http://internal-dashboard.local
Restart=always
User=kiosk

[Install]
WantedBy=kiosk.target

Activate custom target:


# Load target and service
sudo systemctl daemon-reload

# Set target as default
sudo systemctl set-default kiosk.target

# Immediately switch to kiosk target
sudo systemctl isolate kiosk.target

Systemd target hierarchy


Kernel initiates systemd (PID 1) -> Target chain               
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ sysinit.target (filesystems, swap, crypto, low-level init)  │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ basic.target (sockets, timers, paths, basic services)       │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                ┌──────────────┴──────────────┐                
                ▼                             ▼                
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ multi-user.target (Server)  │ │ graphical.target (Desktop)  │
│ CLI, SSH, DB, Daemons       │ │ Display Manager, GUI, X11   │
└─────────────────────────────┘ └─────────────────────────────┘

Practical tips for target management

Temporarily changing boot target:


# Boot into different mode once (GRUB parameter)
systemd.unit=multi-user.target    

# Only for this boot
systemd.unit=rescue.target        

# Single-user for repairs

Analyzing system services:


# Display all failed services
systemctl --failed
  UNIT                    LOAD   ACTIVE SUB    DESCRIPTION
● some-service.service    loaded failed failed Some Description

# Analyze boot time by targets
systemd-analyze critical-chain graphical.target
graphical.target @12.456s
└─multi-user.target @12.234s
  └─network.target @8.123s
	└─NetworkManager.service @6.789s +1.334s
	  └─dbus.service @6.123s
		└─basic.target @6.089s

Target switch with time delay:


# Switch to rescue target in 2 minutes
sudo systemctl isolate --job-mode=replace-irreversibly rescue.target --no-block
sleep 120 && sudo systemctl isolate rescue.target

Solving common init system problems

Problem 1: Service does not start automatically


# Check service status in detail
systemctl status my-service.service

# Check service unit file
systemctl cat my-service.service

# Enable service for automatic start
sudo systemctl enable my-service.service

# Check dependencies
systemctl list-dependencies my-service.service

Problem 2: Circular dependencies


# Identify dependency problems
systemd-analyze verify my-service.service

# Find dependency loops
systemctl list-dependencies --all | grep -C5 "loop"

# Which services belong to a target
systemctl list-units --type=service --state=failed

# Manually add services to target
sudo systemctl add-wants multi-user.target my-service.service

Important debugging note: Systemd logs are essential for error diagnosis. Use journalctl -u service-name.service for service-specific logs and journalctl -b for boot logs.

💡 You will need this later to: configure services correctly, diagnose boot problems, switch system modes according to requirements, and create custom boot configurations for special use cases. Understanding init systems and targets is fundamental for professional Linux administration and for scenarios like server deployments, kiosk systems, or emergency recovery.

Initramfs and the early boot phase

The Initial RAM File System (initramfs) is a critical component of the Linux boot process that bridges the gap between kernel start and actual system start. This temporary mini Linux environment enables the kernel to activate complex storage configurations like encrypted hard drives, RAID arrays, or LVM volumes before the actual root filesystem becomes available.

As a Linux administrator, you will regularly face initramfs problems, especially during system updates, hardware changes, or with encrypted systems. A broken or missing initramfs can make your system completely unusable, while a correctly configured initramfs reliably brings even the most complex storage setups to life.

What is an initramfs and what is it for

The fundamental problem without initramfs:

The Linux kernel is modular and contains only the most essential drivers by default. Many storage drivers, filesystem modules, and encryption tools are implemented as separate modules. These modules are normally located in the /lib/modules/ directory of the root filesystem — but that's exactly where the problem lies: to load these modules, the root filesystem must already be mounted. To mount the root filesystem, these exact modules are often needed.

The initramfs solution:

Initramfs elegantly solves this chicken-and-egg problem. It is a compressed archive containing all necessary modules, tools, and scripts for the early boot phase. The bootloader loads this archive together with the kernel into main memory. The kernel unpacks the initramfs into a RAM-based filesystem structure and starts the init process contained within it.


# Examine current initramfs
ls -la /boot/initrd.img*
lrwxrwxrwx 1 root root   28 Jan 15 10:30 /boot/initrd.img -> initrd.img-5.15.0-74-generic
-rw-r--r-- 1 root root 85M Jan 15 10:30 /boot/initrd.img-5.15.0-74-generic
-rw-r--r-- 1 root root 82M Dec 10 09:15 /boot/initrd.img-5.15.0-72-generic

# Extract and examine initramfs contents
sudo mkdir -p /tmp/initramfs-extract
cd /tmp/initramfs-extract
sudo zcat /boot/initrd.img-5.15.0-74-generic | sudo cpio -idmv
ls -la
drwxr-xr-x  2 root root 4096 Jan 15 10:30 bin
drwxr-xr-x  3 root root 4096 Jan 15 10:30 conf
drwxr-xr-x  5 root root 4096 Jan 15 10:30 etc
-rwxr-xr-x  1 root root 7333 Jan 15 10:30 init
drwxr-xr-x 10 root root 4096 Jan 15 10:30 lib
drwxr-xr-x  2 root root 4096 Jan 15 10:30 run
drwxr-xr-x  2 root root 4096 Jan 15 10:30 sbin
drwxr-xr-x  3 root root 4096 Jan 15 10:30 usr

Understanding initramfs structure and components

The initramfs directory structure:


# Important directories in initramfs
find /tmp/initramfs-extract -type d -maxdepth 2
/tmp/initramfs-extract/bin          

# Basic commands
/tmp/initramfs-extract/sbin         

# System binaries
/tmp/initramfs-extract/lib          

# Shared libraries and modules
/tmp/initramfs-extract/lib/modules  

# Kernel modules
/tmp/initramfs-extract/etc          

# Minimal configuration
/tmp/initramfs-extract/conf         

# initramfs-specific configs
/tmp/initramfs-extract/scripts      

# Hook scripts for various phases
/tmp/initramfs-extract/run          

# Runtime directory
/tmp/initramfs-extract/usr/lib      

# Additional libraries

Critical initramfs components:

The /init script is the heart of the initramfs. It is started as the first process (PID 1) in the initramfs environment and orchestrates the entire early boot process:


# Examine the central init script
sudo head -20 /tmp/initramfs-extract/init
#!/bin/sh

echo "Loading, please wait..."
export PATH=/sbin:/bin:/usr/bin:/usr/sbin

# Set modprobe env
export MODPROBE_OPTIONS="-qb"

# Export relevant variables
export ROOT=
export ROOTDELAY=
export ROOTFLAGS=
export ROOTFSTYPE=
export IP=
export BOOT=
export BOOTIF=
export UBIMTD=
export break=
export init=/sbin/init
export quiet=n
export readonly=y
export rootmnt=/root

Kernel module management:


# List modules contained in initramfs
find /tmp/initramfs-extract/lib/modules -name "*.ko" | head -10
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/crypto/aes-x86_64.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/crypto/cbc.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/drivers/ata/ahci.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/drivers/ata/libata.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/drivers/md/dm-mod.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/drivers/md/dm-crypt.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/fs/ext4/ext4.ko
/tmp/initramfs-extract/lib/modules/5.15.0-74-generic/kernel/fs/mbcache.ko

# Module dependencies
cat /tmp/initramfs-extract/lib/modules/5.15.0-74-generic/modules.dep | head -5
kernel/arch/x86/crypto/aes-x86_64.ko:
kernel/crypto/cbc.ko: kernel/crypto/crypto_algapi.ko
kernel/crypto/dm-crypt.ko: kernel/drivers/md/dm-mod.ko kernel/crypto/cbc.ko

Generating and customizing initramfs

Automatic initramfs generation:

Modern Linux distributions automatically generate initramfs images during kernel installation or updates. This process analyzes your system and includes only the actually needed modules and tools.


# Ubuntu/Debian: update-initramfs
sudo update-initramfs -c -k $(uname -r)
update-initramfs: Generating /boot/initrd.img-5.15.0-74-generic

# Update all available kernel versions
sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-5.15.0-74-generic
update-initramfs: Generating /boot/initrd.img-5.15.0-72-generic

# Red Hat/Fedora: dracut
sudo dracut --force /boot/initramfs-$(uname -r).img $(uname -r)

Customizing initramfs configuration:


# Ubuntu/Debian initramfs configuration
sudo nano /etc/initramfs-tools/initramfs.conf

# Important configuration options:
MODULES=most                    

# Which modules to include (most/dep/list)
BUSYBOX=auto                   

# Use BusyBox for minimal shell
COMPRESS=gzip                  

# Compression algorithm
UMASK=0022                     

# File permissions in initramfs
# Explicitly add modules
echo "dm-crypt" | sudo tee -a /etc/initramfs-tools/modules
echo "aes-x86_64" | sudo tee -a /etc/initramfs-tools/modules

# Apply configuration
sudo update-initramfs -u -k $(uname -r)

🔧 Practical example: Initramfs for encrypted hard drive

Scenario: You have set up hard drive encryption after the fact and need to configure initramfs so it can unlock the encrypted partition at boot.

Step 1: Set up encryption (simplified)


# Backup current configuration
sudo cp /etc/initramfs-tools/initramfs.conf /etc/initramfs-tools/initramfs.conf.backup

# Add crypto modules to initramfs
sudo nano /etc/initramfs-tools/modules

# Add the following lines:
aes
aes-x86_64
dm-crypt
sha256
sha512

Step 2: Include cryptsetup tools


sudo nano /etc/initramfs-tools/conf.d/cryptsetup
CRYPTSETUP=y

# Or install cryptsetup-initramfs package
sudo apt install cryptsetup-initramfs

Step 3: Regenerate initramfs with encryption support


# Generate new initramfs
sudo update-initramfs -c -k $(uname -r) -v
Building cpio /boot/initrd.img-5.15.0-74-generic.new initramfs
Adding module /lib/modules/5.15.0-74-generic/kernel/crypto/aes-x86_64.ko
Adding module /lib/modules/5.15.0-74-generic/kernel/crypto/dm-crypt.ko
Adding module /lib/modules/5.15.0-74-generic/kernel/drivers/md/dm-mod.ko
Adding binary /sbin/cryptsetup
Adding binary /sbin/dmsetup
Adding library /lib/x86_64-linux-gnu/libcryptsetup.so.12

# Check generated initramfs
sudo lsinitramfs /boot/initrd.img-$(uname -r) | grep -E "(crypt|dm-)"
sbin/cryptsetup
sbin/dmsetup
lib/modules/5.15.0-74-generic/kernel/crypto/dm-crypt.ko
lib/modules/5.15.0-74-generic/kernel/drivers/md/dm-mod.ko

Step 4: Set boot parameters for encryption


# Configure GRUB for encrypted root partition
sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda2:cryptroot root=/dev/mapper/cryptroot"

sudo update-grub

Understanding initramfs hooks and scripts

Hook system of initramfs-tools:

The initramfs-tools system uses various hook points to enable modular functionality:


# Hook directories and their functions
ls -la /usr/share/initramfs-tools/hooks/
total 48
drwxr-xr-x 2 root root 4096 Jan 15 10:30 .
drwxr-xr-x 6 root root 4096 Jan 15 10:30 ..
-rwxr-xr-x 1 root root 1892 Dec  8 14:22 cryptsetup    

# Encryption
-rwxr-xr-x 1 root root 2103 Dec  8 14:22 lvm2          

# LVM support
-rwxr-xr-x 1 root root 1456 Dec  8 14:22 mdadm         

# Software RAID
-rwxr-xr-x 1 root root 1234 Dec  8 14:22 resume        

# Hibernation support

ls -la /usr/share/initramfs-tools/scripts/
drwxr-xr-x 2 root root 4096 Jan 15 10:30 init-premount   

# Before root mount
drwxr-xr-x 2 root root 4096 Jan 15 10:30 init-bottom     

# After root mount
drwxr-xr-x 2 root root 4096 Jan 15 10:30 local-top       

# Local storage activation
drwxr-xr-x 2 root root 4096 Jan 15 10:30 local-premount  

# Before local mount
drwxr-xr-x 2 root root 4096 Jan 15 10:30 local-bottom    

# After local mount

Creating a custom hook:


# Create own hook for special hardware
sudo nano /etc/initramfs-tools/hooks/custom-hardware

#!/bin/sh
PREREQ=""
prereqs()
{
	echo "$PREREQ"
}

case $1 in
prereqs)
	prereqs
	exit 0
	;;
esac

. /usr/share/initramfs-tools/hook-functions

# Copy special firmware files
copy_file firmware /lib/firmware/custom-device.fw
copy_file firmware /lib/firmware/custom-device.bin

# Add special modules
manual_add_modules custom-driver

# Make executable
sudo chmod +x /etc/initramfs-tools/hooks/custom-hardware

Debugging and troubleshooting initramfs problems

Enabling initramfs debug mode:


# Enable debug information in initramfs
sudo nano /etc/initramfs-tools/initramfs.conf

# Change line:
MODULES=most

# to:
MODULES=most

# and add:
VERBOSE=y

# Boot parameter for initramfs debugging
# Add to GRUB command line:
break=init          

# Stop before init script
break=mount         

# Stop before root mount
break=bottom        

# Stop before handover to real system
debug               

# Verbose output

Diagnosing common initramfs problems:

Problem Symptom Diagnosis Solution
Missing modules "Cannot find root device" Check modules in initramfs Add modules to /etc/initramfs-tools/modules
Wrong UUID "Waiting for root filesystem" /proc/cmdline vs. /etc/fstab Correct UUID in GRUB configuration
Encryption error "cryptsetup failed" Crypto modules missing Install cryptsetup-initramfs
LVM problems "Volume group not found" LVM tools missing Include lvm2 in initramfs

What you need later for encrypted systems

Why encryption requires initramfs:

On unencrypted systems, the kernel can directly mount the root filesystem. On encrypted systems, however, the encryption must first be unlocked before the filesystem becomes readable. This unlocking requires:

  • Cryptsetup tools to unlock LUKS containers
  • Device Mapper modules for virtual block devices
  • Crypto modules for encryption and decryption
  • Password input before the actual system start

# Encrypted system: initramfs dependencies
lsinitramfs /boot/initrd.img-$(uname -r) | grep -E "(crypt|dm-|aes)" | head -10
sbin/cryptsetup
sbin/dmsetup
lib/x86_64-linux-gnu/libcryptsetup.so.12
lib/x86_64-linux-gnu/libdevmapper.so.1.02
lib/modules/5.15.0-74-generic/kernel/crypto/aes-x86_64.ko
lib/modules/5.15.0-74-generic/kernel/crypto/dm-crypt.ko
lib/modules/5.15.0-74-generic/kernel/drivers/md/dm-mod.ko

Encrypted boot process in detail:

  • 1. Kernel starts, loads initramfs
  • 2. initramfs activates dm-crypt modules
  • 3. cryptsetup prompt appears: "Please unlock disk"
  • 4. After password input: LUKS container is unlocked
  • 5. Device Mapper creates /dev/mapper/cryptroot
  • 6. Root filesystem is mounted from /dev/mapper/cryptroot
  • 7. Switch to real root system

Advanced initramfs configurations

Multi-storage setup (RAID + LVM + encryption):


# Enable complex storage setup in initramfs
sudo nano /etc/initramfs-tools/modules

# RAID modules:
raid1
raid5
raid6
md-mod

# LVM modules:
dm-mod
dm-snapshot
dm-mirror

# Encryption modules:
dm-crypt
aes-x86_64
sha256

# Include all necessary tools
sudo apt install mdadm lvm2 cryptsetup-initramfs

# Generate initramfs for complex setup
sudo update-initramfs -c -k $(uname -r) -v

Network boot support in initramfs:


# Network modules for PXE boot or NFS root
sudo nano /etc/initramfs-tools/modules

# Add network drivers:
e1000e
r8169
ath9k

# Enable NFS tools
sudo nano /etc/initramfs-tools/initramfs.conf
BOOT=nfs
NFSROOT=auto

Initramfs boot flow


Kernel loaded & started                                          
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 1. Unpack initramfs to RAM disk -> /init becomes PID 1      │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 2. Load storage drivers: SATA, NVMe, RAID, DM-Crypt, LVM   │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 3. Unlock root filesystem (LUKS) & mount to /sysroot        │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
┌─────────────────────────────────────────────────────────────┐
│ 4. Switch-root (pivot_root) -> Handover to /sbin/init       │
└──────────────────────────────┬──────────────────────────────┘
                               │                               
                               ▼                               
                  Real Linux system starts                     

Observing initramfs security aspects

Security risks from broken initramfs:

A compromised or misconfigured initramfs can pose significant security risks:


# Check initramfs permissions
ls -la /boot/initrd.img*
-rw-r--r-- 1 root root 85M Jan 15 10:30 /boot/initrd.img-5.15.0-74-generic

# WRONG permissions (security risk):
-rw-rw-rw- 1 root root 85M Jan 15 10:30 /boot/initrd.img-5.15.0-74-generic

# Set correct permissions
sudo chmod 644 /boot/initrd.img*
sudo chown root:root /boot/initrd.img*

Secure initramfs practices:

  • 1. Never embed passwords in initramfs scripts
  • 2. Use minimal module sets with MODULES=dep instead of most
  • 3. Regular updates of initramfs for security patches
  • 4. Backup of working initramfs before changes

# Secure initramfs backup routine
sudo cp /boot/initrd.img-$(uname -r) /boot/initrd.img-$(uname -r).backup.$(date +%Y%m%d)
sudo update-initramfs -u -k $(uname -r)

# If problems: sudo cp /boot/initrd.img-$(uname -r).backup.$(date +%Y%m%d) /boot/initrd.img-$(uname -r)

Optimizing initramfs performance

Reducing size and load time:


# Check current initramfs size
du -sh /boot/initrd.img*
85M	/boot/initrd.img-5.15.0-74-generic
82M	/boot/initrd.img-5.15.0-72-generic

# Only include needed modules
sudo nano /etc/initramfs-tools/initramfs.conf

# Change from:
MODULES=most

# to:
MODULES=dep

# Use better compression
COMPRESS=xz

# Generate optimized initramfs
sudo update-initramfs -c -k $(uname -r)
du -sh /boot/initrd.img-$(uname -r)
52M	/boot/initrd.img-5.15.0-74-generic

# Significantly smaller through dep mode and xz compression

Important note: A broken initramfs can make your system completely unusable. Always test initramfs changes first in a virtual environment or keep a working backup ready. Boot problems caused by broken initramfs are often only repairable via live systems.

💡 You will need this later to: install and manage encrypted Linux systems, activate RAID and LVM configurations at boot, systematically diagnose storage problems, and create custom boot environments for special hardware requirements. Initramfs knowledge is essential for every Linux administrator working with modern storage technologies.

Summary and outlook

What you have learned in this article

You have now laid the foundation for understanding Linux boot management. The six essential boot phases from power-on to the login prompt are familiar to you, and you understand the specific tasks of each phase. The interplay between hardware initialization (POST), firmware (BIOS/UEFI), and bootloader software is no longer a black box to you.

The fundamental differences between traditional BIOS systems and modern UEFI firmware have been covered in detail. You now know why UEFI is faster and more secure, but also what compatibility problems can occur during mixed operation. The practical configuration of both firmware types is familiar to you.

GRUB2 as the standard bootloader — you now master its most important aspects. The multi-stage architecture, the configuration files, and the differences between /etc/default/grub and the automatically generated grub.cfg are clear to you. You can change boot parameters, create new boot entries, and know why direct editing of grub.cfg is problematic.

The GRUB command line and recovery techniques enable you to proceed systematically even with severe boot problems. You know the most important commands for emergency diagnosis and can manually start a system even without a functioning boot configuration. The difference between grub rescue> and the normal grub> command line is known to you.

Systemd-boot as a modern alternative — you have learned about it as a lean, UEFI-native solution. The advantages and disadvantages compared to GRUB2 are clear to you, and you understand when systemd-boot is the better choice. The simpler configuration via text files in the EFI System Partition is familiar to you.

Kernel parameters and their practical application

Kernel command line parameters are no longer a mystery to you. You understand the different parameter categories and know which parameters are helpful for hardware problems, performance optimizations, or debug situations. The difference between temporary changes via the GRUB editor and permanent configurations in /etc/default/grub is clear to you.

The most important hardware-specific parameters like nomodeset, acpi=off, or mem= are known to you and you know at which symptoms you should use them. Debug parameters for systematic problem diagnosis are as familiar to you as the security aspects when setting boot parameters.

Init systems and boot targets — you have understood them as critical components for the transition from kernel to user space. The difference between traditional SysVinit and modern systemd is clear to you. You know the most important systemd targets and know how to switch between different system modes. The single-user mode for administrative repairs is familiar to you.

Initramfs — the bridge to complex storage systems

You have learned about the initramfs system as an indispensable component for modern Linux systems. You understand why this temporary boot environment is necessary and what role it plays for encrypted systems, RAID arrays, or LVM configurations. The structure of an initramfs and the most important contained components are known to you.

The generation and customization of initramfs images — you master the tools update-initramfs (Debian/Ubuntu) or dracut (Red Hat/Fedora). You know which modules are needed for specific hardware configurations and how to integrate them into the initramfs. The hook mechanisms for extended functionality are familiar to you.

Important reference tables for everyday use

Boot problem diagnosis by phases:

Boot phase Typical symptoms First diagnosis steps Common solutions
POST/Firmware Beep codes, no display Check hardware connections Replace RAM/CPU/cables
Bootloader "GRUB Rescue", "Boot device not found" Use GRUB command line Reinstall GRUB
Kernel Kernel Panic, hardware detection errors Test boot parameters Driver updates, nomodeset
initramfs "Cannot find root device" Check modules in initramfs Regenerate initramfs
Init system Services don't start Analyze journalctl Fix service dependencies

Most important boot parameters for emergencies:

Parameter Purpose Application
nomodeset Work around graphics problems Black screen after boot
single Single-user mode Password reset, repairs
init=/bin/bash Direct shell Bypass all init systems
acpi=off Hardware compatibility Older hardware, overheating
debug ignore_loglevel Complete debug output Systematic problem diagnosis

⚠️ Warning: Always create backups of your working boot configuration before making changes. A broken bootloader makes your system completely unusable. Copy /etc/default/grub and /boot/grub/grub.cfg to safe locations.

  • Check hardware compatibility: Not all boot parameters work on every hardware.
  • Keep UEFI vs. BIOS consistent: Never mix UEFI and legacy boot modes.

💡 You are now able to professionally perform Linux installations and choose the right boot configuration for your hardware and requirements. Encrypted systems, multi-boot configurations, or special hardware requirements are manageable for you.

💡 You will need this later: A solid understanding of boot management is essential when you want to work professionally as a Linux administrator, perform complex Linux installations, pass the LPIC-1 exam, or act quickly and purposefully in emergencies — because only with these fundamentals can you reliably operate servers, master deep system configurations, and efficiently handle critical failures.

Command Reference (Cheatsheet)

Command / Syntax Category Function & Description
systemd-analyze Boot analysis Shows total system start time (firmware, loader, kernel, userspace)
systemd-analyze blame Boot analysis Lists services sorted by start time
systemd-analyze critical-chain Boot analysis Shows critical path of start chain dependencies
efibootmgr -v UEFI Shows UEFI boot entries and boot order
sudo update-grub GRUB2 Regenerates /boot/grub/grub.cfg from /etc/default/grub
sudo grub-install /dev/sdX GRUB2 Installs bootloader in MBR or EFI partition
sudo update-initramfs -u -k all initramfs Updates initial RAM disk for all installed kernels
lsinitramfs /boot/initrd.img initramfs Inspects contained drivers and modules in initramfs image
systemctl get-default systemd Shows current default boot target
sudo systemctl set-default multi-user.target systemd Sets text-based multi-user target as default
sudo systemctl isolate rescue.target systemd Switches to rescue mode during running operation
journalctl -b -1 -p err Logs Shows error logs from previous system start

Further Resources

Resource Description
GNU GRUB Manual Official GRUB2 bootloader reference documentation
systemd Boot and Target Documentation Official systemd architecture and boot documentation
Linux Administration #9: System Monitoring Previous part: Performance monitoring, iostat, logs & alerts
Linux Administration #1: Fundamentals The foundation: Hardware, kernel, filesystems & permissions
All Linux Administration Articles Complete course overview of all 10 modules

Conclusion: The 10-part Linux administration masterclass in retrospect

With the understanding of boot management and system start, you have mastered the entire lifecycle of a Linux system. From the first electrical impulse through UEFI firmware, GRUB2 bootloader, kernel initialization, and initramfs to the fully loaded systemd userspace, you are now able to systematically isolate boot failures, set up emergency chroots, and specifically eliminate performance bottlenecks during system start.

💡 Practice tip: Keep a bootable USB stick with a live distribution or an ISO in the IPMI/KVM interface for every production server. Combined with the knowledge of chroot /mnt and update-grub, you can revive any broken system in just a few minutes.

Your path as a Linux administrator

With the completion of this 10-part series, you have built a solid, practical enterprise foundation:

  1. Fundamentals & system architecture: FHS, inodes, fstab & permission management.
  2. User & PAM management: Quotas, ACLs, sudoers & auditing.
  3. Process management & cgroups: Signals, priorities & resource limits.
  4. Network & firewalls: iproute2, Netplan, nmcli, DNS & nftables.
  5. Shell scripting & systemd timers: Robust automation & traps.
  6. Data backup & DR: 3-2-1 backups, rsync hardlinks & Borg.
  7. System security & hardening: SSH Ed25519, Fail2ban, AppArmor/SELinux & LUKS.
  8. Virtualization: KVM/QEMU, Libvirt, virsh, virt-install & containers.
  9. System monitoring: vmstat, iostat, journalctl & metrics.
  10. Boot management: UEFI, GRUB2, initramfs & disaster recovery.

👉 Course Overview: All Linux Administration Articles & Modules

Share & export

Export as Markdown