Unified Extensible Firmware Interface
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.
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.
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
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
- 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.
- EFI Runtime Services support should be present in the kernel (
CONFIG_EFI=y, check if present withzgrep CONFIG_EFI /proc/config.gz). - EFI Runtime Services in the kernel SHOULD NOT be disabled via the kernel command line, i.e.
noefikernel parameter SHOULD NOT be used. efivarfsfilesystem should be mounted at/sys/firmware/efi/efivars, otherwise follow #Mount efivarfs section below.efivarshould 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:
- If listing of the UEFI variables (
efivar -l) leads toefivar: error listing variables: Function not implementedand the system is booted into a realtime kernel, addefi=runtimeto the kernel parameters and reboot (efivarfs functionality is disabled by default on those kernels). - 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
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)
- efibootmgr — Tool to manipulate UEFI Firmware Boot Manager Settings
- uefivars — Dumps list of UEFI variables with some additional PCI related info (uses efibootmgr code internally)
- efitools — Tools for manipulating UEFI secure boot platforms
- Ubuntu's Firmware Test Suite — Test suite that performs sanity checks on Intel/AMD PC firmware
efibootmgr
You will have to install the efibootmgr package.
- If efibootmgr does not work on your system, you can reboot into #UEFI Shell and use
bcfgto 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:
- The disk containing the EFI system partition (ESP). E.g.:
/dev/sda,/dev/nvme0n1. - The partition number of the ESP on that disk. The
Yin/dev/sdaYor/dev/nvme0n1pY. - 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.
\ 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
efivarsin read-only mode using fstab. For example:efivarfs /sys/firmware/efi/efivars efivarfs ro,nosuid,nodev,noexec 0 0
- Use the
noefikernel parameter to completely disable OS access to UEFI.
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:
- On the Arch install medium:
/shellx64.efi. A copy of/usr/share/edk2-shell/x64/Shell_Full.efifrom the time the ISO was built. - edk2-shell provides x64 Shell for x64 (64-bit) UEFI and IA32 Shell for IA32 (32-bit) UEFI - compiled directly from latest TianoCore EDK2 release.
- uefi-shell-gitAUR provides x64 Shell for x64 (64-bit) UEFI and IA32 Shell for IA32 (32-bit) UEFI - compiled directly from latest TianoCore EDK2 source.
- On the Arch install medium:
- Shell v1:
- Precompiled UEFI Shell v1 binaries from TianoCore (not updated anymore upstream as of Jan 10, 2014).
- Patched shells:
- Precompiled UEFI Shell v2 binary with bcfg modified to work with UEFI pre-2.3 firmware[dead link 2023-07-30 ⓘ] - from Clover EFI bootloader.
- Precompiled UEFI Shell v2 binary for compatibility with a broad range of firmwares - from the OpenCore bootloader. In the release archive:
EFI/OC/Tools/OpenShell.efi.
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.
- The Arch Linux installation medium has
shellx64.efiat the root of the volume. - rEFInd and systemd-boot will automatically add a boot menu entry for the UEFI shell if
shellx64.efiis 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.
/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.
- Try
bcfgonly ifefibootmgrfails to create working boot entries on your system. - UEFI Shell v1 official binary does not support
bcfgcommand. 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.