Unified Extensible Firmware Interface

From ArchWiki
(Redirected from Efibootmgr)

The Unified Extensible Firmware Interface (UEFI, successor of the EFI) is an interface between operating systems and firmware. It provides a standard environment for booting an operating system and running pre-boot applications.

It is distinct from the "MBR boot code" method that was used by legacy BIOS systems. See Arch boot process for their differences and the boot process using UEFI. To set up UEFI boot loaders, see Arch boot process#Boot loader.

Note: Early vendor UEFI implementations may carry more bugs than their BIOS counterparts. Consider using legacy BIOS booting for such systems if you encounter unsolvable issues.

UEFI versions

  • UEFI started as Intel's EFI in versions 1.x.
  • Later, a group of companies called the UEFI Forum took over its development, which renamed it as Unified EFI starting with version 2.0.
  • Unless specified as EFI 1.x, EFI and UEFI terms are used interchangeably to denote UEFI 2.x firmware.
  • Apple's EFI implementation is neither an EFI 1.x version nor UEFI 2.x version but mixes up both. This kind of firmware does not fall under any one (U)EFI specification and therefore is not a standard UEFI firmware. Unless stated explicitly, these instructions are general and some of them may not work or may be different in Apple Macs.

The latest UEFI specification can be found at https://uefi.org/specifications.

UEFI firmware bitness

Under UEFI, every program whether it is an OS loader or a utility (e.g. a memory testing or recovery tool), should be an EFI application corresponding to the UEFI firmware bitness/architecture.

The vast majority of x86_64 systems, including recent Apple Macs, use x64 (64-bit) UEFI firmware. The only known devices that use IA32 (32-bit) UEFI are older (pre 2008) Apple Macs, Intel Atom System-on-Chip systems (as on 2 November 2013)[1] and some older Intel server boards that are known to operate on Intel EFI 1.10 firmware.

An x64 UEFI firmware does not include support for launching 32-bit EFI applications (unlike x86_64 Linux and Windows versions which include such support). Therefore the EFI application must be compiled for that specific firmware processor bitness/architecture.

Note: Systems with IA32 UEFI require using a boot loader that supports mixed mode booting. For example, systemd-boot.
Warning: Starting with grub 2:2.06.r566.g857af0e17-1, GRUB's i386-efi target is broken so it cannot be used to boot on IA32 UEFI. See FS#79098.

Checking the firmware bitness

The firmware bitness can be checked from a booted operating system.

From Linux

On distributions running Linux kernel 4.0 or newer, the UEFI firmware bitness can be found via the sysfs interface. Run:

$ cat /sys/firmware/efi/fw_platform_size

It will return 64 for a 64-bit (x64) UEFI or 32 for a 32-bit (IA32) UEFI. If the file does not exist, then you have not booted in UEFI mode.

From macOS

Pre-2008 Macs mostly have IA32 EFI firmware while >=2008 Macs have mostly x64 EFI. All Macs capable of running Mac OS X Snow Leopard 64-bit Kernel have x64 EFI 1.x firmware.

To find out the arch of the EFI firmware in a Mac, type the following into the Mac OS X terminal:

$ ioreg -l -p IODeviceTree | grep firmware-abi

If the command returns EFI32 then it is IA32 (32-bit) EFI firmware. If it returns EFI64 then it is x64 EFI firmware. Most of the Macs do not have UEFI 2.x firmware as Apple's EFI implementation is not fully compliant with UEFI 2.x specification.

From Microsoft Windows

64-bit versions of Windows do not support booting on a 32-bit UEFI. So, if you have a 32-bit version of Windows booted in UEFI mode, you have a 32-bit UEFI.

To check the bitness run msinfo32.exe. In the System Summary section look at the values of "System Type" and "BIOS mode".

For a 64-bit Windows on a 64-bit UEFI it will be System Type: x64-based PC and BIOS mode: UEFI, for a 32-bit Windows on a 32-bit UEFI - System Type: x86-based PC and BIOS mode: UEFI. If the "BIOS mode" is not UEFI, then Windows is not booted in UEFI mode.

Linux kernel configuration options for UEFI

The required Linux Kernel configuration options[2] for UEFI systems are:

CONFIG_RELOCATABLE=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_X86_SYSFB=y
CONFIG_FB_SIMPLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y

UEFI Runtime Variables Support (efivarfs filesystem - /sys/firmware/efi/efivars). This option is important as this is required to manipulate UEFI runtime variables using tools like efibootmgr. The configuration option below has been added in kernel 3.10 and later.

CONFIG_EFIVAR_FS=y

UEFI Runtime Variables Support (old efivars sysfs interface - /sys/firmware/efi/vars). This option should be disabled to prevent any potential issues with both efivarfs and sysfs-efivars enabled.

CONFIG_EFI_VARS=n

GUID Partition Table (GPT) configuration option - mandatory for UEFI support

CONFIG_EFI_PARTITION=y

EFI mixed-mode support - to boot a x86_64 kernel on a IA32 UEFI.

CONFIG_EFI_MIXED=y
Tip: All of the above options are set accordingly in all officially supported kernels.

