This page looks best with JavaScript enabled

Recovering UEFI on Linux/Windows/FreeBSD

 ·  πŸŽƒ kr0m

Modern motherboards come with UEFI as the boot system, which brings several advantages such as the ability to boot an OS without a bootloader, support for GPT partitions, network capabilities from the boot itself, among others.

UEFI uses a partition to store EFI images, and if this partition is deleted, it needs to be restored in order to boot. In this guide, I will explain this procedure in both Linux and Windows 10.

First, we need to understand that there is a partition where all the boot images will reside (/boot/efi). As long as this vfat partition exists and has the correct content, both the BIOS-UEFI and Grub will be able to boot these images. During the UEFI boot process, the main boot loader /EFI/BOOT/BOOTX64.EFI is loaded, and it is responsible for finding the rest of the UEFI images for each operating system.

In this article, we will describe how to do it on various operating systems:


Linux

In Linux, it is as simple as chrooting into the system partition and reinstalling grub.
The partitions on my system are:

fdisk -l /dev/sda

Disposit. Comienzo Final Sectores TamaΓ±o Tipo
/dev/sda1 2048 4095 2048 1M Arranque de BIOS
/dev/sda2 4096 413695 409600 200M Sistema EFI
/dev/sda3 413696 2510847 2097152 1G Sistema de ficheros de Linux
/dev/sda4 2510848 468862094 466351247 222,4G Sistema de ficheros de Linux

Chroot into the system partition:

mount /dev/sda4 /mnt/gentoo
mount /dev/sda3 /mnt/gentoo/boot
mount /dev/sda2 /mnt/gentoo/boot/efi

mount -t proc none /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev

chroot /mnt/gentoo /bin/bash
env-update
source /etc/profile
export PS1="(chroot) $PS1"

We mount the directory /sys/firmware/efi/efivars with the rw option to be able to write to it:

mount -o remount,rw /sys/firmware/efi/efivars

We reinstall the EFI and regenerate the grub config:

grub-install --target=x86_64-efi --efi-directory=/boot/efi /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

We exit the chroot:

exit

We reboot:

reboot

NOTE: We will have to compile Grub as follows

vi /etc/make.conf
GRUB_PLATFORMS="efi-64"

Windows

In Windows, we need to boot from the installation CD, access the command line, and reinstall the EFI image.

We start diskpart

diskpart

We select the disk where the EFI partition is located:

list disk
select disk 0

We select the partition where the EFI partition is located and assign it the letter A:

list partition
select partition 1
assign letter=A

We select the partition where Windows is installed and assign it the letter C:

list partition
list vol
select vol 3
assign letter=C
exit

We change to the EFI directory and copy the necessary files:

cd /d a:\EFI\Microsoft\Boot
bootrec /fixboot
bcdboot c:\Windows /l en-gb /s a: /f ALL

After this, we can run grub-mkconfig -o /boot/grub/grub.cfg and we will get an additional entry for Windows.


FreeBSD

In FreeBSD, it is even easier, we just copy the efi files from the memstick to the GPT partition, for this, we download the iso image and dump it to a USB to boot from it:

We dump the image:

dd if=FreeBSD-12.1-RELEASE-amd64-mini-memstick.img of=/dev/XXX bs=1M conv=sync

When booting, select the “shell” option and locate the GPT partition:

gpart list

A efi type entry should appear:

3. Name: ada0p3
   type: efi

We mount the partition to a mounted directory using unionfs to make it writable:

mkdir /tmp/mnt
mount_unionfs /tmp/mnt /mnt/
mount -t msdosfs /dev/ada0p3 /mnt

We create the directory where we will copy the efi images and copy those images:

mkdir /mnt/EFI/FreeBSD
cp /boot/*.efi /mnt/EFI/FreeBSD/

We check the UEFI status at this moment:

efibootmgr -v

We insert a new entry:

efibootmgr --create --activate --label FreeBSD --loader /dev/ada0p3:/EFI/FreeBSD/boot1.efi

If we add an incorrect entry and want to remove it, we execute:

efibootmgr -B ID

For more information about efibootmgr and UEFI on FreeBSD:
https://www.freebsd.org/cgi/man.cgi?query=efibootmgr&sektion=8&manpath=freebsd-release-ports
https://www.freebsd.org/cgi/man.cgi?query=uefi&sektion=8&manpath=freebsd-release-ports


If we also have Linux installed and use Grub as the bootloader, we need to manually add an entry from Linux:

mount -o remount,rw /sys/firmware/efi/efivars

vi /etc/grub.d/40_custom

#!/bin/sh
exec tail -n +3 $0
menuentry "FreeBSD chainloader" {
        insmod part_gpt
        insmod fat
        set root='hd0,gpt3'
        chainloader /efi/freebsd/boot1.efi
}

We install and regenerate the Grub configuration:

grub-install --target=x86_64-efi --efi-directory=/boot/efi /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

If you liked the article, you can treat me to a RedBull here