, 2 min read

Configure boot settings in UEFI

Original post is here eklausmeier.goip.de/blog/2020/08-29-configure-boot-settings-in-uefi.


Main source for trouble-shooting is Arch-Wiki UEFI. It describes the commands:

  1. bcfg within UEFI shell
  2. Linux command efibootmgr

1. It is ighly recommended to install the UEFI-shell, which is in package edk2-shell. On Asrock copy

cp -p /usr/share/edk2-shell/x64/Shell_Full.efi /boot/shellx64.efi

So name of the shell should change to shellx64.efi, at least on Asrock systems A300M and X570.

Create UEFI boot entry where boot entry says: Run UEFI-shell with parameter fs0:\\archlinux-fallback.nsh.

efibootmgr -c -d /dev/nvme0n1 -l /shellx64.efi -L Shellx64_u -v -u "fs0:\\archlinux-fallback.nsh"

This script, executed by UEFI-shell, is as follows: cat archlinux.nsh

fs1:
vmlinuz-linux root=UUID=63669b64-5753-44a6-8626-561a6c98ab5b rw  cryptdevice=/dev/disk/by-uuid/9b0766ca-06ce-41d6-9b46-04c66573f3aa:Samsung2TB ip=192.168.0.20:192.168.0.20:192.168.0.1:255.255.255.0:chieftec:eth0:none initrd=\initramfs-linux.img

The first statement "changes" to disk 21, i.e., fs1:. This is only required if your kernel is not on fs0:, disk #1. This is analogoues to the old DOS ways of specifying A:, B:, C:. This UEFI-shell script is very similar to a GRUB entry. Important to note is that vmlinuz-linux is directly "executable" via UEFI-shell. vmlinuz-linux takes arguments which tell where to find root directory, initial RAM disk, and possibly any information for entering decrypt password for an encrypted boot device.

2. Instead of

efibootmgr -c -d /dev/nvme0n1 -l /shellx64.efi -L Shellx64_u -v -u "fs0:\\archlinux-fallback.nsh"

one could also configure UEFI boot entry as below, although more complicated, but better understanding what exactly is done behind the scenes:

printf "fs0:\\\archlinux-fallback.nsh" | ~klm/c/2ndzero | efibootmgr -c -d /dev/nvme0n1 -l /shellx64.efi -L Shellx64 -v -@ -

C program 2ndzero adds hex 00 every second character. Below program adds 0x00 after each character:

/* Read stdin and insert hex zero after every character */
#include <stdio.h>

int main (int argc, char *argv[]) {
        int c;

        while ((c = getchar()) != EOF) {
                putchar(c);
                putchar('\0');
        }

        return 0;
}

3. Some useful efibootmgr examples. Show all UEFI boot variants:

efibootmgr -v

Looking in hex into boot configuration for 0003:

# xxd /sys/firmware/efi/efivars/Boot0003-8be4df61-93ca-11d2-aa0d-00e098032b8c
00000000: 0700 0000 0100 0000 4e00 7300 7400 6100  ........N.s.t.a.
00000010: 7200 7400 7500 7000 2e00 6e00 7300 6800  r.t.u.p...n.s.h.
00000020: 0000 0401 2a00 0100 0000 0008 0000 0000  ....*...........
00000030: 0000 0000 0800 0000 0000 aa20 e196 a404  ........... ....
00000040: 834e 9199 f4f3 a1e9 2bf2 0202 0404 2000  .N......+..... .
00000050: 5c00 7300 6800 6500 6c00 6c00 7800 3600  \.s.h.e.l.l.x.6.
00000060: 3400 2e00 6500 6600 6900 0000 7fff 0400  4...e.f.i.......
00000070: 6600 7300 3100 3a00 5c00 7300 7400 6100  f.s.1.:.\.s.t.a.
00000080: 7200 7400 7500 7000 2e00 6e00 7300 6800  r.t.u.p...n.s.h.

Create an UEFI boot entry with just an UEFI-shell:

efibootmgr -c -d /dev/nvme0n1 -l /shellx64.efi -L uefi_shell -v

Delete an UEFI boot entry, in this case number six:

efibootmgr -B -b 6

Delete entry #2:

efibootmgr -B -b 2

Rearrange order of boot entries, and mark entry #9 as active:

efibootmgr -o 5,9,a