3

This is a followup question after

How to Make BIOS/UEFI Flash Drive with Full Disk Encryption

I have followed the answers in this question and created an encrypted full installation of Ubuntu 20.04 in an USB flash drive that booted from either from BIOS or from UEFI configured computers.

Over time I have used this USB flash drive installed Ubuntu in a BIOS only computer and kept it updated with security and other updates. Now the UEFI computer won't boot from this USB drive. When I select Ubuntu from the GRUB it shows me the error:

error file '/vmlinuz-5.8.0-48-generic' not found.
you need to load the kernel first. 

This specific kernel is not installed as it was superseded by newer kernels during security and other updates.

How do I regain the UEFI boot functionality for this USB based Ubuntu installation?

1 Answer 1

3

The Tale of Two grub.cfg

This USB flash drive installation has two separate grub.cfg in two locations. One is used for booting BIOS only computers and the other is used for booting UEFI computers. When new kernels are installed and old ones removed the installation process updates only the grub.cfg file that was used for the current boot. As a result, the two grub.cfg files get out of sync.

The file needed for BIOS boot is at:

/boot/grub/grub.cfg

The file needed for UEFI boot is at:

/boot/efi/boot/grub/grub.cfg

Note, since this is an encrypted installation, the boot partition has the mount point /boot and the ESP partition has the mount point /boot/efi.

Solution

Replace the older grub.cfg with the newer version. In my case, the BIOS one was newer. So I used the command:

sudo cp /boot/grub/grub.cfg /boot/efi/boot/grub/grub.cfg

This fixed the problem for now.

A Script

I wrote a small script called grubsync.sh to copy and replace the older grub.cfg with the newer one, if they are different based on which mode (BIOS or UEFI) the USB booted from.

#!/bin/bash
# Date: Jun 18, 2022
# Purpose: USB123 copy grub.cfg from boot partition grub.cfg to ESP partition
#      or vice versa if grub.cfg is newer
 
# Only run if the computer is USB123
if [[ ! $HOSTNAME == USB123 ]]; then    # Not on right computer
    echo "This is $HOSTNAME, expected USB123, exiting..."
    exit 1
fi

if [[ "$EUID" -ne 0 ]]
    then echo "This script must run with sudo, exiting..."
    exit 1
fi

BOOTgrubCFG="/boot/grub/grub.cfg"
ESPgrubCFG="/boot/efi/boot/grub/grub.cfg"

if cmp --silent -- "$BOOTgrubCFG" "$ESPgrubCFG"; then
    echo "files contents are identical, exiting..."
    exit 1
fi

if ls /sys/firmware/efi; then   # If TRUE then UEFI Boot
    if [[ "$BOOTgrubCFG" -ot "$ESPgrubCFG" ]]; then    # '-ot` means older than
        cp -f "$BOOTgrubCFG" "$BOOTgrubCFG".old 
        cp -f "$ESPgrubCFG" "$BOOTgrubCFG"
        echo "$BOOTgrubCFG" was old, kept with .old ext
        echo "$BOOTgrubCFG" was replaced with "$ESPgrubCFG". 
    fi
else 
    if [[ "$ESPgrubCFG" -ot "$BOOTgrubCFG" ]]; then
        cp -f "$ESPgrubCFG" "$ESPgrubCFG".old 
        cp -f "$BOOTgrubCFG" "$ESPgrubCFG"
        echo "$ESPgrubCFG" is old, kept with .old ext
        echo "$ESPgrubCFG" was replaced with "$BOOTgrubCFG".        
    fi
fi

The hostname of my USB full installation is USB123. Change it before you run the script. You will need to run this script with sudo prefix.

As of now, I have to run this script every time there is a kernel update. With a few tweaks, I may be able to run it at every boot using crontab.

Hope this helps

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .