GRUB and Kernel Parameters

Concept

GRUB (GRand Unified Bootloader) selects a kernel and initramfs pair and passes a command line into the kernel. Those parameters control early behaviour: where root is, whether to break into the initramfs, console devices, cgroup defaults, and a long list of subsystem toggles.

Permanent config lives in distro-managed files; the effective line is whatever the running kernel reports in /proc/cmdline.

Why it matters

  • Recovery often starts by editing the cmdline once in the GRUB menu (rd.break, rescue.target, enforcing=0)
  • Permanent mistakes (root= wrong UUID, missing console=, bad crashkernel=) only show up after reboot
  • UEFI + Secure Boot + wrong EFI path is a “disk is fine, firmware will not chainload” problem
  • Vendor kernels and cloud images sometimes inject parameters via GRUB snippets you did not know existed

Treat cmdline changes like firewall changes: temporary test first, then persist.

Mental Model

UEFI NVRAM / BIOS order
    → EFI binary or MBR stage
        → grub.cfg (or BLS entries)
            → menu entry: linux /vmlinuz… <cmdline>
                          initrd /initramfs…
                → kernel sees /proc/cmdline

Editing sources of truth:

  • RHEL-like: /etc/default/grub + /etc/grub.d/* → grub2-mkconfig
  • Debian-like: /etc/default/grub + /etc/default/grub.d/* → update-grub
  • Some cloud images: grubby or BLS (/boot/loader/entries/*.conf) instead of classic grub.cfg

Runtime view is always cat /proc/cmdline. Config files can lie until the next mkconfig + reboot.

Key Commands

# What is actually running?
cat /proc/cmdline
 
# EFI boot order (UEFI systems)
efibootmgr -v
 
# Generate config after /etc/default/grub changes
# RHEL-like:
grub2-mkconfig -o /boot/grub2/grub.cfg
# or EFI:
grub2-mkconfig -o /boot/efi/EFI/<vendor>/grub.cfg
# Debian-like:
update-grub
 
# grubby (RHEL convenience)
grubby --info=ALL
grubby --update-kernel=ALL --args="systemd.unit=multi-user.target"
grubby --update-kernel=ALL --remove-args="quiet"
 
# Temporary recovery from GRUB menu
# e to edit, change linux/linuxefi line, Ctrl-x or F10 to boot
# Useful one-shot args:
#   systemd.unit=rescue.target
#   systemd.unit=emergency.target
#   rd.break
#   enforcing=0
#   init=/bin/bash
#   console=ttyS0,115200n8
 
# Inspect generated entries
grep -n 'linux\|linuxefi\|options' /boot/grub2/grub.cfg 2>/dev/null | head
ls /boot/loader/entries/ 2>/dev/null

Common parameters worth knowing:

ParameterRole
root=UUID=…Real root device for initramfs
ro / rwInitial mount of root
rd.break / rd.shellInitramfs debug shells
systemd.unit=Override default target
console=Serial / graphical console
quiet splashHide early messages (remove when debugging)
enforcing=0SELinux permissive for this boot
nouveau.modeset=0 / nomodesetBroken GPU bring-up
crashkernel=Reserved memory for kdump

Common Failure Modes & Symptoms

SymptomLikely causeFirst checks
GRUB: no such device / UUID/boot moved, wrong UUID in cfgblkid, regenerate cfg from chroot
Firmware boots wrong diskEFI order or leftover entryefibootmgr -v, delete stale
Kernel boots, no messagesquiet + wrong/missing console=Remove quiet; set serial console
Changes in /etc/default/grub ignoredForgot grub2-mkconfig / update-grubDiff cfg mtime vs default file
Only old kernel listedNew kernel package did not update cfgReinstall kernel package, mkconfig
Secure Boot rejectionUnsigned/shim path wrongMOK, vendor EFI binary, SB state
root= points at vanished nameUsed /dev/sdX instead of UUIDFix to UUID/LABEL
Temporary edit “did nothing”Edited wrong menu entry (rescue vs default)Confirm the line you boot

Investigation Tips

  • Photograph or serial-capture the GRUB error before you reboot again. The text names the missing UUID or file.
  • For one-off recovery, prefer GRUB menu edit over rewriting disk from a live image when the filesystem is healthy.
  • After editing /etc/default/grub, regenerate and verify the output file contains your args (grep the cfg).
  • On dual-boot or multipath hosts, GRUB may have been installed to the wrong disk. efibootmgr and the cloud/firmware boot order matter more than /boot/grub2 existing.
  • grubby --update-kernel=ALL is safer than hand-editing cfg on RHEL when you only need to add/remove args.
  • Keep console=tty0 console=ttyS0,115200n8 (order matters) on machines you will only ever reach via serial or cloud console.
  • Document permanent cmdline policy (audit, hugepages, cgroup) in the same place you document fstab — it is part of the host contract.

Personal Lessons Learned

  • Removing quiet splash for one boot has answered more “black screen after upgrade” tickets than any package reinstall. Early kernel messages were there the whole time.
  • I treat grubby --info=ALL as the source of truth on RHEL before arguing about what /etc/default/grub says. They diverge after manual cfg edits.
  • Serial console parameters belong in the golden image, not in the runbook written after the first unreachable production reboot.