Universal Extended Firmware Interface (UEFI) is essentially the successor to the computer BIOS, and SecureBoot is a component which enforces checking bootloaders with public key cryptography to ensure that only verified bootloaders can boot, adding another layer of protection from malware at a lower level.

NB: EFI and UEFI can be used interchangeably.

The situation with SecureBoot, Microsoft and Linux

When SecureBoot was announced, there was uproar in the Linux community for fear of OEMs locking devices to Microsoft Windows, whereby SecureBoot would not allow Linux to be installed [1][2]. This is actually not the case:

Microsoft has mandated the following for

Windows 8 Certified Devices

  • Secure boot must be on by default - by extension this causes Legacy (BIOS) booting to be disabled by default, as SecureBoot and Legacy booting cannot work in tandem

  • Secure boot must be able to be turned off EXCEPT for ARM devices where you must NOT be able to turn it off

  • Secure boot requires firmware that supports UEFI v2.3.1 Errata B and has the Microsoft Windows Certification Authority in the UEFI signature database

NB: UEFI Firmware support is all over the place and hard to anticipate. For example, some firmwares which should support EFI shell v2 don't, and some firmwares don't use a proper bootloader entry table and hardcode Microsoft's bootloader location instead.

What this means is that it's often best to turn off SecureBoot, and pick a distribution which has proper support for UEFI, as compatibility with Windows 8 requires EFI mode. I'd recommend against changing to Legacy booting unless absolutely necessary, especially for newer devices, as when you learn how to use EFI it's a lot neater and easier. SecureBoot is nice, and not particularly difficult to use, however some EFI implementations are broken and don't accept new MOKs properly or are riddled with other bugs (e.g. HP ProBook 4540s).

GPT Partition scheme

Many new devices come with disks partitioned to the GPT partition scheme. In my opinion there's nothing wrong with it, I partition my disks with GPT and I feel that if you're going to use EFI you might as well use GPT too. The only real noticeable difference is that there is no need to use logical partitions and I'm typing gdisk instead of fdisk (which apparently now also has experimental GPT support too).

EFI History

EFI is designed to replace BIOS, but what does the BIOS do? It initialises the hardware and hands over to the operating system. It's limited to 16-bit operations, the MBR partition layout, and has been hacked upon for years to support newer technologies like multiple cores. EFI is a fresh, fully 64-bit pre-boot environment which is programmable in C rather than ASM, and features a full network stack - with EFI it is possible to diagnose and repair a system without divulging into an operating system at all, even across a network. EFI also POSTs faster, leading to faster boot times. From within the EFI shell, you can load filesystem drivers to modify a filesystem without booting into an OS. It's also possible to implement a web browser as an EFI application too. One of EFI's major benefits is that it supports booting from a GPT partitioned disk, meaning that it can boot from a disk larger than 2.2TB.

Using EFI

EFI Booting

EFI looks for a FAT32 partition of partition type EF00 (GPT), known as the EFI system partition, with a structure like this:

  • \EFI\Boot...

  • \EFI\Microsoft...

  • \EFI\ubuntu...

Note that the EFI shell uses backslashes, akin to Windows and DOS.

The EFI version of the boot-order menu should populate itself with .efi executables in the EFI system partition, and then list devices. Booting from a device should run \EFI\Boot\bootx64.efi (64bit devices) from that device.

To create an EFI system partition, using gdisk assign the partition type as EF00 and partition it as FAT32. Note that FAT32 is not case sensitive.

Most modern distributions provide images which are EFI bootable. To use EFI you must boot the installer in EFI mode. The simplest way to do this is to turn off Legacy booting in the BIOS and check if it works. If not, you must create an EFI bootable image by copying the files from the original installer and hacking in an EFI bootloader into it. A note on Linux Mint: Even though their install image is technically EFI bootable (check if there is a /boot/EFI directory), the way their kernel loads with casper causes it to mess up when booting from EFI - their documentation says to switch to Legacy booting, but I'd just recommend switching to a *buntu, which will automate pretty much everything, and do SecureBoot magic too; besides, they're pretty much the same and just as evil as each other.

Managing EFI Bootloader Entries

