Rebuilding my EFI partition
This is a short one, I promise.
I just installed Windows on my desktop machine (for work, believe it or not?!), and… Let’s just say that the Windows installer UI isn’t great when it comes to identifying the different partitions and drives on the machine, and terrible UI usually leads to mistakes. Like nuking the EFI partition on my main Ubuntu drive rather than on the drive where I wanted to install Windows. Whoops?!
UEFI, or EFI, is “the BIOS” (it’s not, it’s similar to calling LibreOffice Writer “Word”), or more plainly, the program that first runs on your computer before the operating system, AKA the firmware. It knows which OS is on your machine by looking at all the drives for specific partitions onto which your OS installer will drop its own EFI program on how to boot it, and register it into the firmware. You can have multiple EFI programs on a single partition, but also multiple partitions, all of them with their own sets of program. That’s OK, the firmware can handle it.
It’s actually fairly easy to fix if you know what you’re doing, which I sort of do as I’ve been there before, a couple of times. At least next time I’ll have an easy reference to get to.
Grab a Ubuntu install USB stick, go through the nice graphical installer thing until it asks you whether you want to install or try. You want the latter. You probably can even ignore the installer altogether if you’re using a QWERTY keyboard, which I’m not.
Now that you have a full Linux system to work with, the first task will be to
recreate the disk partition itself. I used the Disks application for this,
because it actually tells me a lot of things about the disks so I knew I was
operating on the right one. You want to create a partition on the disk itself
(rather than a LVM volume), formatted using the FAT filesystem. In the
properties of that partition, you’ll have a field called UUID, that should look
like 8F6A-5D0E.
Now, I used the LVM install way back when I installed my desktop Ubuntu, which
means that my disk has now three partitions: a FAT one that we just created, an
ext4 one that’s normally mounted on /boot, and a LVM partition, with a
couple of volumes in it, one of them being my Ubuntu root.
Conceptually, what remains to be done is to chroot into my Ubuntu root, from
where I can just point it to the new EFI partition and use a single command to
tell it to reinstall itself onto the computer. Conceptually simple, barely more
complicated in actuality.
chroot is a program that allows you to run some commands pretending that a
given folder is actually the root of your filesystem. Since all your OS
programs are in specific locations on your filesystem, this allows for a
lightweight form of “OS impersonation”. This allows me to use my desktop
Ubuntu programs rather than the ones from the installer I booted from.
First, we need to actually mount our root. For this I simply went to
the file explorer, and went through all available volumes until I found the
right one. Do remember to eject the other ones! Once you’ve identified it,
you’ll probably see that your current path is something like
/media/ubuntu/c3dd86ab-87e5-4d1a-9002-b741c8df2b5b.
Before we can chroot into it, we need to prepare it a little bit, making sure that the future root sees some special virtual filesystems (not backed by your drives, but rather describing live properties of the system — it’s complicated…), using bindmounts.
MOUNTPOINT=/media/ubuntu/c3dd86ab-87e5-4d1a-9002-b741c8df2b5b
sudo mount --bind /proc $MOUNTPOINT/proc # Probably not strictly necessary
sudo mount --rbind /dev $MOUNTPOINT/dev
sudo mount --rbind /sys $MOUNTPOINT/sys
Note the use of --rbind, particularly important in the case of /sys. It
means that any other filesystem mounted within /sys will also be bound in
the destination. The one we want in particular is
/sys/sys/firmware/efi/efivars, as it is the way to talk to the firmware, and
register EFI programs.
Once that’s done, we can finally chroot!
sudo chroot $MOUNTPOINT
Careful, you’re now running as root on your home system!
Use whatever editor is available on your system to edit /etc/fstab, looking
for a line looking like this:
# /boot/efi was on /dev/nvme0n1p1 during curtin installation
/dev/disk/by-uuid/1234-ABCD /boot/efi vfat defaults 0 1
Replace the old UUID (here 1234-ABCD) with the one of the partition we
created earlier, save, exit, and then run the final stretch:
mount -a # Mounts the disks, in particular /boot and the newly configured /boot/efi
grub-install
exit # exits the chroot
Just like that, your EFI firmware once again knows about your Ubuntu install. This would likely work very similarly for most other Linux distros.