Modify the System
Bootloader

Modify the system bootloader

CIS126RH | RHEL System Administration 1
Mesa Community College

GRUB 2 (GRand Unified Bootloader version 2) is the bootloader used on all modern RHEL 9 systems. It is responsible for loading the Linux kernel into memory at boot. Administrators must be able to view and modify bootloader settings — adding kernel parameters, changing the default boot entry, and setting a boot timeout — without breaking the system. The critical rule: never edit GRUB configuration files directly. Always use grubby or grub2-mkconfig so changes survive kernel updates. These skills are tested on the RHCSA exam.

Learning Objectives

  1. Explain the GRUB 2 architecture — Describe how GRUB 2 boots RHEL, where configuration files live, and why /boot/grub2/grub.cfg must never be edited directly
  2. Modify kernel parameters with grubby — Use grubby to add, remove, and view kernel command-line parameters for the default and specific boot entries
  3. Set the default boot entry — Use grubby --set-default and grub2-set-default to configure which kernel boots by default
  4. Regenerate the GRUB configuration — Use grub2-mkconfig to rebuild grub.cfg from templates after making changes to /etc/default/grub

GRUB 2 Architecture

GRUB 2 uses a two-layer configuration system to separate editable settings from the generated boot configuration.

File / Location Purpose Edit directly?
/etc/default/grub Administrator settings: timeout, cmdline options, graphics mode Yes — this is the file to edit for system-wide settings
/etc/grub.d/ Script files that generate menu entries (40_custom for custom entries) Yes — for custom boot entries
/boot/grub2/grub.cfg The actual boot configuration read by GRUB at boot time No — auto-generated; manual edits are overwritten
/boot/loader/entries/*.conf BLS (Boot Loader Specification) per-kernel entries on UEFI systems Use grubby instead of editing directly
Never edit /boot/grub2/grub.cfg directly

grub.cfg is auto-generated by grub2-mkconfig and overwritten every time a new kernel is installed. Manual edits are silently lost. Always use grubby or edit /etc/default/grub and regenerate.

Viewing the Current GRUB Configuration

Before making changes, always inspect the current bootloader state.

# Show the default kernel and its parameters
$ grubby --default-kernel
/boot/vmlinuz-5.14.0-362.24.1.el9_3.x86_64

# Show the index number of the default entry
$ grubby --default-index
0

# Show full details about the default boot entry
$ sudo grubby --info=DEFAULT
index=0
kernel="/boot/vmlinuz-5.14.0-362.24.1.el9_3.x86_64"
args="ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"
root="/dev/mapper/rhel-root"
initrd="/boot/initramfs-5.14.0-362.24.1.el9_3.x86_64.img"
title="Red Hat Enterprise Linux (5.14.0-362.24.1.el9_3.x86_64) 9.3"

# List all boot entries
$ sudo grubby --info=ALL

Adding Kernel Parameters with grubby

grubby is the recommended tool for modifying kernel parameters on RHEL 9. Changes take effect at the next reboot.

# Add a parameter to the default kernel
$ sudo grubby --update-kernel=DEFAULT --args="quiet"

# Add multiple parameters at once
$ sudo grubby --update-kernel=DEFAULT --args="quiet splash"

# Add a parameter to a specific kernel (by path)
$ sudo grubby --update-kernel=/boot/vmlinuz-5.14.0-362.el9.x86_64 \
    --args="net.ifnames=0"

# Add a parameter to ALL installed kernels
$ sudo grubby --update-kernel=ALL --args="net.ifnames=0"

# Verify the change was applied
$ sudo grubby --info=DEFAULT
args="ro ... rhgb quiet net.ifnames=0"
grubby --update-kernel=DEFAULT --args= is the exam pattern

Most exam tasks ask to add a kernel parameter. The answer is always: sudo grubby --update-kernel=DEFAULT --args="PARAMETER" followed by verification with sudo grubby --info=DEFAULT.

Removing Kernel Parameters with grubby

The --remove-args flag removes specific parameters from a kernel entry without affecting other parameters.

# Remove a single parameter from the default kernel
$ sudo grubby --update-kernel=DEFAULT --remove-args="quiet"

# Remove multiple parameters
$ sudo grubby --update-kernel=DEFAULT --remove-args="quiet splash"

# Remove a parameter from ALL kernels
$ sudo grubby --update-kernel=ALL --remove-args="rhgb"

# Common parameters to add/remove and why
Parameter Effect when present Common use
quietSuppresses most kernel messages at bootRemove to see verbose boot messages for diagnostics
rhgbShows graphical boot splash screenRemove on servers for text boot output
net.ifnames=0Disables predictable network interface names (eth0, eth1)Add for compatibility with legacy scripts
rd.breakDrops to a shell early in boot (before root mount)Add temporarily for password recovery
systemd.unit=rescue.targetBoots into rescue modeAdd temporarily to troubleshoot startup issues

Setting the Default Boot Entry

When multiple kernels are installed, the default boot entry determines which one loads automatically after the timeout expires.

# Show all available boot entries
$ sudo grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.14.0-362.24.1.el9_3.x86_64"
title="Red Hat Enterprise Linux (5.14.0-362.24.1.el9_3.x86_64) 9.3"
index=1
kernel="/boot/vmlinuz-5.14.0-284.30.1.el9_2.x86_64"
title="Red Hat Enterprise Linux (5.14.0-284.30.1.el9_2.x86_64) 9.2"

# Set the default by kernel path
$ sudo grubby --set-default=/boot/vmlinuz-5.14.0-284.30.1.el9_2.x86_64

# Set the default by index number
$ sudo grub2-set-default 1

# Set back to the newest/highest-numbered kernel
$ sudo grub2-set-default 0

# Verify the new default
$ grubby --default-kernel
/boot/vmlinuz-5.14.0-284.30.1.el9_2.x86_64

$ grubby --default-index
1

/etc/default/grub: System-Wide Settings

This file contains variables that apply to all boot entries when grub2-mkconfig regenerates grub.cfg.

$ cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
Variable Purpose
GRUB_TIMEOUTSeconds to wait at boot menu before booting default (0=immediate, -1=wait forever)
GRUB_DEFAULTDefault entry: a number, "saved" (use grubenv), or kernel title
GRUB_CMDLINE_LINUXKernel parameters added to ALL boot entries
GRUB_TERMINAL_OUTPUTconsole = serial/VGA; gfxterm = graphical
GRUB_ENABLE_BLSCFGtrue = use BLS per-kernel config files (RHEL 9 default)

grub2-mkconfig: Regenerating grub.cfg

After editing /etc/default/grub, regenerate the boot configuration with grub2-mkconfig. The output location differs by firmware type.

# Step 1: Edit the settings file
$ sudo vim /etc/default/grub
# Change GRUB_TIMEOUT=5 to GRUB_TIMEOUT=10

# Step 2: Determine firmware type (BIOS or UEFI)
$ ls /sys/firmware/efi 2>/dev/null && echo UEFI || echo BIOS
UEFI

# Step 3: Regenerate grub.cfg
# UEFI systems:
$ sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for EFI firmware configuration
Found linux image: /boot/vmlinuz-5.14.0-362.24.1.el9_3.x86_64
Found initrd image: /boot/initramfs-5.14.0-362.24.1.el9_3.x86_64.img
done

# BIOS/legacy systems:
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

# Step 4: Verify timeout changed in grub.cfg
$ grep timeout /boot/grub2/grub.cfg
UEFI vs BIOS: different grub.cfg paths

UEFI: /boot/efi/EFI/redhat/grub.cfg
BIOS: /boot/grub2/grub.cfg
Check with ls /sys/firmware/efi — if the directory exists, the system uses UEFI.

Changing the Boot Timeout

The boot timeout controls how long GRUB waits at the menu before booting the default entry automatically. This is changed via /etc/default/grub.

# Step 1: View current timeout
$ grep GRUB_TIMEOUT /etc/default/grub
GRUB_TIMEOUT=5

# Step 2: Change the timeout (edit the file)
$ sudo sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=10/' /etc/default/grub

# Step 3: Regenerate grub.cfg
$ sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg   # UEFI
# or:
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg              # BIOS

# Step 4: Verify
$ grep GRUB_TIMEOUT /etc/default/grub
GRUB_TIMEOUT=10

# Special timeout values
# GRUB_TIMEOUT=0   → boot immediately, no menu shown
# GRUB_TIMEOUT=-1  → wait forever, always show menu
# GRUB_TIMEOUT=5   → show menu for 5 seconds (default)

Temporary Boot Parameters: Editing at Boot Time

For one-time debugging or recovery, boot parameters can be edited interactively in the GRUB menu — changes apply only to that single boot.

  1. Reboot the system. At the GRUB menu, press e to edit the selected entry.
  2. Find the linux line (the line starting with linux or linuxefi) — this is the kernel command line.
  3. Navigate to the end of the line and add or remove parameters. Common changes: remove quiet and rhgb for verbose output; add rd.break for initramfs shell access.
  4. Press Ctrl+X to boot with the modified parameters. The changes apply only to this one boot — they are not saved.
GRUB menu edits are not persistent

Edits made at the GRUB menu with e apply only to the current boot. To make permanent changes, use grubby or edit /etc/default/grub and regenerate.

Boot Loader Specification (BLS) Entries

RHEL 9 uses the BLS format — each installed kernel has its own configuration file in /boot/loader/entries/. grubby manages these files.

# List BLS entry files
$ ls /boot/loader/entries/
2a8e3a24c82e4f7c8e123abc-5.14.0-362.24.1.el9_3.x86_64.conf
2a8e3a24c82e4f7c8e123abc-5.14.0-284.30.1.el9_2.x86_64.conf

# View a BLS entry file
$ cat /boot/loader/entries/2a8e*-5.14.0-362*.conf
title Red Hat Enterprise Linux (5.14.0-362.24.1.el9_3.x86_64) 9.3
version 5.14.0-362.24.1.el9_3.x86_64
linux /vmlinuz-5.14.0-362.24.1.el9_3.x86_64
initrd /initramfs-5.14.0-362.24.1.el9_3.x86_64.img
options ro crashkernel=1G-4G:192M,... rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet
grub_users $grub_users
grub_arg --unrestricted
grub_class kernel

# When grubby --update-kernel --args is run, it modifies the "options" line above
# This is why grubby changes are persistent — the .conf file is updated

grubby vs grub2-mkconfig: When to Use Each

Task Use Why
Add a kernel parameter to default kernel grubby --update-kernel=DEFAULT --args= Modifies only the targeted kernel entry; no regeneration needed
Remove a kernel parameter grubby --update-kernel=DEFAULT --remove-args= Same — surgical removal from the args string
Set the default boot entry grubby --set-default= or grub2-set-default Updates grubenv; no regeneration needed
Change boot timeout Edit /etc/default/grub then grub2-mkconfig -o GRUB_TIMEOUT is a global setting applied during regeneration
Add a parameter to all kernels (including future) Add to GRUB_CMDLINE_LINUX in /etc/default/grub then regenerate New kernels installed by dnf will automatically inherit the parameter
Add a custom boot entry Edit /etc/grub.d/40_custom then regenerate Custom entries are defined in the /etc/grub.d/ script files

Bootloader Quick Reference

Task Command
Show default kernel pathgrubby --default-kernel
Show default entry indexgrubby --default-index
Show all boot entry detailssudo grubby --info=ALL
Show default entry detailssudo grubby --info=DEFAULT
Add parameter to default kernelsudo grubby --update-kernel=DEFAULT --args="PARAM"
Add parameter to all kernelssudo grubby --update-kernel=ALL --args="PARAM"
Remove parameter from default kernelsudo grubby --update-kernel=DEFAULT --remove-args="PARAM"
Set default by kernel pathsudo grubby --set-default=/boot/vmlinuz-VERSION
Set default by indexsudo grub2-set-default INDEX
View grub.cfg timeout settinggrep timeout /etc/default/grub
Change timeout (edit source)sudo vim /etc/default/grub → change GRUB_TIMEOUT
Regenerate grub.cfg (UEFI)sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
Regenerate grub.cfg (BIOS)sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Check firmware typels /sys/firmware/efi 2>/dev/null && echo UEFI || echo BIOS

Common Mistakes

Mistake What goes wrong Correct approach
Editing /boot/grub2/grub.cfg directly Changes are silently overwritten the next time grub2-mkconfig runs or a kernel is updated Use grubby for per-kernel changes; edit /etc/default/grub for global changes
Forgetting to run grub2-mkconfig after editing /etc/default/grub Changes to /etc/default/grub have no effect — grub.cfg still contains the old values Always run sudo grub2-mkconfig -o /boot/.../grub.cfg after any edit to /etc/default/grub
Using the wrong grub.cfg path for the firmware type grub2-mkconfig succeeds but writes to the wrong file — GRUB ignores the changes Check with ls /sys/firmware/efi: UEFI → /boot/efi/EFI/redhat/grub.cfg; BIOS → /boot/grub2/grub.cfg
Using --args= instead of --remove-args= when trying to remove a parameter The parameter is added a second time instead of being removed Use --remove-args="PARAM" to remove; --args="PARAM" only adds
Not verifying with grubby --info=DEFAULT after making changes Typo in parameter name goes unnoticed until reboot causes unexpected behaviour Always run sudo grubby --info=DEFAULT to confirm the args string looks correct
Setting GRUB_TIMEOUT=0 on a remote system without serial console If boot fails, there is no opportunity to select an alternate kernel — system is unreachable Keep GRUB_TIMEOUT at least 1-5 seconds on remote systems to allow manual entry selection

Practical Scenario: Adding net.ifnames=0

The exam scenario: configure the system to use traditional network interface names (eth0, eth1) instead of predictable names (ens3, eno1).

# Step 1: Verify current kernel parameters
$ sudo grubby --info=DEFAULT
args="ro ... rhgb quiet"
# net.ifnames=0 is not present

# Step 2: Add the parameter to ALL kernels
$ sudo grubby --update-kernel=ALL --args="net.ifnames=0"

# Step 3: Verify it was added
$ sudo grubby --info=DEFAULT
args="ro ... rhgb quiet net.ifnames=0"

# Step 4: Reboot for the change to take effect
$ sudo systemctl reboot

# After reboot: verify the interface names changed
$ ip link show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> ...

Knowledge Check

Answer these before moving to the next slide.

  1. Why should /boot/grub2/grub.cfg never be edited directly? What should be used instead?
  2. Write the command to add the kernel parameter console=ttyS0 to the default boot entry.
  3. After adding the parameter in question 2, write the command to verify it was successfully applied.
  4. Write the two steps needed to change the GRUB boot timeout from 5 seconds to 15 seconds on a UEFI system.
  5. There are two kernels installed. Write the command to make the second kernel (index 1) boot by default.
  6. What is the difference between grubby --update-kernel=DEFAULT and grubby --update-kernel=ALL?

Knowledge Check — Answers

  1. /boot/grub2/grub.cfg is auto-generated by grub2-mkconfig and overwritten every time a new kernel is installed or grub2-mkconfig is run. Manual edits are silently lost. Use grubby for per-kernel changes or edit /etc/default/grub and regenerate with grub2-mkconfig.
  2. sudo grubby --update-kernel=DEFAULT --args="console=ttyS0"
  3. sudo grubby --info=DEFAULT — examine the args= line in the output and confirm console=ttyS0 appears.
  4. (1) sudo vim /etc/default/grub and change GRUB_TIMEOUT=5 to GRUB_TIMEOUT=15. (2) sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg (UEFI) or sudo grub2-mkconfig -o /boot/grub2/grub.cfg (BIOS). Check with ls /sys/firmware/efi to determine which path to use.
  5. sudo grub2-set-default 1 — also accept sudo grubby --set-default=/boot/vmlinuz-VERSION with the full path of the second kernel shown by sudo grubby --info=ALL.
  6. --update-kernel=DEFAULT modifies only the currently configured default boot entry — the single kernel that loads when the system boots without manual selection. --update-kernel=ALL applies the change to every installed kernel entry, including older kernels and rescue entries — useful for parameters that should always be present regardless of which kernel is booted.

Key Takeaways

  1. Never edit /boot/grub2/grub.cfg directly — it is auto-generated. Use grubby for per-kernel parameter changes (no regeneration needed). Edit /etc/default/grub for global settings like timeout, then run grub2-mkconfig -o /path/to/grub.cfg to regenerate.
  2. Add parameters with grubby --update-kernel=DEFAULT --args="PARAM". Remove with --remove-args=. Use ALL instead of DEFAULT to apply to every installed kernel. Verify every change with sudo grubby --info=DEFAULT.
  3. Set the default boot entry with grub2-set-default INDEX. Index 0 is the newest kernel. Use grubby --info=ALL to see all entries and their indices. Use grubby --set-default=/boot/vmlinuz-VERSION for path-based selection that survives index reordering.
  4. UEFI and BIOS use different grub.cfg paths. UEFI: /boot/efi/EFI/redhat/grub.cfg. BIOS: /boot/grub2/grub.cfg. Check with ls /sys/firmware/efi. Sending grub2-mkconfig to the wrong path produces no error but also no effect at boot.

Graded Lab

  • Run grubby --default-kernel and sudo grubby --info=DEFAULT to record the current default kernel and its parameters. Note the args= line as your baseline.
  • Add the kernel parameter quiet to the default entry if it is not already present (or add net.ifnames=0 as an alternative). Use sudo grubby --update-kernel=DEFAULT --args="PARAM". Verify with sudo grubby --info=DEFAULT.
  • Remove the parameter you added in the previous step using sudo grubby --update-kernel=DEFAULT --remove-args="PARAM". Verify it is gone with sudo grubby --info=DEFAULT.
  • Check the firmware type with ls /sys/firmware/efi. View the current timeout in /etc/default/grub. Change GRUB_TIMEOUT to a different value and regenerate grub.cfg with the correct path for your firmware. Verify with grep timeout /boot/grub2/grub.cfg or the EFI equivalent.
  • If multiple kernels are installed, use sudo grubby --info=ALL to list them. Use sudo grub2-set-default 1 to make the second entry default, then verify with grubby --default-index. Restore index 0 as the default.
  • Open /boot/grub2/grub.cfg in a read-only viewer (less). Identify the generated stanza for the default kernel. Confirm it matches what grubby --info=DEFAULT showed — do not edit this file.
RHCSA Objective

"Modify the system bootloader." Use grubby --update-kernel=DEFAULT --args= for kernel parameters. Use /etc/default/grub + grub2-mkconfig for global settings. Always verify with grubby --info=DEFAULT.