A Linux install will often call efibootmgr to add an entry to the EFI bootloaders, which tells the computer to boot into GRUB or whatever bootloader it installs. The problem is that efibootmgr does not always work. E.g. It works fine on my Lenovo, yet does nothing on my Asus desktop. A safer approach is to use the EFI shell v2 (Shell v1 doesn't have support for managing bootloader entries).

EFI Shell

EFI shell v2 requires a newer UEFI firmware, so do a BIOS update before proceeding.

Links to the latest versions of EFI shells can be found on the Arch wiki. They have a great write-up on UEFI too.

Put the .efi executable onto the EFI system partition, or onto a memory stick (with an EFI system partition) and boot from it. If this doesn't work, try putting it at \EFI\Boot\bootx64.efi

The bcfg command is used to manage bootloader entries, and some basic help can be found from help bcfg.

Generally, you just want to add an entry pointing to rEFInd or GRUB located on your EFI:

  • bcfg boot add 0 fs0:\EFI\Boot\rEFInd.efi "rEFInd"

EFI demonstrates its versatility in that you can dynamically load filesystem drivers (e.g. ext4) and perform simple filesystem operations on connected drives, and easily manipulate the bootloader list.

Help command will yield a description of said command, or will list commands and their descriptions if the argument is omitted.

Some useful commands to remember:

  • bcfg - boot config

  • edit - basic text editor

  • cp - copy

  • mv - move

  • mkdir - make directory

  • ls - list directory

  • cd - change directory

NB: The US keyboard layout is used in the EFI shell, mapping \ to #.

Poor implementations

Some EFI implementations ignore the bootloader list outright, or wipe it clean frequently. Some hardcode the Windows EFI bootloader location, whilst some hardcode \EFI\Boot\bootx64.efi which is usually a stub pointing to the Windows EFI bootloader location.

In these cases, first try putting your binary (rEFInd/GRUB) at \EFI\Boot\bootx64.efi, and if that fails put it at the Windows EFI bootloader location.


Microsoft sign their bootloaders, and almost every new computer you buy recognises that signature and knows that their bootloader is verified and can run. Microsoft have a partnership with VeriSign whereby you can get a .efi binary signed using Microsoft's Third-Party key, provided that the software is not licensed under GPLv3 and is what Microsoft considers secure: it must continue the chain of signatures and not allow untrusted code to take over the machine [3]. This is why GRUB2 hasn't been signed.

At the moment, there are two Linux solutions to SecureBoot:

  • shim

  • PreLoader

NB: The latest version of shim is unsigned, therefore won't work - I'm using 0.2, which is the latest signed version

These two programs essentially chainload a bootloader, and are signed themselves via the Microsoft Third-Party Key. PreLoader was devised by the Linux Foundation, whilst shim is a Fedora project. Ubuntu and Fedora are both using shim at the moment, but nobody has included PreLoader into their distro yet.

An oddity I have noticed is that while GRUB2 has no issue with chainloading .efi binaries, it cannot seem to locate them if GRUB2 has been launched with SecureBoot turned on.


When using shim, there are essentially 3 levels of security:

  • BIOS-level keys

  • shim's built-in keys

  • Machine owner's keys (MOK)

The first are the keys provided by Microsoft. While they are replaceable on a lot of machines, the procedure varies drastically and can be very contrived. In short, nobody modifies these.

The second are keys built into shim that would be used by repository maintainers like Canonical, so that the version of GRUB in their repositories is always signed. In the stand-alone signed version of shim, this list is effectively empty - unlike the versions of shim found in Canonical and Fedora repositories.

The third are self-generated keys which are used to sign bootloaders which are not supported by the repository maintainers. Essentially, you generate a key, register it with MOKManager (provided by shim), which will store that in NVRAM. Afterwards, as long as shim is chainloading a binary that has been signed by that key, it is considered secure and allowed to boot.

shim can be configured to only launch signed kernels (Ubuntu and Fedora do this by default) using the SecureBoot mechanism too, but not many distros sign their kernels in such a way.

NB: shim is hardcoded to launch grubx64.efi, so rename your desired bootloader to that.


PreLoader takes a similar approach, however it stores hashes rather than keys. This means that the binary of the bootloaders remains unmodified. Simply rename your bootloader to loader.efi and put it in the same directory as PreLoader.efi and HashTool.efi (provided by PreLoader). When you launch PreLoader.efi, it will complain that it doesn't recognise loader.efi, which will launch HashTool.efi to prompt whether or not you want to enrol the hash for loader.efi. This method is arguably simpler, but it allows the user to blindly accept loading of any binary - somewhat defeating the point of SecureBoot. In my experience, PreLoader is more flaky than shim, for example, when I used it my BIOS constantly complained that the binary was not verified, yet booted it anyway.

Poor implementations

Some SecureBoot implementations don't accept MOKs, meaning that shim and PreLoader do not work. The only options following this are to:

  • Disable SecureBoot

  • Replace BIOS keys

  • Windows quirks

  • Windows EFI Bootloader location

  • The EFI bootloader for Windows is located at:

    • \EFI\Microsoft\Boot\bootmgfw.efi

Windows 7 and EFI

The 64bit edition of Windows 7 supports either Legacy or EFI mode, but will insist on EFI mode if it is being installed to a partition with the GPT partition table. The GPT partition table removes the 4-primary-partition limit, and can support disks larger than 2.2Tb.

Other versions of Windows 7, and previous versions of Windows (excluding Windows Vista SP1 64bit) will use Legacy booting and won't install to a GPT partitioned disk.

Posted by Nick Hu on 18/07/2013