GRUB (GRand Unified Bootloader) is the first thing that runs after the firmware. It shows the boot menu, loads the kernel and passes it boot parameters. You rarely touch it, but when you need to boot an older kernel, add a kernel parameter or repair a server that doesn’t boot, knowing GRUB is essential.

The files

  • /etc/default/grub — the file you edit: timeout, default entry, kernel parameters.
  • /etc/grub.d/ — scripts that generate menu entries.
  • /boot/grub/grub.cfg (Debian/Ubuntu) or /boot/grub2/grub.cfg (RHEL family) — the generated config. Don’t edit it by hand, because it’s overwritten on every kernel update.

After editing /etc/default/grub, regenerate the config:

sudo update-grub                                   # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg        # RHEL family (BIOS and modern UEFI)

Common settings

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=menu
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
  • GRUB_TIMEOUT — seconds the menu waits. Cloud images often set 0 or a hidden menu, which makes it hard to choose another kernel from the console. Set it to 5 with TIMEOUT_STYLE=menu if you want a chance to intervene.
  • GRUB_CMDLINE_LINUX — kernel parameters for every boot entry.
  • GRUB_CMDLINE_LINUX_DEFAULT — parameters for normal boots only (Debian/Ubuntu), not for recovery entries.

Cloud images may override these in /etc/default/grub.d/*.cfg. Check there if your changes don’t take effect.

Boot an older kernel by default

List the menu entries:

grep -E "menuentry '|submenu '" /boot/grub/grub.cfg | cut -d"'" -f2

Set the default to a specific entry (submenu > entry):

# /etc/default/grub
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-85-generic"

Then run sudo update-grub.

Or remember whatever was booted last:

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

Boot a different entry once, for the next boot only:

sudo grub-reboot "Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-85-generic"
sudo reboot

On RHEL-family systems, grubby manages kernels directly:

sudo grubby --info=ALL | grep -E '^kernel|^index'
sudo grubby --set-default /boot/vmlinuz-5.14.0-427.el9.x86_64
sudo grubby --default-kernel

Add kernel parameters

Example: disable a feature or enable cgroup options.

# /etc/default/grub
GRUB_CMDLINE_LINUX="… existing … systemd.unified_cgroup_hierarchy=1"

Run sudo update-grub, reboot, then check cat /proc/cmdline.

RHEL family:

sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
sudo grubby --update-kernel=ALL --remove-args="quiet"

Common parameters:

Parameter Use
console=tty0 console=ttyS0,115200 Show boot output on VNC and serial consoles
nomodeset Avoid graphics driver problems at boot
systemd.unit=rescue.target Boot into rescue mode (one-off, set from the menu)
init=/bin/bash Emergency root shell, bypassing init (password recovery)
ipv6.disable=1 Disable IPv6 entirely

Edit parameters for one boot (from the console)

At the GRUB menu (open the VNC console and reboot):

  1. Highlight the entry and press e.
  2. Find the line starting with linux, and add your parameter at the end.
  3. Press Ctrl+X or F10 to boot.

The change is temporary, so it’s safe for experiments and recovery. See Linux rescue mode.

If the menu doesn’t show, hold Shift (BIOS) or tap Esc (UEFI) right after the reboot starts.

Reinstall GRUB

If GRUB itself is broken, for example after a disk replacement on a RAID 1 dedicated server or after an interrupted update, reinstall it from the running system or a rescue environment.

BIOS systems:

sudo grub-install /dev/sda
sudo update-grub

UEFI systems (Ubuntu/Debian):

sudo apt install --reinstall grub-efi-amd64 shim-signed
sudo grub-install
sudo update-grub

From a rescue system, mount the installed system and chroot into it first:

sudo mount /dev/vda1 /mnt
for d in dev proc sys run; do sudo mount --rbind /$d /mnt/$d; done
sudo mount /dev/vda15 /mnt/boot/efi      # if UEFI
sudo chroot /mnt
grub-install /dev/vda && update-grub
exit

On mirrored dedicated servers, install GRUB on both disks so either can boot.

Security: password-protect GRUB editing

Anyone with console access can edit kernel parameters and get a root shell (init=/bin/bash). On servers, the console is protected by your provider account, so this is usually acceptable. For extra protection, set a GRUB password with grub-mkpasswd-pbkdf2 and a password_pbkdf2 entry in /etc/grub.d/40_custom.

Quick reference

Task Command
Settings /etc/default/grub
Regenerate update-grub / grub2-mkconfig -o /boot/grub2/grub.cfg
List entries grep menuentry /boot/grub/grub.cfg
Boot entry once grub-reboot "entry"
Default kernel (RHEL) grubby --set-default /boot/vmlinuz-…
Add parameter (RHEL) grubby --update-kernel=ALL --args="…"
Current parameters cat /proc/cmdline
Reinstall (BIOS) grub-install /dev/sda

Related: upgrade the kernel and uname.

  • Linux
  • Boot
  • Kernel