UEFI variables

UEFI defines variables through which an operating system can interact with the firmware. UEFI boot variables are used by the boot loader and used by the OS only for early system start-up. UEFI runtime variables allow an OS to manage certain settings of the firmware like the UEFI boot manager or managing the keys for UEFI Secure Boot protocol etc. You can get the list using:

$ efivar --list

UEFI variables support in Linux kernel

Linux kernel exposes UEFI variables data to userspace via efivarfs (EFI VARiable FileSystem) interface (CONFIG_EFIVAR_FS) - mounted using efivarfs kernel module at /sys/firmware/efi/efivars - it has no maximum per-variable size limitation and supports UEFI Secure Boot variables. Introduced in kernel 3.8.

Requirements for UEFI variable support

  1. Kernel should be booted in UEFI mode via EFISTUB (optionally using a boot manager) or by a UEFI boot loader, not via BIOS or CSM, or Apple's Boot Camp which is also a CSM.
  2. EFI Runtime Services support should be present in the kernel (CONFIG_EFI=y, check if present with zgrep CONFIG_EFI /proc/config.gz).
  3. EFI Runtime Services in the kernel SHOULD NOT be disabled via the kernel command line, i.e. noefi kernel parameter SHOULD NOT be used.
  4. efivarfs filesystem should be mounted at /sys/firmware/efi/efivars, otherwise follow #Mount efivarfs section below.
  5. efivar should list (option -l/--list) the UEFI variables without any error.

If UEFI Variables support does not work even after the above conditions are satisfied, try the below workarounds:

  1. If listing of the UEFI variables (efivar -l) leads to efivar: error listing variables: Function not implemented and the system is booted into a realtime kernel, add efi=runtime to the kernel parameters and reboot (efivarfs functionality is disabled by default on those kernels).
  2. See #Userspace tools are unable to modify UEFI variable data for more troubleshooting steps

Mount efivarfs

If efivarfs is not automatically mounted at /sys/firmware/efi/efivars by systemd during boot, then you need to manually mount it to expose UEFI variables to userspace tools like efibootmgr:

# mount -t efivarfs efivarfs /sys/firmware/efi/efivars
Note: The above command should be run both outside (i.e. before) and inside the chroot, if any.

See efivarfs.html for kernel documentation.

Userspace tools

There are few tools that can access/modify the UEFI variables, namely

  • efivar — Library and Tool to manipulate UEFI variables (used by efibootmgr)
https://github.com/rhboot/efivar || efivar
  • efibootmgr — Tool to manipulate UEFI Firmware Boot Manager Settings
https://github.com/rhboot/efibootmgr || efibootmgr
  • uefivars — Dumps list of UEFI variables with some additional PCI related info (uses efibootmgr code internally)
https://github.com/fpmurphy/Various/tree/master/uefivars-2.0 || uefivars-gitAUR
  • efitools — Tools for manipulating UEFI secure boot platforms
https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git || efitools
  • Ubuntu's Firmware Test Suite — Test suite that performs sanity checks on Intel/AMD PC firmware
https://wiki.ubuntu.com/FirmwareTestSuite/ || fwts-gitAUR

efibootmgr

You will have to install the efibootmgr package.

Note:
  • If efibootmgr does not work on your system, you can reboot into #UEFI Shell and use bcfg to create a boot entry for the bootloader.
  • If you are unable to use efibootmgr, some UEFI firmwares allow users to directly manage UEFI boot entries from within its boot-time interface. For example, some firmwares have an "Add New Boot Option" choice which enables you to select a local EFI system partition and manually enter the EFI application location e.g. \EFI\refind\refind_x64.efi.
  • The below commands use rEFInd boot manager as example.

To add a new boot option using efibootmgr, you need to know three things:

  1. The disk containing the EFI system partition (ESP). E.g.: /dev/sda, /dev/nvme0n1.
  2. The partition number of the ESP on that disk. The Y in /dev/sdaY or /dev/nvme0n1pY.
  3. The path to the EFI application (relative to the root of the ESP)

For example, if you want to add a boot option for /efi/EFI/refind/refind_x64.efi where /efi is the mount point of the ESP, run

$ findmnt /efi
TARGET SOURCE    FSTYPE OPTIONS
/efi   /dev/sda1 vfat   rw,flush,tz=UTC

In this example, this indicates that the ESP is on disk /dev/sda and has partition number 1. The path to the EFI application relative to the root of the ESP is /EFI/refind/refind_x64.efi. So you would create the boot entry as follows:

# efibootmgr --create --disk /dev/sda --part 1 --loader /EFI/refind/refind_x64.efi --label "rEFInd Boot Manager" --unicode
# efibootmgr --create --disk /dev/nvme0n1p1 --loader /EFI/refind/refind_x64.efi --label "rEFInd Boot Manager" --unicode

See efibootmgr(8) or efibootmgr README for more info.

Note: UEFI uses backward slash \ as path separator but efibootmgr automatically converts UNIX-style / path separators.

Disable UEFI variable access

