Restore GPT/EFI partition table as well as grub on Linux

The Linux operating system, especially in the early days, was considered unforgiving: when you start fiddling with something there is a non-negligible chance that you will need a backup so that you can recover from your mistakes.

In this post, I wanted to share a bunch of commands that I found useful while moving my Linux box to encrypted partitions.

I am going to assume familiarity with the (linux) command line and the concepts of a partition table and a boot loader.

With great power comes great precaution

Changes to hard drive configuration cannot be performed while the system is running - you will need a bootable USB flash drive containing any of these Live Linux Distributions.

It is a wise choice to pick the one that matches what you have installed on disk if you are recovering from a previous mistake. For the purpose of this post, I will use Manjaro Live because I use Manjaro i3 Community Edition.

For writing the downloaded ISO to a USB drive I use isousb. Arch (on which Manjaro is based) gives you access to a plethora of great little hacks tools. Simple and effective.

Another thing you want to do before running any of the commands is to take a full-disk snapshot 1 but I am not going to go deep into that.

Backing up a GPT partition table

After booting up Manjaro Live, I can use sgdisk 2 for storing the GUID Partition Table (GPT) in a safe place:

sudo sgdisk --backup=/path/to/usb/gpt_$(date --iso-8601=date) /dev/sda

You can use the gdisk program family only with GPT partition tables and not all tables, especially legacy ones, are GPT 3

Restoring the partition table

Let's say one day while fooling around with gparted you inadvertently click on the "Create Partition Table..." menu button. Warnings are on the screen, but you persist in your mischief by applying the changes.

It goes without saying that even a seasoned Linux user makes mistakes. Fortunately, we have a backup that we can restore from:

sudo sgdisk --load-backup=/path/to/usb/gpt_20210101 /dev/sda

Easy-peasy reboot and...boom It does not boot.

The partition table is only half of the story, if you are using GPT it is likely your firmware is using the Unified Extensible Firmware Interface - UEFI for short.

Restoring UEFI requires access to the file system 4 - we need to chroot.

Chroot

The Arch wiki page has the best definition here:

A chroot is an operation that changes the apparent root directory for the current running process and their children.

We will mount all the relevant partitions to a directory (usually /mnt) and then execute commands from it. This step depends on how the partitions were organized in the first place (gparted can shed some light on this).

I have mainly seen two setups:

  • /boot on one partition and root on another
    /           # /dev/sdX
    └── boot    # /dev/sdY and EFI System Partition
    
  • only /boot/efi on a separate partition and root (including /boot on another)
    /           # /dev/sdX
    └── boot
        └── efi # /dev/sdY and EFI System Partition
    

The former is what I have got so these are the commands I needed to run:

mkdir -p /mnt
sudo mount /dev/sdX /mnt
sudo mount /dev/sdY /mnt/boot

cd /mnt
mount -t proc /proc proc/
mount -t sysfs /sys sys/
mount -o bind /dev dev/
mount -o bind /sys/firmware/efi/efivars sys/firmware/efi/efivars/

When your live distro contains helpers like arch-chroot or manjaro-chroot you can simply:

sudo mount /dev/sdX /mnt
mkdir -p /mnt/boot
sudo mount /dev/sdY /mnt/boot

sudo manjaro-chroot /mnt /bin/bash # I prefer bash over sh

Chroot and LUKS

An additional series of commands are necessary if your partitions are encrypted. Without going too much into details again, LUKS is the most common way to encrypt your disk on Linux.

If that is you, do the following:

sudo cryptsetup luksOpen /dev/sdX cryptoroot
sudo mount /dev/mapper/cryptoroot /mnt
sudo cryptsetup luksOpen /dev/sdY cryptoboot
sudo mount /dev/mapper/cryptoboot /mnt/boot

sudo manjaro-chroot /mnt /bin/bash

Restoring the EFI

Finally, we can fix our booting issues. After chroot-ing (you'll usually notice the different terminal prompt), execute:

sudo grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Grub --recheck
sudo update-grub # this is optional but recommended

A gotcha to be aware of is that --efi-directory specifies where grub's EFI will be created, not the location of /boot/efi .

Consequently the resulting folder structure for a setup where /boot also serves an EFI System Partition (the first above) is:

/boot/
├── EFI
│   └── Grub # this matches the --bootloader-id
├── grub
└── ...

In the other scenario you will end up with something inside /boot/efi/EFI instead.

Finding safety in the dragon's nest

While technically you should be good to boot now, sometimes this still does not happen mainly because the computer firmware's boot manager does not know of the existence of EFI/Grub/grubx64.efi .

Once again, that is entirely dependent on the machine but on a Dell you will have to enter the BIOS setup (F12) and figure your way around "Boot Sequence" and "Add Boot Option".

This last piece of information also concludes the post, happy linuxing!


  1. my favourite tool for that is Clonezilla.

  2. for way more detail check this very instructive post.

  3. check MBR vs GPT - Things to Know When Partitioning.

  4. I am not entirely sure about the correctness of this sentence but the commands work. Checking UEFI Booting also seems to confirm.