Creating an EFI partition with all the convenient tools (rEFInd, Grub, memtest, …)

  • Hardware is of type x86_64.
  • Secure boot is not used (no key management, or signing of binaries).
  • Following script fragments are using FreeBSD commands.
    For example the tar command is based on libarchive and is able to process multiple archive format, including zip files.
  • The $EFI environment variable is to be defined and point to the EFI directory in the mounted ESP partition.
rEFInd
rEFInd with multi-loaders theme

Configuration

When using hypervisor such as Bhyve, the provided UEFI is not able to store data in NVRAM, so configuring boot information is not possible, it will be necessary to store the boot loader at the default emplacement EFI/BOOT/bootx64.efi. In our case shim can be use to reconstruct a boot configuration (using BOOT.CSV)

Installing shim as default boot loader
1
2
mkdir -p ${EFI}/BOOT
cp ${EFI}/shim/fbx64.efi ${EFI}/BOOT/bootx64.efi

rEFInd

We apply our multi-loaders theme which basically:

Installing theme in rEFInd
1
tar xvfz multi-loaders.tgz -C ${EFI}/refind/ 

rEFInd is configured using the refind.conf file, we will load the default configuration and the additional theme before applying our custom configuration (here selecting a subset of tools).

${EFI}/refind/refind.conf
1
2
3
4
5
include refind.dflt.conf             # Load default configuration
include multi-loaders/theme.conf     # Load multi-loaders boot theme

# Custom settings below
showtools netboot, memtest, shell, bootorder, shutdown, reboot, firmware

Installation

If the disk is not partitioned, you can use GParted to create the GPT partition scheme as well as the EFI partition (ESP).

For the EFI partition keep it mind the following characteristics:

rEFInd

Installing rEFInd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version=0.13.0
file=refind-bin-${version}.zip
project=refind
path=projects/${project}/files/${version}/${file}

curl -L -s http://sourceforge.net/${path}/download |
   tar xvfz - -C ${EFI} --strip-components 1 refind-bin-${version}/refind

# Rename sample as default configuration
# so it can be included in `refind.conf` with: `include refind.dflt.conf`
mv -i ${EFI}/refind/refind.conf-sample ${EFI}/refind/refind.dflt.conf

# Add a fallback entry for `shim`
echo "refind_x64.efi,rEFInd Boot Manager,,This is the boot entry for rEFInd" |
    iconv -f UTF-8 -t UTF-16LE > ${EFI}/refind/BOOT.CSV

IPXE

Installing iPXE
1
2
3
4
5
pkg install ipxe
mkdir -p ${EFI}/ipxe ${EFI}/tools

cp /usr/local/share/ipxe/*.efi-{i386,x86_64} ${EFI}/ipxe/
cp /usr/local/share/ipxe/ipxe.efi-x86_64 ${EFI}/tools/ipxe.efi

Grub

Installing Grub
1
2
3
4
5
6
7
8
9
10
11
12
13
# For current version see and ajust `version` from
#  https://packages.ubuntu.com/groovy/amd64/grub-efi-amd64-bin/download
version=2.04-1ubuntu35_amd64
package=grub-efi-amd64-bin
origin=grub2
file=${package}_${version}.deb
path=pool/main/${origin%"${origin#?}"}/${origin}/${file}

mkdir -p ${EFI}/grub

curl -s http://fr.archive.ubuntu.com/ubuntu/${path} |
  tar Oxfz - data.tar.xz                            |
  tar xzvf - --strip-components 6 -C ${EFI}/grub/ '*/monolithic/'

Super Grub 2 Disk

Installing Super Grub
1
2
3
4
5
6
7
8
9
10
version=2.04s1
dir=super_grub2_disk_${version}
file=super_grub2_disk_standalone_x86_64_efi_${version}.EFI
project=supergrub2
path=projects/${project}/files/${version}/${dir}/${file}

mkdir ${EFI}/super-grub

wget -O ${EFI}/super-grub/super-grub.efi \
	https://sourceforge.net/${path}/download

shim

Installing shim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# For current version see, and ajust `version` from
#  https://packages.ubuntu.com/groovy/amd64/shim/download
version=15+1552672080.a4a1fbe-0ubuntu2_amd64
package=shim
origin=shim
file=${package}_${version}.deb
path=pool/main/${origin%"${origin#?}"}/${origin}/${file}

mkdir -p ${EFI}/shim

curl -s http://fr.archive.ubuntu.com/ubuntu/${path} |
  tar Oxfz - data.tar.xz                            |
  tar xzvf - --strip-components 4 -C ${EFI}/shim/ usr/lib/shim

# Remove ubuntu fallback entry
rm ${EFI}/shim/BOOTX64.CSV

GPT fdisk

Installing GPT fdisk
1
2
3
4
5
6
7
8
9
10
version=1.0.4
file=gdisk-efi-${version}.zip
project=gptfdisk
dir=${project}/${version}/gdisk-binaries
path=projects/${project}/files/${dir}/${file}

mkdir -p ${EFI}/tools

curl -L -s https://sourceforge.net/${path}/download |
  tar xvzf - --strip-components 1 -C ${EFI}/tools/ gdisk-efi/gdisk_x64.efi

UEFI Shell Disk Utilities

Installing UEFI Shell Disk Utilities
1
2
3
4
5
6
7
8
9
# Password: EFIDiskUtil#1.3
file=efi-disk-utility-v-1-3.zip
path=content/dam/develop/public/us/en/documents/${file}

mkdir -p ${EFI}/tools

curl -s https://software.intel.com/${path} |
  tar -Oxzf $file 'EfiDiskUtilityV*.zip'   |
  tar xvfz - -C ${EFI}/tools/ --strip-components 1 binaries

Memtest

Installing memtest86
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Download and extract memtest86-usb.img
curl -s https://www.memtest86.com/downloads/memtest86-usb.zip |
  tar xvfz - memtest86-usb.img

# Loopback mount EFI partition from memtest86-usb.img
mnt=`mktemp -d tmpdir.XXXXXX`
dev=`mdconfig -a -t vnode -f memtest86-usb.img`
mount_msdosfs /dev/${dev}p2 ${mnt}

# Copy files to new location, using `memtest86` as destination
mkdir -p ${EFI}/memtest86
cp -r ${mnt}/EFI/BOOT/* ${EFI}/memtest86/

# Cleanup
umount ${mnt}
rmdir ${mnt}
mdconfig -du ${dev}
rm memtest86-usb.img