| Tested on | RHEL 10.2 (Coughlan) — vm1.lab.example (BIOS firmware) |
|---|---|
| Package | grub2-tools 2.12-46.el10_2grubby 8.40-83.el10 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora |
| Privilege | sudo or root for bootloader changes and reboots |
| Scope | GRUB2 boot flow on RHEL, BLS entries under /boot/loader/entries/, grubby for default kernel and kernel arguments, /etc/default/grub, grub2-mkconfig --update-bls-cmdline, one-time grub2-reboot, and recovery from bad parameters. Does not cover Debian or Ubuntu GRUB, manual root password recovery, or exhaustive grubby flag reference. |
| Related guides | grubby command examples Boot with old kernel What GRUB files do Reset root password on RHEL RHCSA tutorial |
update-grub. It does not walk through resetting the root password at the GRUB prompt—that belongs in reset root password on RHEL.
On RHEL 10, GRUB2 reads BLS snippets, loads a kernel and initramfs, and passes kernel command-line arguments to the running system. This walkthrough on vm1.lab.example uses grubby for everyday changes and /etc/default/grub plus grub2-mkconfig when you need distribution-wide defaults synchronized into every entry.
How GRUB2 Booting Works on RHEL
Firmware
↓
GRUB2
↓
Boot Loader Specification entry
↓
Kernel + initramfs + kernel arguments| Term | Meaning on RHEL |
|---|---|
| GRUB2 | Bootloader that shows the menu, loads the kernel, and passes arguments |
| BLS | Boot Loader Specification format; each kernel has a snippet under /boot/loader/entries/ |
| Kernel entry | One BLS file describing linux, initrd, and options for a installed kernel |
| grubby | RHEL tool to list entries, set the default kernel, and edit kernel arguments |
/etc/default/grub |
Distribution defaults such as GRUB_CMDLINE_LINUX and menu timeout |
Package updates install new kernels and BLS snippets automatically. Your job is usually to pick the default entry and adjust options, not to hand-edit grub.cfg for every kernel change.
RHEL GRUB2 Quick Reference
| Task | Command |
|---|---|
| List kernels and entries | grubby --info=ALL |
| Show default kernel | grubby --default-kernel |
| Set default kernel | grubby --set-default /boot/vmlinuz-VERSION |
| Add argument to all kernels | grubby --update-kernel=ALL --args="parameter=value" |
| Remove argument | grubby --update-kernel=ALL --remove-args="parameter" |
| One-time next boot | grub2-reboot <index|title|id> |
| Running kernel arguments | cat /proc/cmdline |
| Regenerate GRUB config | grub2-mkconfig -o /boot/grub2/grub.cfg |
Sync /etc/default/grub into BLS |
grub2-mkconfig -o /boot/grub2/grub.cfg --update-bls-cmdline |
For additional grubby flags and title-based lookups, see grubby command examples.
Identify BIOS vs UEFI Boot
Firmware mode determines where the platform firmware looks first, but RHEL 10 regenerates the same main configuration path for routine administration.
Check firmware mode:
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOSBIOSOn this lab host firmware is legacy BIOS. On UEFI systems the same check prints UEFI.
Locate the active GRUB configuration:
ls -l /boot/grub2/grub.cfg-rw-------. 1 root root 7352 Aug 3 11:45 /boot/grub2/grub.cfgOn RHEL 10, write regenerated configuration to /boot/grub2/grub.cfg for both BIOS and UEFI. The UEFI stub under /boot/efi/EFI/redhat/ loads that file; do not replace the stub grub.cfg with grub2-mkconfig output.
Understand RHEL Boot Loader Specification Entries
BLS snippets live in /boot/loader/entries/:
ls /boot/loader/entries/23b7a5ba4a464d768c37c2b2990e7d06-0-rescue.conf
23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64.conf
23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64+debug.confA typical entry contains:
| Field | Role |
|---|---|
title |
Menu label |
version |
Kernel version identifier |
linux |
Path to vmlinuz |
initrd |
Path to initramfs image |
options |
Kernel command line (root=, resume=, rhgb, and custom parameters) |
Inspect one file:
head -8 /boot/loader/entries/23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64.conftitle Red Hat Enterprise Linux (6.12.0-211.42.1.el10_2.x86_64) 10.2 (Coughlan)
version 6.12.0-211.42.1.el10_2.x86_64
linux /vmlinuz-6.12.0-211.42.1.el10_2.x86_64
initrd /initramfs-6.12.0-211.42.1.el10_2.x86_64.img $tuned_initrd
options root=/dev/mapper/rhel-root ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet
grub_users $grub_users
grub_arg --unrestricted
grub_class rhelTreat these files as output of package management and grubby, not the primary edit surface. For file layout background, see what GRUB files do.
List Installed Kernels and Boot Entries
grubby --info=ALL summarizes every BLS-backed entry:
grubby --info=ALLindex=0
kernel="/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64+debug"
args="ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"
root="/dev/mapper/rhel-root"
initrd="/boot/initramfs-6.12.0-211.42.1.el10_2.x86_64+debug.img $tuned_initrd"
title="Red Hat Enterprise Linux (6.12.0-211.42.1.el10_2.x86_64+debug) 10.2 (Coughlan) with debugging"
id="23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64+debug"
index=1
kernel="/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64"
args="ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"
root="/dev/mapper/rhel-root"
initrd="/boot/initramfs-6.12.0-211.42.1.el10_2.x86_64.img $tuned_initrd"
title="Red Hat Enterprise Linux (6.12.0-211.42.1.el10_2.x86_64) 10.2 (Coughlan)"
id="23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64"
index=2
kernel="/boot/vmlinuz-0-rescue-23b7a5ba4a464d768c37c2b2990e7d06"
args="ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"
root="/dev/mapper/rhel-root"
initrd="/boot/initramfs-0-rescue-23b7a5ba4a464d768c37c2b2990e7d06.img"
title="Red Hat Enterprise Linux (0-rescue-23b7a5ba4a464d768c37c2b2990e7d06) 10.2 (Coughlan)"
id="23b7a5ba4a464d768c37c2b2990e7d06-0-rescue"Read index for menu ordering, kernel for the path you pass to grubby --set-default, and args for stored kernel parameters. The 0-rescue entry is the rescue kernel created at installation.
Check and Change the Default Kernel
Show which kernel boots by default:
grubby --default-kernel/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64Set the default to the installed production kernel path (adjust the version to match your host):
sudo grubby --set-default /boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64The default is /boot/loader/entries/23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64.conf with index 1 and kernel /boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64Confirm the saved default:
grubby --default-kernel/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64Reboot to run the newly selected default, then verify the running kernel:
uname -r6.12.0-211.42.1.el10_2.x86_64Use kernel paths rather than menu indexes when you script changes. Installing or removing kernels can reorder indexes. For booting a previous build after an upgrade, see boot with old kernel.
Select a Different Kernel for One Boot
Persistent default: grubby --set-default updates saved_entry in /boot/grub2/grubenv for every future boot until you change it again.
One boot only: pick another entry at the GRUB menu, or set next_entry with the BLS entry id (most stable), title, or index:
sudo grub2-reboot 23b7a5ba4a464d768c37c2b2990e7d06-0-rescueIndexes also work (grubby --info=ALL shows each index=), but installing or removing kernels can reorder them. Red Hat recommends id or title when you need a repeatable one-time boot target.
Inspect the environment block:
sudo grub2-editenv /boot/grub2/grubenv listsaved_entry=23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64
menu_auto_hide=1
boot_success=0
boot_indeterminate=0
next_entry=23b7a5ba4a464d768c37c2b2990e7d06-0-rescuesaved_entry remains the normal default. next_entry applies only to the next boot, then GRUB clears it.
Clear a pending one-time boot without rebooting:
sudo grub2-editenv - unset next_entryAdd Kernel Command-Line Parameters
Use grubby for the everyday workflow. printk.time=1 adds timestamps to kernel log lines and is safe for lab testing:
sudo grubby --update-kernel=ALL --args="printk.time=1"Confirm the argument landed on every entry:
grubby --info=/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64 | grep ^args=args="ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet printk.time=1"The BLS options line matches:
grep ^options /boot/loader/entries/23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64.confoptions root=/dev/mapper/rhel-root ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet printk.time=1Reboot before the running kernel picks up new arguments:
cat /proc/cmdlineBOOT_IMAGE=(hd0,gpt2)/vmlinuz-6.12.0-211.42.1.el10_2.x86_64 root=/dev/mapper/rhel-root ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quietUntil reboot, /proc/cmdline still reflects the currently running kernel, not the updated BLS entry.
Remove Kernel Parameters
Remove the test parameter from all kernels:
sudo grubby --update-kernel=ALL --remove-args="printk.time=1"Verify it disappeared from the stored entry:
grubby --info=/boot/vmlinuz-6.12.0-211.42.1.el10_2.x86_64 | grep ^args=args="ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"Reboot and check /proc/cmdline again when you need to confirm the running kernel no longer has the parameter.
Configure Parameters Through /etc/default/grub
/etc/default/grub holds distribution-wide settings. Important keys on this host:
grep -E '^GRUB_(TIMEOUT|DEFAULT|CMDLINE_LINUX)' /etc/default/grubGRUB_TIMEOUT=5
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX="resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"| Setting | Role |
|---|---|
GRUB_CMDLINE_LINUX |
Distribution-wide kernel command line that grub2-mkconfig --update-bls-cmdline can push into the BLS entries |
GRUB_TIMEOUT |
Seconds the menu waits before booting the default |
GRUB_DEFAULT=saved |
Default entry comes from saved_entry in grubenv |
grubby edits existing BLS options directly. /etc/default/grub holds distribution-wide defaults that grub2-mkconfig --update-bls-cmdline can overwrite into every BLS options line.
Add a shared argument to /etc/default/grub:
sudo sed -i 's/rhgb quiet"/rhgb quiet audit=1"/' /etc/default/grubPush GRUB_CMDLINE_LINUX into every BLS entry:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg --update-bls-cmdlineGenerating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
doneCheck one entry:
grep ^options /boot/loader/entries/23b7a5ba4a464d768c37c2b2990e7d06-6.12.0-211.42.1.el10_2.x86_64.confoptions root=/dev/mapper/rhel-root ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet audit=1Revert the test change on a lab host when finished:
sudo sed -i 's/ audit=1//' /etc/default/grubRegenerate so BLS entries drop the test argument:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg --update-bls-cmdlineUse grubby for routine kernel-argument changes directly in BLS entries. RHEL 10 normally carries those arguments forward when a newer kernel is installed. Use /etc/default/grub plus --update-bls-cmdline when you intentionally want the BLS command lines realigned with GRUB_CMDLINE_LINUX. That step overwrites BLS snippets; it is not merely appending missing arguments, so grubby-only parameters absent from GRUB_CMDLINE_LINUX can be removed.
Change the GRUB Menu Timeout
Edit GRUB_TIMEOUT in /etc/default/grub, then regenerate:
sudo grub2-mkconfig -o /boot/grub2/grub.cfgGenerating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
doneConfirm at the next boot that the menu waits the configured number of seconds. GRUB_TIMEOUT=0 hides the menu immediately unless you interrupt boot.
Inspect the Active Kernel Command Line
The running kernel exposes the command line it received at boot:
cat /proc/cmdlineBOOT_IMAGE=(hd0,gpt2)/vmlinuz-6.12.0-211.42.1.el10_2.x86_64 root=/dev/mapper/rhel-root ro resume=UUID=78531da6-a389-46e8-9bad-267572940826 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quietCompare this line to grubby --info or the BLS options field. If they differ, you likely changed stored entries but have not rebooted yet, or a one-time menu edit overrode the saved entry.
Rebuild GRUB Configuration
You do not need grub2-mkconfig after every grubby change. grubby updates BLS snippets and grubenv directly.
Regenerate when you change /etc/default/grub, after some manual recovery steps, or when generated grub.cfg is clearly stale:
sudo grub2-mkconfig -o /boot/grub2/grub.cfgGenerating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
doneOn RHEL 10 the correct target is always:
sudo grub2-mkconfig -o /boot/grub2/grub.cfgfor BIOS and UEFI. Add --update-bls-cmdline when GRUB_CMDLINE_LINUX or other defaults must flow into /boot/loader/entries/.
Recover from a Bad Kernel Parameter
If a new kernel argument prevents boot:
- Interrupt the GRUB menu at startup.
- Highlight the entry and press
eto edit temporarily. - Remove or fix the bad argument on the
linuxline. - Press Ctrl+x to boot with the temporary change.
- After the system is up, remove the argument permanently with grubby:
sudo grubby --update-kernel=ALL --remove-args="bad.parameter"Reboot again to confirm clean startup.
This workflow fixes kernel command-line mistakes. Locked root accounts or forgotten passwords use a different procedure in reset root password on RHEL.
Troubleshoot GRUB and Kernel Entries
| Symptom | Likely cause | Fix |
|---|---|---|
| New kernel missing from menu | Package did not finish installing or BLS snippet missing | rpm -q kernel; reinstall kernel package; check /boot/loader/entries/ |
| Wrong kernel boots every time | Default not updated or saved_entry stale |
grubby --set-default /boot/vmlinuz-VERSION; verify grubby --default-kernel |
| Parameter in BLS but not active | No reboot after grubby change | Reboot; compare grubby --info to /proc/cmdline |
| Boot failure after parameter change | Bad kernel argument | Edit once at GRUB menu; remove with grubby --remove-args |
| BLS entry missing | Manual deletion or failed install | Reinstall kernel or rescue package; avoid hand-editing as routine |
grub.cfg looks wrong |
Regenerated wrong path or stale file | grub2-mkconfig -o /boot/grub2/grub.cfg; never overwrite UEFI stub directly |
| UEFI boot breaks after mkconfig | Output written to EFI stub path | Regenerate only /boot/grub2/grub.cfg on RHEL 10 |
| Rescue kernel confusion | 0-rescue is fallback, not default |
Use for recovery; set normal default with grubby --set-default after fix |
Practical GRUB Configuration Examples
Safe patterns on a lab host:
grubby --info=ALL— inventory kernels before you change anythinggrubby --set-default /boot/vmlinuz-VERSION— pick the production kernelgrubby --update-kernel=ALL --args="printk.time=1"— test parameter add- Reboot and
cat /proc/cmdline— confirm the running kernel grubby --update-kernel=ALL --remove-args="printk.time=1"— revert- Edit
GRUB_TIMEOUTin/etc/default/grub, thengrub2-mkconfig -o /boot/grub2/grub.cfg grub2-reboot 23b7a5ba4a464d768c37c2b2990e7d06-0-rescue— one-time rescue boot by BLS id; clear withgrub2-editenv - unset next_entry
Avoid parameters that disable storage, networking, or SELinux unless you have snapshot recovery. Do not use this article as a root password reset guide.
References
- grubby(8) — Linux manual page
- kernel-command-line(7) — Linux manual page
- Red Hat — Configuring kernel command-line parameters
- Red Hat — Managing, monitoring, and updating the kernel
Summary
You configured GRUB2 on RHEL by working with BLS snippets under /boot/loader/entries/ rather than treating grub.cfg as the primary edit target. grubby lists entries, sets the default kernel, and adds or removes kernel arguments on one or all installed kernels. grubby --default-kernel and uname -r confirm default selection after reboot; cat /proc/cmdline shows what the running kernel actually received.
The distinction that saves time on RHEL 10 is tooling choice: routine per-kernel work stays in grubby, while /etc/default/grub plus grub2-mkconfig -o /boot/grub2/grub.cfg --update-bls-cmdline synchronizes distribution-wide GRUB_CMDLINE_LINUX values into every BLS entry. Regenerate /boot/grub2/grub.cfg on both BIOS and UEFI; do not overwrite the UEFI stub configuration directly.
If a bad parameter blocks boot, edit once at the GRUB menu, boot, then make the fix permanent with grubby. For exhaustive command coverage, continue with grubby command examples; for booting a previous kernel build, see boot with old kernel. Root password recovery stays in reset root password on RHEL.

