Ubuntu 24.10 GRUB Manual

A complete zero-to-hero guide to GRUB on modern Ubuntu. Learn how the bootloader works, how to configure it safely, and how to recover from broken boots, dual-boot issues, and Secure Boot problems.

Ubuntu 24.10 GRUB Manual

From Zero‑to‑Hero – How GRUB Works, How to Configure It, and How to Fix Anything That Goes Wrong

Target audience – Anyone who installed Ubuntu 24.10 (or any later Ubuntu) on a BIOS‑ or UEFI‑based machine and wants to understand the bootloader that sits in front of the OS.
What you’ll get – A step‑by‑step guide, ready‑to‑copy command lines, a troubleshooting matrix, and placeholders for screenshots you can paste into your own documentation.

Table of Contents

  1. What Is GRUB? – The Big Picture
  2. GRUB’s Two Main Flavors: BIOS vs. UEFI
  3. Boot Flow on Ubuntu 24.10
  4. Where the Files Live
  5. Installing / Re‑installing GRUB
  6. The Core Configuration Files
  7. Generating a New grub.cfg
  8. Adding Custom Menu Entries
  9. Changing the Default Kernel / Timeout
  10. Themes, Backgrounds, and Fancy Tricks
  11. Secure Boot & Shim
  12. Dual‑Boot & Multi‑Boot Scenarios
  13. Recovering From a Broken GRUB
  14. Common Errors & How to Fix Them
  15. Common Errors & How to Fix Them (Full Matrix)
  16. Common Errors & How to Fix Them – Full Matrix (Expanded)
  17. Tools: boot-repair, grub‑customizer, efibootmgr
  18. Backup, Restore, and Version‑Control of GRUB
  19. Cheat‑Sheet – One‑Page Command Summary
  20. Final Thoughts

1. What Is GRUB? – The Big Picture

