The Linux boot process transforms a powered-off machine into a fully functional operating system. Understanding each stage deeply allows you to troubleshoot boot failures, configure multi-boot systems, reset forgotten root passwords, and optimise startup times. RHCA candidates must know the complete boot sequence for both RHEL 6 (SysV init) and RHEL 7+ (systemd).
Overview: Six Boot Stages
When you press the power button, the machine goes through these stages in sequence:
- BIOS/UEFI — Hardware POST and boot device selection
- MBR/GPT — First sector read, bootloader stage 1 loaded
- GRUB — Full bootloader, kernel and initrd selected
- Kernel — Hardware initialisation, root filesystem mounted
- init/systemd — First user-space process, PID 1
- Run level / Target — Services started, system ready
Stage 1: BIOS (Basic Input/Output System)
BIOS is firmware stored in non-volatile memory (originally ROM, now flash) on the motherboard. It runs before any operating system software and performs the following:
POST (Power On Self Test)
POST runs a series of hardware diagnostics when the system powers on:
- Tests CPU registers and arithmetic
- Tests RAM integrity (basic memory check)
- Detects and initialises storage controllers (SATA, SAS, NVMe)
- Detects keyboard, video, USB devices
- Reads boot order from BIOS settings (CMOS)
If POST finds an error, it either beeps (beep codes) or displays an error message and halts. If POST succeeds, BIOS locates the first bootable device according to the configured boot order and reads its first sector (512 bytes for MBR).
UEFI vs BIOS
Modern systems use UEFI (Unified Extensible Firmware Interface) instead of traditional BIOS:
| Feature | Legacy BIOS | UEFI |
|---|---|---|
| Disk size limit | 2 TB (MBR) | 9.4 ZB (GPT) |
| Partition table | MBR | GPT |
| Boot partition | MBR sector 0 | EFI System Partition (ESP, FAT32) |
| Secure Boot | No | Yes (verifies bootloader signature) |
| Boot speed | Slower | Faster |
| Interface | 16-bit, text only | 32/64-bit, graphical |
Stage 2: MBR and the Bootloader Chain
The Master Boot Record is the first 512 bytes of the boot disk. BIOS loads these bytes into RAM address 0x7C00 and jumps to that address. The code in the MBR (IPL — Initial Program Loader) does one thing: find and load the second-stage bootloader (GRUB core or stage 1.5).
For GRUB 2 (current standard), the chain is:
- boot.img (446 bytes in MBR) → reads and loads core.img
- core.img (1.5 to 2 KB, stored in sectors between MBR and first partition) → loads GRUB modules from /boot filesystem
- GRUB modules (grub.cfg, kernel modules) → presents boot menu, loads kernel
This multi-stage approach allows GRUB to be much larger and more capable than the 446-byte MBR limitation would allow.
Stage 3: GRUB (Grand Unified Bootloader)
GRUB is the most widely used Linux bootloader. Its responsibilities are:
- Display a boot menu (with configurable timeout)
- Allow the user to modify kernel parameters interactively
- Load the selected kernel image into RAM
- Load the initrd (initial RAM disk) image into RAM
- Transfer control to the kernel with the boot parameters
GRUB Configuration Files
RHEL 6: /boot/grub/grub.conf (or /etc/grub.conf, a symlink)
RHEL 7: /boot/grub2/grub.cfg (auto-generated — do not edit directly)
# RHEL 7 — edit this instead:
/etc/default/grub # main options
/etc/grub.d/ # menu entry scripts
# Regenerate grub.cfg after editing:
# grub2-mkconfig -o /boot/grub2/grub.cfg
# RHEL 6 grub.conf example:
default=0 # which entry to boot (0-indexed)
timeout=5 # seconds to wait before booting
splashimage=(hd0,0)/grub/splash.xpm.gz
title Red Hat Enterprise Linux 7
root (hd0,0)
kernel /vmlinuz-3.10.0 ro root=/dev/sda1 quiet
initrd /initramfs-3.10.0.img
Key GRUB Kernel Parameters
# Common kernel boot parameters (passed via grub.cfg or at boot menu):
ro = mount root filesystem read-only initially (standard)
root=/dev/sda1 = root filesystem device
quiet = suppress most boot messages
rhgb = Red Hat graphical boot (graphical splash screen)
1 or single = boot to single user mode (RHEL 6)
rd.break = stop before pivot to real root (RHEL 7, for password reset)
selinux=0 = disable SELinux for this boot
init=/bin/bash = start bash instead of init/systemd (emergency recovery)
mem=1G = limit RAM to 1GB (for testing)
nomodeset = disable kernel mode setting (graphics troubleshooting)
Stage 4: Kernel Initialisation
When GRUB transfers control to the kernel, the kernel takes over completely. The kernel initialisation sequence:
- Decompress itself: The kernel image (vmlinuz) is compressed. It decompresses itself in RAM.
- initialise hardware: Detects CPU features, enables memory, initialises interrupt handlers, detects PCI devices.
- Mount initrd: The initrd (initial RAM disk) is a temporary compressed filesystem loaded by GRUB. The kernel mounts it as a temporary root filesystem. It contains essential drivers needed to access the real root filesystem (SCSI drivers, LVM, RAID, etc.).
- Load drivers from initrd: Uses modules in initrd to discover and initialise storage hardware.
- Mount real root filesystem: Using the drivers now loaded, finds and mounts the actual root partition (as specified by the
root=kernel parameter). - Switch root: Pivots from the initrd to the real root filesystem.
- Start PID 1: Executes the first user-space process.
initrd vs initramfs
- initrd: older approach — a compressed ext2 filesystem image mounted as a RAM disk device (
/dev/ram0) - initramfs: current approach — a cpio archive extracted directly into tmpfs. More flexible, no size limitations.
# List contents of initramfs:
# lsinitrd /boot/initramfs-$(uname -r).img
# Rebuild initramfs (after adding storage driver for new hardware):
# dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
# Check kernel and initramfs:
# ls -lh /boot/
Stage 5: init vs systemd
SysV init (RHEL 6)
SysV init was the traditional init system used in Unix systems since the 1980s. It reads /etc/inittab to determine the default run level, then executes startup scripts from /etc/rc.d/rcN.d/ directories sequentially.
# /etc/inittab (RHEL 6):
id:3:initdefault: # default run level = 3
# Run level scripts:
/etc/rc.d/rc0.d/ → halt
/etc/rc.d/rc1.d/ → single user
/etc/rc.d/rc3.d/ → multi-user CLI
/etc/rc.d/rc5.d/ → multi-user GUI
# Scripts starting with K = kill (stop)
# Scripts starting with S = start
# Number = order (e.g., S20 starts before S80)
# Check run level:
# who -r
# runlevel
systemd (RHEL 7+)
systemd is the modern init system that replaces SysV init. Its key improvements:
- Parallel startup: Services start concurrently when their dependencies are met — much faster than sequential SysV scripts.
- Socket activation: systemd can listen on sockets and start services only when the first connection arrives, reducing boot time.
- Dependency tracking: Services declare their dependencies explicitly; systemd builds a dependency graph and starts/stops services in the correct order.
- Journal integration: All service output is captured by journald — no more scattered log files.
- Cgroups integration: Each service runs in its own cgroup — resource limits, isolation, and tracking of all processes a service spawns.
# systemd unit files (service definitions):
/lib/systemd/system/ # vendor-provided (do not edit)
/etc/systemd/system/ # local overrides and custom units
# Unit file types:
.service # a daemon/process (httpd.service)
.target # group of units (multi-user.target)
.socket # socket activation
.timer # cron replacement
.mount # filesystem mounts
# Default target (equiv to default run level):
# systemctl get-default
# systemctl set-default multi-user.target # server
# systemctl set-default graphical.target # desktop
# Run level to systemd target mapping:
# 0 → poweroff.target
# 1 → rescue.target
# 3 → multi-user.target
# 5 → graphical.target
# 6 → reboot.target
Stage 6: Run Levels / Targets
Run Level | systemd Target | Description
-----------|----------------------|----------------------------------
0 | poweroff.target | Shutdown
1 | rescue.target | Single user, maintenance
2 | multi-user.target | Multi-user, no NFS (RHEL 6)
3 | multi-user.target | Full multi-user, CLI only
4 | (unused) |
5 | graphical.target | Multi-user with GUI
6 | reboot.target | Reboot
Troubleshooting Boot Problems
System Won't Boot — Diagnostic Flowchart
# Step 1: Does BIOS complete POST?
# No → hardware problem (RAM, CPU, motherboard). Check beep codes.
# Yes → continue
# Step 2: Does GRUB menu appear?
# No → MBR/bootloader corrupted
# Fix: Boot from rescue media, run grub-install /dev/sda
# Step 3: Does kernel load?
# No → kernel or initrd corrupted/missing
# Fix: Boot from rescue, reinstall kernel: rpm -ivh kernel-*.rpm
# Step 4: Does root filesystem mount?
# No → /etc/fstab error or filesystem corruption
# Fix: Boot in single user mode, run fsck, check /etc/fstab
# Step 5: Does init/systemd start?
# No → init binary missing or corrupted
# Fix: Boot with init=/bin/bash, reinstall systemd
Repairing GRUB 2
# Boot from RHEL installation media in Rescue mode
# Mount the installed system:
# chroot /mnt/sysimage
# Reinstall GRUB to MBR:
# grub2-install /dev/sda
# Regenerate GRUB config:
# grub2-mkconfig -o /boot/grub2/grub.cfg
# Exit and reboot:
# exit
# reboot
Repairing /etc/fstab Errors
# Symptom: System drops to emergency shell at boot with
# "A dependency job for local-fs.target failed"
# 1. Boot passes rd.break or enters emergency mode
# 2. Remount root as read-write:
# mount -o remount,rw /
# 3. Edit /etc/fstab:
# vi /etc/fstab
# Find the incorrect entry (wrong UUID, wrong device, wrong options)
# Comment it out or fix it
# 4. Reboot:
# systemctl reboot
Console Ports for Out-of-Band Management
Console ports allow you to access a server even when it is not booted or when the network is down. These are critical for datacenter administration:
| Vendor | Console Name | Full Name |
|---|---|---|
| Dell | iDRAC | integrated Dell Remote Access Controller |
| HP | iLO | Integrated Lights-Out |
| IBM Power | HMC | Hardware Management Console |
| Cisco UCS | CIMC | Cisco Integrated Management Controller |
# Connect to iDRAC/iLO via SSH or web browser
# Then use console redirect to access the server's virtual console
# This works even when the OS is not running (BIOS-level access)
Kernel Modules
Kernel modules are device drivers and filesystem support code that can be loaded and unloaded at runtime without rebooting. They are stored as .ko files in /lib/modules/$(uname -r)/.
# List all loaded modules:
# lsmod
# Load a module:
# modprobe dm_mirror # load with all dependencies
# insmod /path/to/module.ko # load without checking dependencies
# Remove a module:
# modprobe -r dm_mirror # remove with unused dependencies
# rmmod dm_mirror # remove specific module
# Module information:
# modinfo dm_mirror # shows description, dependencies, parameters
# View module dependencies:
# depmod # rebuild module dependency database
# cat /lib/modules/$(uname -r)/modules.dep
# Block a module from loading:
# echo "blacklist usb_storage" >> /etc/modprobe.d/blacklist.conf
# Check current kernel version:
# uname -r # version only
# uname -a # all info (arch, hostname, version)
# cat /etc/redhat-release # OS version