Access to the UEFI can potentially cause harm beyond the running OS level. Even hardware-level bricking is possible in some cases of poor UEFI implementation. [3]

So, as the UEFI variables access is not required for daily system usage, you may want to disable it, to avoid potential security breaches or accidental harm.

Possible solutions are:

  • Mount efivars in read-only mode using fstab. For example:
    efivarfs /sys/firmware/efi/efivars efivarfs ro,nosuid,nodev,noexec 0 0
  • Use the noefi kernel parameter to completely disable OS access to UEFI.
Note: UEFI userspace tools cannot be used with a such setup, so perform the all necessary configurations before. Also UEFI-related commands (e.g. systemctl reboot --firmware-setup) will not work either.

UEFI Shell

The UEFI Shell is a shell/terminal for the firmware which allows launching EFI applications which include UEFI bootloaders. Apart from that, the shell can also be used to obtain various other information about the system or the firmware like memory map (memmap), modifying boot manager variables (bcfg), running partitioning programs (diskpart), loading UEFI drivers, editing text files (edit), hexedit etc.

Obtaining UEFI Shell

You can obtain a BSD licensed UEFI Shell from the TianoCore EDK2 project:

Shell v2 works best in UEFI 2.3+ systems and is recommended over Shell v1 in those systems. Shell v1 should work in all UEFI systems irrespective of the spec. version the firmware follows. More information at ShellPkg and the EDK2 mailing list thread—Inclusion of UEFI shell in Linux distro iso.

Launching UEFI Shell

Few Asus and other AMI Aptio x64 UEFI firmware based motherboards (from Sandy Bridge onwards) provide an option called Launch EFI Shell from filesystem device. For those motherboards, copy the x64 UEFI Shell to the root of your EFI system partition, named as shellx64.efi.

Tip:
  • The Arch Linux installation medium has shellx64.efi at the root of the volume.
  • rEFInd and systemd-boot will automatically add a boot menu entry for the UEFI shell if shellx64.efi is in the root of the EFI system partition.

Systems with Phoenix SecureCore Tiano UEFI firmware is known to have embedded UEFI Shell which can be launched using either F6, F11 or F12 key.

Note: If you are unable to launch UEFI Shell from the firmware directly using any of the above mentioned methods, create a FAT32 USB pen drive with the EFI binary copied as /USB_drive_mointpoint/EFI/BOOT/BOOTx64.EFI. This USB should come up in the firmware boot menu. Launching this option will launch the UEFI Shell for you.

Important UEFI Shell commands

UEFI Shell commands usually support -b option which makes output pause after each page. Run help -b to list available internal commands. Available commands are either built into the shell or discrete EFI applications.

For more info see Intel Scripting Guide 2008[dead link 2023-07-30 ⓘ] and Intel "Course" 2011[dead link 2023-07-30 ⓘ].

bcfg

bcfg modifies the UEFI NVRAM entries which allows the user to change the boot entries or driver options. This command is described in detail in page 96 (Section 5.3) of the UEFI Shell Specification 2.2 document.

Note:
  • Try bcfg only if efibootmgr fails to create working boot entries on your system.
  • UEFI Shell v1 official binary does not support bcfg command. See #Obtaining UEFI Shell for a modified UEFI Shell v2 binary which may work in UEFI pre-2.3 firmwares.

To dump a list of current boot entries:

Shell> bcfg boot dump -v

To add a boot menu entry for rEFInd (for example) as 4th (numbering starts from zero) option in the boot menu:

Shell> bcfg boot add 3 FS0:\EFI\refind\refind_x64.efi "rEFInd Boot Manager"

where FS0: is the mapping corresponding to the EFI system partition and FS0:\EFI\refind\refind_x64.efi is the file to be launched.

To add an entry to boot directly into your system without a bootloader, configure a boot option using your kernel as an EFISTUB:

Shell> bcfg boot add N fsV:\vmlinuz-linux "Arch Linux"
Shell> bcfg boot -opt N "root=/dev/sdX# initrd=\initramfs-linux.img"

where N is the priority, V is the volume number of your EFI system partition, and /dev/sdX# is your root partition.

To remove the 4th boot option:

Shell> bcfg boot rm 3

To move the boot option #3 to #0 (i.e. 1st or the default entry in the UEFI Boot menu):

Shell> bcfg boot mv 3 0

For bcfg help text:

Shell> help bcfg -v -b

or:

Shell> bcfg -? -v -b

map

map displays a list of device mappings i.e. the names of available file systems (FS0) and storage devices (blk0).

Before running file system commands such as cd or ls, you need to change the shell to the appropriate file system by typing its name:

Shell> FS0:
FS0:\> cd EFI/

edit

edit provides a basic text editor with an interface similar to nano, but slightly less functional. It handles UTF-8 encoding and takes care or LF vs CRLF line endings.

For example, to edit rEFInd's refind.conf in the EFI system partition (FS0: in the firmware),

Shell> edit FS0:\EFI\refind\refind.conf

Press Ctrl+e for help.

UEFI drivers

This article or section needs expansion.