Component Role Location (default)
GRUB Stage 1 (MBR or EFI stub) Tiny code that the firmware loads first. It points to the rest of GRUB. BIOS: first 446 bytes of the disk (/dev/sda).
UEFI: EFI/ubuntu/grubx64.efi in the ESP.
GRUB Stage 1.5 (optional) Filesystem driver that lets Stage 1 read /boot/grub. Only used on BIOS when the /boot partition is not directly adjacent. Embedded between MBR and first partition (if needed).
GRUB Stage 2 (core.img) Full GRUB loader; reads grub.cfg, presents the menu, loads kernels. /boot/grub/x86_64-efi/core.img (UEFI) or /boot/grub/i386-pc/core.img (BIOS).
grub.cfg Human‑readable menu description, generated from /etc/default/grub + /etc/grub.d/*. /boot/grub/grub.cfg (never edited by hand).
shim.efi (when Secure Boot is enabled) Small signed loader that hands control to GRUB. /boot/efi/EFI/ubuntu/shimx64.efi.

Key point: Never edit grub.cfg directly. It is regenerated every time you run update-grub (or grub-mkconfig). All persistent changes go in /etc/default/grub or in custom scripts under /etc/grub.d/.

2. GRUB’s Two Main Flavors: BIOS vs. UEFI

Feature BIOS (Legacy) UEFI (Modern)
Boot file core.img loaded from the MBR .efi file stored on the EFI System Partition (ESP)
Partition table MBR (dos) GPT (recommended)
Secure Boot Not supported Supported via shim
Installation command grub-install /dev/sda grub-install
--target=x86_64-efi
--efi-directory=/boot/efi
--bootloader-id=ubuntu
Default config path /boot/grub/grub.cfg Same file, but the loader reads it from the ESP (/boot/efi/EFI/ubuntu/grub.cfg is a symlink)

Ubuntu 24.10 defaults to UEFI on any system that supports it. If you force a legacy install (e.g., for an old BIOS box) the installer will set up the BIOS version automatically.

3. Boot Flow on Ubuntu 24.10

+-----------------+   BIOS/UEFI   +-----------------+   reads   +-----------------+
| Firmware (BIOS  |-------------> | GRUB Stage 1    |---------> | GRUB Stage 2    |
| or UEFI)        |   (MBR/EFI)  | (core.img)      |  grub.cfg  | (grub.cfg)      |
+-----------------+               +-----------------+           +-----------------+
                                                                  |
                                                                  v
                                                  +---------------------------+
                                                  | Linux kernel (vmlinuz)    |
                                                  | initramfs (initrd.img)    |
                                                  +---------------------------+
                                                                  |
                                                                  v
                                               +-------------------------------+
                                               | systemd (PID 1) → userspace   |
                                               +-------------------------------+
  1. Firmware loads the appropriate GRUB binary.
  2. GRUB Stage 2 parses grub.cfg and shows the menu.
  3. When you pick an entry, GRUB loads the kernel (vmlinuz‑<version>) and the initramfs (initrd.img‑<version>).
  4. The kernel mounts the root filesystem (using the UUID/label supplied by GRUB) and hands over to systemd.

Understanding this chain makes it easier to pinpoint where something went wrong.

4. Where the Files Live

Path Description
/boot/grub/grub.cfg Generated menu file (read‑only for users).
/etc/default/grub Central place for most options (timeout, default entry, splash, etc.).
/etc/grub.d/00_header99_custom Scripts that generate sections of grub.cfg.
/boot/efi/EFI/ubuntu/ UEFI‑specific files (grubx64.efi, shimx64.efi, MokManager.efi).
/var/lib/grub/ Staging area used by grub-mkconfig.
/etc/grub.d/41_custom The script that inserts everything you put into /etc/grub.d/40_custom.
/etc/grub.d/30_os-prober Detects other OSes (Windows, other Linuxes).
/etc/grub.d/10_linux Generates menu entries for the kernels installed on Ubuntu.

5. Installing / Re‑installing GRUB

5.1 BIOS (Legacy)

sudo grub-install /dev/sda          # replace sda with your boot disk
sudo update-grub                    # generate grub.cfg

5.2 UEFI

# Ensure the ESP is mounted at /boot/efi (Ubuntu does this automatically)
sudo mount | grep efi               # sanity check
sudo grub-install \
    --target=x86_64-efi \
    --efi-directory=/boot/efi \
    --bootloader-id=ubuntu \
    --recheck
sudo update-grub

5.3 When the installer fails

Symptom Likely cause Quick fix
grub-install: error:
cannot find EFI directory
ESP not mounted or wrong mount point. sudo mount /dev/sdxY /boot/efi (replace with your ESP).
grub-install: error:
device is full
/boot partition out of space. Clean old kernels (sudo apt autoremove) or enlarge the partition.
grub-install: error:
invalid EFI file name
Wrong --bootloader-id. Use a simple ID: --bootloader-id=ubuntu.

6. The Core Configuration Files

6.1 /etc/default/grub – the “master switchboard”

# /etc/default/grub
GRUB_DEFAULT=0                     # default entry (0 = first)
GRUB_TIMEOUT_STYLE=menu           # show menu (instead of countdown)
GRUB_TIMEOUT=5                     # seconds before auto‑boot
GRUB_DISTRIBUTOR=`lsb_release -i -s`  # usually "Ubuntu"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""              # extra kernel parameters
GRUB_DISABLE_SUBMENU=true         # flat list instead of submenu
GRUB_GFXMODE=1920x1080,auto        # graphics mode for the menu
GRUB_GFXPAYLOAD_LINUX=keep         # keep the same mode for the kernel
GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"

Key variables you’ll change often

Variable What it does Example
GRUB_DEFAULT Which entry boots automatically. Can be saved (use grub-set-default). GRUB_DEFAULT=saved
GRUB_TIMEOUT Seconds before auto‑boot. Set to 0 for “no menu”. GRUB_TIMEOUT=2
GRUB_CMDLINE_LINUX_DEFAULT Kernel parameters for normal boots. "quiet splash pcie_aspm=off"
GRUB_DISABLE_OS_PROBER Turn off detection of other OSes (speed up update-grub). GRUB_DISABLE_OS_PROBER=true

6.2 /etc/grub.d/* – the generators

Script What it adds
00_header Boiler‑plate, set timeout_style, theme loading.
10_linux All Ubuntu kernel entries (menuentry 'Ubuntu, with Linux …').
20_linux_xen Xen hypervisor entries (rare).
30_os-prober Entries for Windows, other Linuxes, macOS.
40_custom User‑provided menu entries (hand‑written).
41_custom Wrapper that reads /etc/grub.d/40_custom.

Never edit 10_linux or 30_os-prober directly – they get regenerated each time you run update-grub. Put your own items in 40_custom.

7. Generating a New grub.cfg

# The canonical command (run as root)
sudo update-grub                # wrapper → grub-mkconfig -o /boot/grub/grub.cfg

Under the hood:

sudo grub-mkconfig -o /boot/grub/grub.cfg

If you suspect a broken script, you can run it manually to see the output:

sudo /etc/grub.d/10_linux

The output is a chunk of the future grub.cfg.

8. Adding Custom Menu Entries

8.1 The simplest way – 40_custom

Edit the file:

sudo vim /etc/grub.d/40_custom

Add a block like this:

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply
# add any menu entries you want below, and run "update-grub" after
# saving this file.

menuentry "My Old Ubuntu (3.10 kernel)" {
    set root=(hd0,1)               # adjust to your /boot partition
    linux /boot/vmlinuz-3.10.0-112-generic root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro quiet splash
    initrd /boot/initrd.img-3.10.0-112-generic
}

Make sure the file is executable (it already is on a fresh install, but verify):

sudo chmod +x /etc/grub.d/40_custom

Run sudo update-grub and you’ll see the new entry appear at the bottom of the menu.

8.2 Advanced – Full‑screen rescue entry

menuentry "Rescue mode – Drop to root shell" {
    set root=(hd0,msdos1)
    linux /boot/vmlinuz-$(uname -r) root=UUID=$rootuuid ro recovery nomodeset
    initrd /boot/initrd.img-$(uname -r)
}

9. Changing the Default Kernel / Timeout

9.1 Pick a specific kernel as default

  1. Find the entry number (grub-mkconfig prints numbers in comments).
  2. Edit /etc/default/grub:
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.5.0-28-generic"

You can also use the saved mode:

GRUB_DEFAULT=saved
sudo grub-set-default "Advanced options for Ubuntu>Ubuntu, with Linux 6.5.0-28-generic"

Now the next boot will use that kernel, but you can still pick another one from the menu.

9.2 Adjust the timeout

GRUB_TIMEOUT=3                # 3 seconds
GRUB_TIMEOUT_STYLE=hidden    # hide the menu unless SHIFT is held

Run sudo update-grub after each change.

10. Themes, Backgrounds, and Fancy Tricks

Ubuntu ships a basic theme, but you can install many community ones.

10.1 Install a theme package

sudo apt install grub-theme-starfield  # example from the repos

10.2 Use a custom theme you downloaded

Assume you unpacked mytheme.tar.gz into /usr/share/grub/themes/mytheme.

sudo cp -r mytheme /usr/share/grub/themes/
sudo vim /etc/default/grub
# change/add:
GRUB_THEME="/usr/share/grub/themes/mytheme/theme.txt"

Run sudo update-grub and reboot.

10.3 Change the background image only

If you don’t want a full theme, just set GRUB_BACKGROUND:

GRUB_BACKGROUND="/usr/share/backgrounds/ubuntu/planet.jpg"

11. Secure Boot & Shim

Ubuntu 24.10 ships with Signed GRUB (shim.efi). If Secure Boot is enabled in the firmware:

  1. Bootshimx64.efi (signed by Microsoft) loads grubx64.efi.
  2. If you install a custom kernel that isn’t signed, you must sign it with your own Machine Owner Key (MOK) or disable Secure Boot.

11.1 Enroll your own MOK (if you need custom kernels)

# Install the signing tools
sudo apt install mokutil

# Generate a key pair
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=My Ubuntu MOK/"

# Enroll the key
sudo mokutil --import MOK.der
# Reboot – you’ll be prompted to confirm the key enrollment.

After enrollment, you can sign a kernel:

sudo sbsign --key MOK.priv --cert MOK.der \
    --output /boot/vmlinuz-5.19.0-custom-signed \
    /boot/vmlinuz-5.19.0-custom

Then point your custom GRUB entry to the signed kernel.

12. Dual‑Boot & Multi‑Boot Scenarios

12.1 Adding Windows to the menu

If os-prober is enabled (default), Windows will appear automatically.

sudo vim /etc/default/grub
GRUB_DISABLE_OS_PROBER=false   # ensure it’s not disabled

Run sudo update-grub.

12.2 Manual Windows entry (when os-prober fails)

menuentry "Windows 11 (loader)" {
    insmod part_gpt
    insmod fat
    set root='hd0,gpt1'   # ESP partition
    chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}

12.3 Keeping a separate GRUB for each OS (advanced)

You can install GRUB on each disk’s MBR/EFI and use the firmware’s boot‑order list (efibootmgr) to pick which OS boots by default.

sudo efibootmgr -c -d /dev/sda -p 1 -L "Ubuntu" -l '\EFI\ubuntu\shimx64.efi'
sudo efibootmgr -c -d /dev/sdb -p 1 -L "Windows" -l '\EFI\Microsoft\Boot\bootmgfw.efi'

Now you can change the default with:

sudo efibootmgr -o 0002,0001   # Windows (0002) first, then Ubuntu (0001)

13. Recovering From a Broken GRUB

13.1 The “GRUB rescue>” prompt

Typical messages:

grub rescue> unknown command `linux'
grub rescue> ls

Step‑by‑step rescue (BIOS)

Boot into Ubuntu and reinstall GRUB from the OS:

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

Set the root and prefix

grub rescue> set root=(hd0,msdos1)
grub rescue> set prefix=(hd0,msdos1)/boot/grub
grub rescue> insmod normal
grub rescue> normal

This should drop you into the normal GRUB menu.

Find the one that contains /boot/grub

grub rescue> ls (hd0,msdos1)/

Look for grub directory.

Identify your partitions

grub rescue> ls
(hd0) (hd0,msdos1) (hd0,msdos2) …

Step‑by‑step rescue (UEFI)

If you land in grub> (not grub rescue>), the same set root/prefix trick works, but you may need to specify the ESP:

grub> ls (hd0,gpt1)/
grub> set root=(hd0,gpt1)
grub> set prefix=(hd0,gpt1)/EFI/ubuntu
grub> insmod normal
grub> normal

13.2 Using a Live USB (the “safest” method)

  1. Boot from an Ubuntu 24.10 live USB (choose “Try Ubuntu”).
  2. Mount your system partitions:
sudo mount /dev/sda2 /mnt               # root partition
sudo mount /dev/sda1 /mnt/boot/efi      # ESP (if UEFI)
sudo mount --bind /dev /mnt/dev
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
  1. Chroot into the installed system:
sudo chroot /mnt
  1. Reinstall GRUB:
# BIOS:
grub-install /dev/sda
# UEFI:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu --recheck
update-grub
  1. Exit and reboot.

14. Common Errors & How to Fix Them

Error Message Cause Fix (one‑liner)
error: unknown
filesystem
GRUB cannot read the filesystem (corrupt /boot). Boot live USB, run
fsck /dev/sdXY.
error: file
'/boot/vmlinuz‑…'
not found
Kernel image missing (perhaps removed). Reinstall the kernel
(sudo apt install
linux-image-generic
).
error: cannot find
a device for
/boot/grub
GRUB_ROOT/GRUB_PREFIX
wrong after moving partitions.
Update /etc/fstab
and reinstall GRUB.
grub-install: error:
device is full
/boot partition full. sudo apt autoremove &&
sudo apt clean
.
error: no such
partition
UUID changed
(e.g., after cloning).
Edit
/etc/default/grub
with the new UUID or run
sudo update-grub.
failed to load
kernel
initrd
missing or corrupted.
Regenerate initramfs:
sudo update-initramfs
-c -k all
.
warning: file
'/boot/grub/i386-pc/modinfo.sh'
not found
Mixed BIOS/UEFI scripts. Remove the stray script or reinstall the correct GRUB flavour.
error: unknown
command 'setpci'
Kernel parameter typo in
GRUB_CMDLINE_LINUX.
Remove the offending
line from
/etc/default/grub.
error: cannot
write to device
Disk is read‑only
(e.g., due to hardware
write‑protect).
Ensure the disk is not locked, or replace the disk.
invalid signature
(UEFI, Secure Boot)
Custom kernel unsigned. Sign the kernel with MOK (see § 11) or disable Secure Boot.

15. Common Errors & How to Fix Them (Full Matrix)

Below is the full matrix of the most common GRUB problems you’ll encounter on Ubuntu 24.10. Each row includes a short description, the command that usually triggers it, the diagnostic steps, and the fix.

# Symptom Trigger Diagnostics Fix
1 error: file
'/boot/grub/grub.cfg'
not found
Boot after moving
/boot
to a separate partition.
ls /boot/grub/
(in live chroot).
Update
GRUB_ROOT
and
GRUB_PREFIX
via
grub-install --force.
2 grub> unknown
command 'linux'
Using a legacy BIOS GRUB on a UEFI system (or vice‑versa). ls shows partitions but not the ESP. Reinstall appropriate GRUB flavour
(grub-install
--target=x86_64-efi …
).
3 Menu disappears after kernel upgrade GRUB_TIMEOUT_STYLE=hidden
and
GRUB_TIMEOUT=0.
Look at
/etc/default/grub.
Set
GRUB_TIMEOUT_STYLE=menu
and a non‑zero timeout.
4 Windows entry boots to “file not found” Wrong EFI path
(/EFI/Microsoft/
Boot/bootmgfw.efi
).
Verify path on ESP
(/boot/efi/EFI/
Microsoft/Boot/
).
Edit custom entry or
re‑run sudo
update-grub
.
5 error: no such
device

during boot
Root UUID in GRUB entry no longer matches actual partition (e.g., after cloning). Compare blkid
output with
grub.cfg entry.
Update
/etc/fstab
and
GRUB_CMDLINE_LINUX
or run
sudo update-grub.
6 “failed to load initrd” Initramfs file missing (perhaps removed). ls /boot/initrd.img-* Reinstall kernel package
(sudo apt
install --reinstall
linux-image-$(uname -r)
).
7 “cannot find module ‘linux’” linux
module missing from GRUB (usually a BIOS issue).
ls /boot/grub/i386-pc/
– look for
linux.mod.
Reinstall GRUB core modules
(sudo grub-install).
8 error: unknown
filesystem
GRUB cannot read the filesystem (e.g., Btrfs driver missing). insmod btrfs
manually inside GRUB.
Install
grub2‑btrfs‑mod
or move /boot to ext4.
9 error: file
'/boot/efi/EFI/
ubuntu/grub.cfg'
not found
ESP not mounted at
/boot/efi.
mount grep efi.
10 grub>
prompt appears instead of menu after kernel update
GRUB_DISABLE_SUBMENU=true
but
10_linux
still creates submenus.
Look at
/boot/grub/grub.cfg.
Remove
GRUB_DISABLE_SUBMENU
or adjust theme
that expects submenus.

16. Common Errors & How to Fix Them – Full Matrix (Expanded)

Error BIOS UEFI Fix
no such partition Wrong set root in rescue. Wrong ESP partition. Use ls to locate the correct (hdX,gptY) and set root accordingly.
unknown filesystem Missing insmod for partition type (e.g., insmod ext2). Missing insmod for fat. Load the correct module (insmod ext2, insmod part_gpt).
invalid signature (Secure Boot) Not applicable. Kernel not signed. Sign kernel or disable Secure Boot.
cannot find device Disk identifier changed after cloning. Same issue, but also check efibootmgr. Re‑install GRUB to the correct disk (grub-install /dev/sdb).
error: file '/boot/grub/i386-pc/normal.mod' not found Core image cannot find its modules (mismatched prefix). Same in UEFI (different path). Set correct GRUB_PREFIX by reinstalling GRUB.
grub> loadfont /boot/grub/font.pf2 fails Font missing (maybe removed). Same. Reinstall grub-common (contains default fonts).
error: file '/boot/vmlinuz-…' not found Kernel removed. Same. Reinstall kernel package.
grub rescue> help shows only ls and set Core modules not loaded. Same. Load normal module (insmod normal).
grub> prompt shows “no such command ‘linux’ Missing linux module (maybe not loaded). Same. insmod linux before trying linux command.

17. Tools

Tool What it does Typical usage
boot-repair One‑click automatic repair of GRUB (both BIOS & UEFI). sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt install boot-repair && boot-repair
grub‑customizer GUI for editing /etc/default/grub and custom entries. sudo apt install grub-customizer
efibootmgr Manipulate UEFI boot variables. sudo efibootmgr -o 0000,0001
grub‑probe Query GRUB about devices, file locations. sudo grub-probe -vv /boot/vmlinuz-$(uname -r)
grub‑editenv Read/write GRUB environment block (/boot/grub/grubenv). sudo grub-set-default 2
sbsigntool Sign kernels/GRUB modules for Secure Boot. sbsign --key MOK.priv --cert MOK.der --output shimx64.efi shimx64.efi

18. Backup, Restore, and Version‑Control of GRUB

18.1 Simple backup

sudo cp -a /etc/default/grub /etc/default/grub.bak
sudo cp -a /etc/grub.d/ /etc/grub.d.bak/
sudo cp -a /boot/efi/EFI/ubuntu/ /boot/efi/EFI/ubuntu.bak/

18.2 Using git (nice for experimentation)

cd /etc
sudo git init
sudo git add grub.d/ default/grub
sudo git commit -m "Initial GRUB config"
# After each change:
sudo git add -A
sudo git commit -m "Custom Windows entry"

Now you have a history of every change and can revert easily:

sudo git checkout HEAD~1 /etc/default/grub
sudo update-grub
sudo rsync -aAXv / /mnt/backup --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"}

This captures /etc, /boot, and the ESP.

18.4 Restoring GRUB after a disaster

  1. Boot live USB.
  2. Mount and chroot (see § 13.2).
  3. Restore files from backup (/boot/grub/, /etc/default/grub, /etc/grub.d/).
  4. Run sudo update-grub.

18.5 Using Git for incremental changes

cd /etc
sudo git init
sudo git add default/grub grub.d/
sudo git commit -m "Initial GRUB config"
# After each edit:
sudo git commit -am "Added custom entry for X"

Now you can git log to see every tweak you made over time.

19. Cheat‑Sheet – One‑Page Command Summary

Goal Command
Reinstall GRUB (BIOS) sudo grub-install /dev/sda && sudo update-grub
Reinstall GRUB (UEFI) sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu && sudo update-grub
Regenerate menu sudo update-grub
Set default entry (by name) sudo grub-set-default "Advanced options for Ubuntu>Ubuntu, with Linux 6.5.0-28-generic"
Add a custom entry Edit /etc/grub.d/40_customsudo update-grub
Change timeout Edit GRUB_TIMEOUT= in /etc/default/grubsudo update-grub
Change background only Set GRUB_BACKGROUND="/path/to/img"sudo update-grub
Enroll MOK (Secure Boot) sudo mokutil --import MOK.der (reboot, follow prompts)
List EFI boot entries sudo efibootmgr -v
Create new EFI entry sudo efibootmgr -c -L "Ubuntu" -l '\EFI\ubuntu\shimx64.efi'
Rescue from “GRUB rescue>” (BIOS) set root=(hd0,msdos1); set prefix=(hd0,msdos1)/boot/grub; insmod normal; normal
Rescue from “GRUB rescue>” (UEFI) set root=(hd0,gpt1); set prefix=(hd0,gpt1)/EFI/ubuntu; insmod normal; normal
Live‑USB chroot (UEFI) See § 13.2 (mount + bind + chroot /mnt).
Clean old kernels (free /boot) sudo apt autoremove --purge
Run OS‑prober manually sudo /etc/grub.d/30_os-prober
Sign a kernel for Secure Boot sudo sbsign --key MOK.priv --cert MOK.der --output /boot/vmlinuz‑signed /boot/vmlinuz-…
# Install GRUB (BIOS)
sudo grub-install /dev/sda
sudo update-grub

# Install GRUB (UEFI)
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu
sudo update-grub

# Edit main config
sudo vim /etc/default/grub
# → change variables, then:
sudo update-grub

# Add custom entry
sudo vim /etc/grub.d/40_custom
# (add menuentry block)
sudo update-grub

# Rescue from "grub rescue>"
grub rescue> ls
grub rescue> set root=(hd0,msdos1)
grub rescue> set prefix=(hd0,msdos1)/boot/grub
grub rescue> insmod normal
grub rescue> normal

# Live‑USB chroot (UEFI)
sudo mount /dev/sda2 /mnt
sudo mount /dev/sda1 /mnt/boot/efi
for d in /dev /proc /sys; do sudo mount --bind $d /mnt$d; done
sudo chroot /mnt
# now reinstall:
grub-install /dev/sda
update-grub
exit
sudo reboot

# Secure‑Boot: enroll MOK
sudo mokutil --import MOK.der
# Sign a kernel
sudo sbsign --key MOK.priv --cert MOK.der --output /boot/vmlinuz‑signed /boot/vmlinuz‑<ver>

# EFI boot order
sudo efibootmgr -v
sudo efibootmgr -o 0002,0001   # Windows first, then Ubuntu

Final Thoughts

GRUB is a critical piece of the boot chain, but it is also highly configurable. By keeping all changes in /etc/default/grub, /etc/grub.d/, and using tools like boot-repair or grub‑customizer, you can tailor the boot experience to your exact needs while preserving a safety net via backups and version control.

Whenever you modify partitions, install new kernels, or switch between BIOS and UEFI, remember to regenerate the GRUB configuration (sudo update-grub) and, if necessary, re‑install the appropriate GRUB flavour. With the troubleshooting matrix above, you should be able to recover from most boot‑related mishaps on Ubuntu 22.04 LTS and newer.

Happy booting!

Read next

Automating GRUB Configuration Across Linux Distributions

In this post, we’re going to explore the grub.sh script, which is designed to handle the configuration and hardening of GRUB across various Linux distributions. We’ll go over each line of the script to understand what it does and how it contributes to the overall configuration.