This page is mainly intended to describe UEFI for Debian purposes: what's supported in Debian and how to use it, plus some troubleshooting tips.
- What is UEFI?
- History and naming
- Architectures supported
- PC platform: BIOS, UEFI, CSM etc.
- ARM64 platform: UEFI, U-Boot, Fastboot, etc.
- ARM32 platform: UEFI, U-Boot, Fastboot, etc.
- Disk partitioning: MS-DOS and GPT
- Booting a UEFI machine normally
- Booting from removable media
- debian-installer support
- efibootmgr and efivar
- Quirks, workarounds and special UEFI features in Debian and Debian-Installer
- Missing features
What is UEFI?
(U)EFI stands for (Unified) Extensible Firmware Interface. It's a standard specification for the firmware interface on a computer, and it has been implemented by multiple vendors on various platforms.
History and naming
UEFI started life as Intel's EFI specification. It was first seen in the wild on Itanium (ia64) machines and that's where Debian's first support started too.
Later, Intel passed control over the EFI specification to the UEFI Forum and they continued developing newer versions of the specification. The U for Unified was added to the name at this point. In most references here and elsewhere on the net, EFI and UEFI are interchangeable terms to describe the same thing.
There are multiple further bits of terminology here, and things are often confused. So let's explain!
UEFI is actually a set of interface specifications, nothing more.
The reference implementation of the UEFI specifications is called edk2 or EDK II (EFI Development Kit, version 2). Code can be found at https://github.com/tianocore/edk2 .
Tianocore is the name of the upstream development group working on the Open Source EDK II project - see https://www.tianocore.org/ for more information.
OVMF (Open Virtual Machine Firmware) is a build of edk2 designed to be used as firmware for a virtual machine.
Many commercial UEFI firmware implementations are built on top of edk2, with changes commonly being made to add platform initialisation and a pretty GUI on the front end.
UEFI has been supported to some extent on 5 of Debian's architectures:
64-bit Itanium (ia64 in Debian)
64-bit x86-64 (amd64)
32-bit x86 (i386)
32-bit ARM (armhf)
64-bit Aarch64 (arm64)
There are some caveats, though...
- Since the Debian Jessie release (8.0), ia64 is no longer a release architecture in Debian
- Support for 32-bit ARM systems (armhf) is only available in Debian Buster (10.0) onwards, and is still under development at the time of writing.
It's a fair bet to assume that RISC-V might end up with UEFI support in the future too.
PC platform: BIOS, UEFI, CSM etc.
On the PC architectures (amd64 and i386), UEFI-based firmware is a relatively new replacement for the ancient BIOS (Basic Input/Output System) that has existed ever since the PC was first developed in the 1980s. The old BIOS systems have strict limitations due to their ancient design, running in 16-bit mode with access to only 1MB of memory, and limited access to other resources like disks. UEFI firmware is normally fully native and so should be able to access all the system memory and all the devices.
For the sake of backwards compatibility, many current PCs using UEFI also include a Compatibility Support Module (CSM), extra support code that will continue to boot in the old BIOS style. Over time, this support will most likely be phased out. Some systems were already being sold UEFI-only (i.e. with no CSM) in 2014.
x86 virtual machines can be run using qemu with either BIOS or UEFI firmware. qemu will default to BIOS using SeaBIOS, but it can also run OVMF. Debian includes builds of OVMF for amd64 in the ovmf package.
ARM64 platform: UEFI, U-Boot, Fastboot, etc.
Some Aarch64 machines (arm64) use U-Boot or other options like Fastboot for their firmware, but most general-purpose arm64 machines (e.g. those intended for use as servers) should be expected to use UEFI, typically via a build of edk2.
Debian includes edk2-based VM firmware for arm64 in the qemu-efi package. For some reason this is often described as AAVMF to distinguish it from OVMF for x86. It's basically the same software.
ARM32 platform: UEFI, U-Boot, Fastboot, etc.
Most Arm machines (armhf) use U-Boot or other options like Fastboot for their firmware, but some machines can run edk2 as well directly.
Again, edk2 is also a good option for firmware for 32-bit Arm VMs. Debian includes this firmware in the qemu-efi-arm package.
Recent versions of U-Boot have also included some limited UEFI functionality. This is designed to be "just enough UEFI" to support common operations, without including a lot of the more complicated possibilities underneath.
Disk partitioning: MS-DOS and GPT
Historically, the most common method of partitioning disks on PC platforms has been the MS-DOS standard using a Master Boot Record (MBR) and a tiny limited partition table with space to describe only 4 "primary" partitions. This is what BIOS systems still use to date. There are several important limitations that come with this scheme, but the most obvious one is the size limit of 2TB per disk. Back when this partitioning format was invented, a 100MB disk was large. Today, multi-terabyte disks are the norm.
UEFI also includes support for a newer partitioning format: the GUID Partition Table (GPT). It's much more flexible than the MS-DOS option, including:
- many more partitions (up to 128 per disk)
- much larger disks (up to 8ZB: 8,000,000,000 TB)
- much better definitions of what each partition might be used for
Booting a UEFI machine normally
Regular UEFI boot has several lists of possible boot entries, stored in UEFI config variables (normally in NVRAM), and boot order config variables stored alongside them. It allows for many different boot options, and a properly-defined fallback order. In many cases, you can even list and choose which OS / boot loader to use from the system boot menu (similar to the boot device menu implemented in many BIOSes). Unfortunately, a lot of PC UEFI implementations have got this wrong and so don't work properly.
The correct way for this to work when booting off local disk is for a boot variable to point to a vendor-specific bootloader program in
on the EFI System Partition (ESP), a specially tagged partition which is normally formatted using FAT32.
Debian installs grub-efi for its EFI bootloader, as:
Each version of GRUB here contains all the code and configuration that GRUB needs to work from that point.
By using separate vendor directories like this, UEFI allows for clean interoperability between vendors. If only the firmware developers were competent... Some implementations ignore the boot order altogether, some filter it and will only run things that claim to be "Windows", etc. See below for tips on how to work around some of the known bugs in broken UEFI implementations.
Booting from removable media
If there are no boot variables pointing to a bootloader program in the ESP, or if the user has told the system appropriately, it will look for bootloaders in certain specific paths too. On each device, it will look for FAT32 filesystems. Within each of those, it will look for a specifically-named bootloader file, again with a different name per architecture:
The different names are deliberate - it allows for one disk or CD to contain boot files for multiple architectures with no clashes.
On Debian installation media, each of these files is again a copy of grub-efi with sufficient built-in code and configuration to find the rest of the system from there.
debian-installer's support for UEFI is mostly contained in two modules.
First comes the partman-efi module, and this will be loaded automatically if d-i recognises it has been booted in UEFI mode. partman-efi will cope with both MS-DOS and GPT partitioned disks, but will offer to use GPT by preference on disks that are not already partitioned. It knows how to set up an ESP with appropriate partition type and filesystem if necessary, and will ensure it's correctly mounted on the installed system later. If the system already has an ESP, partman-efi will attempt to use that rather than create a new one. This is for interoperability with existing operating systems in dual-boot systems.
Once the normal installation process has been completed, the second major component with UEFI support comes into play: grub-installer. It will install the grub-efi bootloader to the right location in the ESP and will use efibootmgr to register that bootloader with the firmware. On correctly-working systems, this should work without needing any user interaction. This module will automatically find the ESP and install its files in the right place, leaving no space for confusion on where boot files are saved (as can happen with MBR/MS-DOS systems).
The initial support to make UEFI amd64 systems directly installable in Debian was added in Wheezy (7.0) Support was later added for i386 and arm64 systems for Jessie (8.0), along with a number of quirks and bug workarounds. See below for more details about those. Support for armhf was added in Buster (10.0).
efibootmgr and efivar
The Linux kernel gives access to the UEFI configuration variables via a set of files under /sys, using two different interfaces.
The older interface was efivars, showing files under /sys/firmware/efi/vars, and this is what was used by default in both Wheezy and Jessie.
The new interface is efivarfs, which will expose things in a slightly different format under /sys/firmware/efi/efivars. This is the new preferred way of using UEFI configuration variables, and Debian switched to it by default from Stretch onwards.
The exact details of these interfaces are hidden from view somewhat by efibootmgr and efivar, userland software packages written to work with them. Initially, all of the code was written directly in efibootmgr but more recently the lower-level code has been split out into the library efivar to make it easier to share this code with other utilities like fwupd. Read the man pages for these for full details, but here are a couple of examples from a system with many devices:
efibootmgr example 1 - display boot entries
# efibootmgr BootCurrent: 0019 Timeout: 0 seconds BootOrder: 0019,0006,0007,0008,0009,000A,000B,000C,000D,000E,000F,0010,0011,0012,0013 Boot0000 Setup Boot0001 Boot Menu Boot0002 Diagnostic Splash Screen Boot0003 Startup Interrupt Menu Boot0004 ME Configuration Menu Boot0005 Rescue and Recovery Boot0006* USB CD Boot0007* USB FDD Boot0008* ATAPI CD0 Boot0009* ATA HDD2 Boot000A* ATA HDD0 Boot000B* ATA HDD1 Boot000C* USB HDD Boot000D* PCI LAN Boot000E* ATAPI CD1 Boot000F* ATAPI CD2 Boot0010 Other CD Boot0011* ATA HDD3 Boot0012* ATA HDD4 Boot0013 Other HDD Boot0014* IDER BOOT CDROM Boot0015* IDER BOOT Floppy Boot0016* ATA HDD Boot0017* ATAPI CD: Boot0018* PCI LAN Boot0019* debian
efibootmgr example 2 - verbose display of boot entries
The same as example 1, but with more detail (including the GUIDs used to identify devices).
# efibootmgr -v BootCurrent: 0019 Timeout: 0 seconds BootOrder: 0019,0006,0007,0008,0009,000A,000B,000C,000D,000E,000F,0010,0011,0012,0013 Boot0000 Setup FvFile(721c8b66-426c-4e86-8e99-3457c46ab0b9) Boot0001 Boot Menu FvFile(126a762d-5758-4fca-8531-201a7f57f850) Boot0002 Diagnostic Splash Screen FvFile(a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380) Boot0003 Startup Interrupt Menu FvFile(f46ee6f4-4785-43a3-923d-7f786c3c8479) Boot0004 ME Configuration Menu FvFile(82988420-7467-4490-9059-feb448dd1963) Boot0005 Rescue and Recovery FvFile(665d3f60-ad3e-4cad-8e26-db46eee9f1b5) Boot0006* USB CD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,86701296aa5a7848b66cd49dd3ba6a55) Boot0007* USB FDD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,6ff015a28830b543a8b8641009461e49) Boot0008* ATAPI CD0 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a35401) Boot0009* ATA HDD2 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f602) Boot000A* ATA HDD0 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f600) Boot000B* ATA HDD1 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f601) Boot000C* USB HDD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,33e821aaaf33bc4789bd419f88c50803) Boot000D* PCI LAN VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,78a84aaf2b2afc4ea79cf5cc8f3d3803) Boot000E* ATAPI CD1 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a35403) Boot000F* ATAPI CD2 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a35404) Boot0010 Other CD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a35406) Boot0011* ATA HDD3 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f603) Boot0012* ATA HDD4 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f604) Boot0013 Other HDD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f606) Boot0014* IDER BOOT CDROM ACPI(a0341d0,0)PCI(16,2)ATAPI(0,1,0) Boot0015* IDER BOOT Floppy ACPI(a0341d0,0)PCI(16,2)ATAPI(0,0,0) Boot0016* ATA HDD VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f6) Boot0017* ATAPI CD: VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a354) Boot0018* PCI LAN VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,78a84aaf2b2afc4ea79cf5cc8f3d3803) Boot0019* debian HD(1,800,f3800,042e27b6-2c33-4d0e-8ee4-d579c3e39a1e)File(\EFI\debian\grubx64.efi)
efibootmgr example 3 - add a new boot entry
Create a new boot entry, pointing to a bootloader program on disk /dev/sdb, partition 1; write a new signature to the MBR if needed; call it "debian"; the bootloader program is in \EFI\debian\grubx64.efi
# efibootmgr -c -d /dev/sdb -p 1 -w -L debian -l '\EFI\debian\grubx64.efi' BootCurrent: 0019 Timeout: 0 seconds BootOrder: 0019,0006,0007,0008,0009,000A,000B,000C,000D,000E,000F,0010,0011,0012,0013 Boot0000 Setup Boot0001 Boot Menu Boot0002 Diagnostic Splash Screen Boot0003 Startup Interrupt Menu Boot0004 ME Configuration Menu Boot0005 Rescue and Recovery Boot0006* USB CD Boot0007* USB FDD Boot0008* ATAPI CD0 Boot0009* ATA HDD2 Boot000A* ATA HDD0 Boot000B* ATA HDD1 Boot000C* USB HDD Boot000D* PCI LAN Boot000E* ATAPI CD1 Boot000F* ATAPI CD2 Boot0010 Other CD Boot0011* ATA HDD3 Boot0012* ATA HDD4 Boot0013 Other HDD Boot0014* IDER BOOT CDROM Boot0015* IDER BOOT Floppy Boot0016* ATA HDD Boot0017* ATAPI CD: Boot0018* PCI LAN Boot0019* debian
Quirks, workarounds and special UEFI features in Debian and Debian-Installer
Initial support for UEFI installation was added for amd64 in Wheezy (7.0). This worked for many users, but various users reported issues. Most of these were not directly bugs in Debian's UEFI support, but nonetheless we have added workarounds to help these people.
Dual-booting systems currently installed using BIOS fallback boot
Quite a number of early UEFI systems were shipped with a non-UEFI installation of Windows 7 pre-installed, and the firmware set up to attempt UEFI boot first and BIOS boot second. This worked fine for users, but the moment a new operating system was installed alongside that copy of Windows, it would be difficult/impossible to dual-boot it.
debian-installer will now warn the user if it is booted in UEFI mode but can find it only non-UEFI existing OS installations. It gives them the option to switch the installer to non-UEFI mode from this point forwards so they don't break potential dual-boot setup.
Force grub-efi installation to the removable media path
Many UEFI firmware implementations are unfortunately buggy, as mentioned earlier. Despite the specification for boot entries and boot order being quite clear about how things should work, there are lots of systems in the wild which get it wrong. Some systems simply ignore valid requests to add new boot entries. Others will accept those requests, but will refuse to use them unless they describe themselves as "Windows" or similar. There are lots of other similar bugs out there, suggesting that many system vendors have done very little testing beyond "does it work with Windows?"
As described above, on a UEFI system bootloaders should be installed only in the correct vendor-specific directory in the EFI System Partition (ESP). But, because of the buggy firmware implementations out there, operating system distributors cannot necessarily expect that this will work correctly for all systems. Microsoft have worked around this (and arguably also made the problem worse) - the Windows installer also installs to the removable media path in the ESP (e.g. \EFI\boot\bootx64.efi for amd64/X64 systems). All firmware implentations have to use this path to be able to run an OS installer. This means that Windows will always work on all these broken implementations, but it also means that system vendors can get away with shipping broken implementations. It removes the idea of having a fallback boot path and sensible control of boot order.
All OS installers installing things to this removable media path will conflict with any other such installers, which is bad and wrong. That's why in Debian we don't do this by default.
However, to help support those unfortunate people who own buggy systems like this there is an option to force grub-efi installation to the removable media path too. There is a d-i Rescue Mode option to force this - if you've just installed Debian on your UEFI system but it won't boot Debian afterwards, this may fix the problem for you. It can also be selected during the normal installation run using Expert mode, or preseed users can add the following option in their configuration (for amd64, tweak the package name to suit on other architectures):
grub-efi-amd64 grub2/force_efi_extra_removable boolean true
If a bootable Debian Installer image is not available simply copy \EFI\debian\grubx64.efi to \EFI\boot\bootx64.efi using whatever means are available (other operating system, connect the storage device to a different computer, etc.).
As the name implies, installing grub-efi to the removable media path can be useful (or even necessary) for portable Debian installations on removable media.
32-bit x86 PC (i386) support for UEFI
In Wheezy (Debian 7.0), i386 UEFI support was intentionally omitted for a variety of reasons. However, since then lots more UEFI-only x86 machines were produced so we enabled it. Since Debian Jessie (8.0), all standard i386 Debian installation media should work for UEFI installation as well as in BIOS mode, just like on amd64.
Support for mixed-mode systems: 64-bit system with 32-bit UEFI
Some systems have been released containing 64-bit Intel Atom CPUs (such as the Bay Trail), but unfortunately use 32-bit UEFI firmware with no BIOS compatibility mode. Using the 32-bit UEFI x86 support, an i386 installation should be possible on these machines but it won't make the most of the 64-bit hardware.
Debian Jessie (8.0) was the first Linux distribution to include full support for mixed-mode UEFI installation on these machines. The multi-arch installation media (available in netinst and DVD form) include the UEFI boot loaders necessary for both i386 and amd64 boot. By selecting "64-bit install" from the initial boot menu, debian-installer will install a 64-bit (amd64) version of Debian. The system will automatically detect that the underlying UEFI firmware is 32-bit and will install the appropriate version of grub-efi to work with it.
Although Debian releases since Wheezy (7.0) have included general UEFI support, there are still some features that have not yet been implemented.
UEFI support in live images
Since the first release of Stretch (9.0), UEFI is now supported on both installation and live images.
In previous releases UEFI support existed only in Debian's installation images. The accompanying live images did not have support for UEFI boot.
UEFI Secure Boot
Debian supports UEFI Secure Boot for Buster (10.0) onwards for amd64, i386 and arm64. See SecureBoot for more details on how this works. It is supported for all the installation media and live media that we create for these three platforms.
RAID for the EFI System Partition
This is arguably a mis-design in the UEFI specification - the ESP is a single point of failure on one disk. For systems with hardware RAID, that will provide some backup in case of disk failure. But for software RAID systems there is currently no support for putting the ESP on two separate disks in RAID. There might be a way to do something useful with fallback options, but this will need some investigation...
How to reinstall the grub-efi bootloader on Debian
Could not read EFI vars under RT kernel
Due to high latency of efivars are disabled by default on RT kernel (see patch). You could enable by passing kernel command line efi=runtime
How to tell if you've booted via UEFI
The Debian installer splash screen will say it's the UEFI installer, and will look slightly different to the equivalent screen in BIOS mode. BIOS boot is done via isolinux/syslinux, but UEFI boot is done using grub.
Later on, the thing to look for is the directory /sys/firmware/efi. If that exists, the system is running in UEFI mode.
Diagnosing problems with boot order
efibootmgr is your friend. Run it without parameters to simply list the boot options and boot order on your system, or add -v for more detail of where each boot entry points.
After that, check to see if you have Secure Boot enabled - we didn't support Secure Boot until version 10.0 (Buster).
If that still doesn't help, you may have a buggy firmware implementation. Try installing to the removable media path - see above for instructions.
There are lots of other UEFI resources on the internet. Particularly useful ones include:
http://www.uefi.org/ - the UEFI Forum
http://wiki.osdev.org/UEFI - OSDev wiki page about UEFI
http://wiki.osdev.org/Broken_UEFI_implementations - wiki page for Linux distro vendors to share information about systems with broken UEFI implementations
The best place to talk about UEFI support in Debian is the mailing list: mailto:email@example.com or in our irc channel (#debian-efi on irc.debian.org)