User:YHNdnzj/EFI boot partitions
Overview
The EFI system partition (also called ESP) is an OS independent partition that acts as the storage place for the UEFI boot loaders, applications and drivers to be launched by the UEFI firmware. It is mandatory for UEFI boot.
The "Linux extended boot" (XBOOTLDR) partition can be created to keep the kernel and initramfs separate from the ESP. This is particularly helpful to dual boot with Windows with an existing ESP that is too small.
EFI system partition
Check for an existing partition
If you are installing Arch Linux on an UEFI-capable computer with an installed operating system, like Windows 10 for example, it is very likely that you already have an EFI system partition.
To find out the disk partition scheme and the system partition, use fdisk as root on the disk you want to boot from:
# fdisk -l /dev/sdx
The command returns:
- The disk's partition table: it indicates
Disklabel type: gpt
if the partition table is GPT orDisklabel type: dos
if it is MBR. - The list of partitions on the disk: Look for the EFI system partition in the list, it is usually at least 100 MiB in size and has the type
EFI System
orEFI (FAT-12/16/32)
. To confirm this is the ESP, mount it and check whether it contains a directory namedEFI
, if it does this is definitely the ESP.
Proceed to #Mount the partition if an ESP already exists. Optionally, check out #Linux extended boot. If you did not find one, you will need to create it, proceed to #Create the partition.
Create the partition
The following two sections show how to create an EFI system partition (ESP).
The partition size should provide adequate space for storing boot loaders and other files required for booting.
To prevent interoperability issues with other operating systems[1] and ensure compatibility with Advanced Format drives[2], it is recommended to make it at least 300 MiB.
- For early and/or buggy UEFI implementations the size of at least 512 MiB might be needed.[3]
- To ensure the partition can be formatted to FAT32, it should be at least 36 MiB on drives with 512 byte logical sector size and 260 MiB on drives with 4096 logical sector size.[4]
- If you plan to install multiple kernels and either mount the partition to /boot or pack the kernels in unified kernel images, you can use 1 GiB to be on the safe side.
- If none of these are relevant issues, the partition size can be as small as 2 MiB, in which case it could house nothing more than a boot loader.
GPT partitioned disks
EFI system partition on a GUID Partition Table is identified by the partition type GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B
.
Choose one of the following methods to create an ESP for a GPT partitioned disk:
- fdisk: Create a partition and use the
t
command to change its partition type toEFI System
. - gdisk: Create a partition with partition type
EF00
. - GNU Parted: Create a partition with
fat32
as the file system type and set theesp
flag on it.
After creating the partition, it should be formatted with a file system. Proceed to the #Format the partition section below.
MBR partitioned disks
- Some firmware might not support UEFI/MBR booting due to it not being supported by Windows Setup.
- bootctl does not support installing systemd-boot to an MBR partitioned disk; see systemd issue 1125.
See also Partitioning#Choosing between GPT and MBR for the limits of MBR and the advantages of GPT in general.
EFI system partition on a Master Boot Record partition table is identified by the partition type ID EF
.
Choose one of the following methods to create an ESP for a MBR partitioned disk:
- fdisk: Create a primary partition and and use the
t
command to change its partition type toEFI (FAT-12/16/32)
. - GNU Parted: Create a primary partition with
fat32
as the file system type and set theesp
flag on it.
After creating the partition, it should be formatted with a file system. Proceed to the #Format the partition section below.
Format the partition
The UEFI specification mandates support for the FAT12, FAT16, and FAT32 file systems (see UEFI specification version 2.10, section 13.3.1.1), but any conformant vendor can optionally add support for additional file systems; for example, the firmware in Apple Macs supports the HFS+ file system.
To prevent potential issues with other operating systems and since the UEFI specification says that UEFI "encompasses the use of FAT32 for a system partition, and FAT12 or FAT16 for removable media"[5], it is recommended to use FAT32. Use the mkfs.fat(8) utility from dosfstools:
# mkfs.fat -F 32 /dev/sdxY
If you get the message WARNING: Not enough clusters for a 32 bit FAT!
and you cannot create a larger ESP, reduce cluster size with mkfs.fat -s2 -F32 ...
or -s1
; otherwise the partition may be unreadable by UEFI. See mkfs.fat(8) for supported cluster sizes.
For partitions smaller than 32 MiB using FAT32 may not be possible. In which case, format it to FAT16 or even FAT12. For example, a 2 MiB ESP will only be able to support FAT12:
# mkfs.fat -F 12 /dev/sdxY
Linux extended boot
XBOOTLDR is currently not explicitly supported by boot loaders other than systemd-boot. However, since other EFI boot loaders typically support booting from other partitions (regardless of the partition type), it should available for them too.}}
Create the partition
Create a partition with partition type GUID of bc13c2ff-59e6-4262-a352-b275fd6f7172
[6] (ea00
type for gdisk). The size of the XBOOTLDR partition should be large enough to accommodate all of the kernels you are going to install.
File system choices
For systemd-boot, it is possible to load extra EFI drivers, including file system drivers, before reading the XBOOTLDR partition. GRUB and rEFInd come with some file system drivers out-of-the-box. However, it is generally not recommended to use a file system that is not supported by the UEFI firmware. File system drivers implemented outside of Linux kernel are known to be potentially flawed (e.g. FS#79851), and can thus prevent the system from booting.
Mount the partitions
With XBOOTLDR
If XBOOTLDR exists, it should be mounted to /boot
, and the ESP is mounted to /efi
.
Without XBOOTLDR
If XBOOTLDR is not used, several choices for mount points exist, all comes with different advantages and disadvantages.
Typical mount points
- mount the ESP to
/boot
:- This facilitates system maintenance and administration, as
/boot
is the default path where microcode packages place the CPU microcode initramfs files and where mkinitcpio places kernels and initramfs images. - This ensures that the above files are directly accessible to most boot loaders, as not all of them can access files on other volumes. And even they can, it is usually not recommended as mentioned below:
- This doesn't carry the potentiality that the file system drivers implemented by boot loaders are flawed, and thus preventing the system from booting. E.g. FS#79857
- This prevents setting file-specific permissions and/or extended attributes, as FAT sets global permissions at mount time.
- This increases the size requirement for the ESP, as files normally installed in
/boot
will join the EFI-related ones. - In the case of dual-booting, this exposes the OS-specific boot files to potentially hazardous manipulation from other OSes.
- This makes encrypting /boot impossible, as EFI-related files have to be accessible by the firmware.
- This facilitates system maintenance and administration, as
- mount the ESP to
/efi
:- It ensures a separation of concerns between OS- and EFI-related files, which may include other OSes' files better left alone.
- It avoids increasing the size requirement of the ESP by not placing the files installed to
/boot
in it: only the EFI binaries (the boot loader (and optionally drivers) and/or the unified kernel image) will be stored on the ESP, which saves storage space. However, do note that this could suffer from the same problem mentioned in #File system choices. - It allows to preserve Linux-specific filesystem permissions for files residing in
/boot
, avoiding FAT limitations.
Alternative mount points
If you do not use one of the #Typical mount points, you will need to copy your boot files to ESP (referred to hereafter as esp
).
# mkdir -p esp/EFI/arch # cp -a /boot/vmlinuz-linux esp/EFI/arch/ # cp -a /boot/initramfs-linux.img esp/EFI/arch/ # cp -a /boot/initramfs-linux-fallback.img esp/EFI/arch/
Furthermore, you will need to keep the files on the ESP up-to-date with later kernel updates. Failure to do so could result in an unbootable system. The following sections discuss several mechanisms for automating it.
Using bind mount
Instead of mounting the ESP itself to /boot
, you can mount a directory of the ESP to /boot
using a bind mount (see mount(8)). This allows pacman to update the kernel directly while keeping the ESP organized to your liking.
/boot/
). See the forum post [7].Just like in #Alternative mount points, copy all boot files to a directory on your ESP, but mount the ESP outside /boot
. Then bind mount the directory:
# mount --bind esp/EFI/arch /boot
After verifying success, edit your Fstab to make the changes persistent:
/etc/fstab
esp/EFI/arch /boot none defaults,bind 0 0
Using systemd
Systemd features event triggered tasks. In this particular case, the ability to detect a change in path is used to sync the EFISTUB kernel and initramfs files when they are updated in /boot/
. The file watched for changes is initramfs-linux-fallback.img
since this is the last file built by mkinitcpio, to make sure all files have been built before starting the copy. The systemd path and service files to be created are:
/etc/systemd/system/efistub-update.path
[Unit] Description=Copy EFISTUB Kernel to EFI system partition [Path] PathChanged=/boot/initramfs-linux-fallback.img [Install] WantedBy=multi-user.target WantedBy=system-update.target
/etc/systemd/system/efistub-update.service
[Unit] Description=Copy EFISTUB Kernel to EFI system partition [Service] Type=oneshot ExecStart=/usr/bin/cp -af /boot/vmlinuz-linux esp/EFI/arch/ ExecStart=/usr/bin/cp -af /boot/initramfs-linux.img esp/EFI/arch/ ExecStart=/usr/bin/cp -af /boot/initramfs-linux-fallback.img esp/EFI/arch/
Then enable and start efistub-update.path
.
ExecStart=/usr/bin/sbsign --key /path/to/db.key --cert /path/to/db.crt --output esp/EFI/arch/vmlinuz-linux /boot/vmlinuz-linux
Using filesystem events
Filesystem events can be used to run a script syncing the EFISTUB Kernel after kernel updates. An example with incron follows.
/usr/local/bin/efistub-update
#!/bin/sh cp -af /boot/vmlinuz-linux esp/EFI/arch/ cp -af /boot/initramfs-linux.img esp/EFI/arch/ cp -af /boot/initramfs-linux-fallback.img esp/EFI/arch/
/boot/initramfs-linux-fallback.img
is the file to watch. The second parameter IN_CLOSE_WRITE
is the action to watch for. The third parameter /usr/local/bin/efistub-update
is the script to execute./etc/incron.d/efistub-update.conf
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update
In order to use this method, enable the incrond.service
.
Using mkinitcpio hook
Mkinitcpio can generate a hook that does not need a system level daemon to function. It spawns a background process which waits for the generation of vmlinuz
, initramfs-linux.img
, and initramfs-linux-fallback.img
before copying the files.
Add efistub-update
to the list of hooks in /etc/mkinitcpio.conf
.
/etc/initcpio/install/efistub-update
#!/usr/bin/env bash build() { /usr/local/bin/efistub-copy $$ & } help() { cat <<HELPEOF This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP HELPEOF }
/usr/local/bin/efistub-copy
#!/bin/sh if [ "$1" -gt 0 ] then while [ -e /proc/"$1" ] do sleep .5 done fi rsync -a /boot/ esp/ echo "Synced /boot with ESP"
Using mkinitcpio preset
As the presets in /etc/mkinitcpio.d/
support shell scripting, the kernel and initramfs can be copied by just editing the presets.
Replacing the above mkinitcpio hook
Edit the file /etc/mkinitcpio.d/linux.preset
:
/etc/mkinitcpio.d/linux.preset
# mkinitcpio preset file for the 'linux' package # Directory to install the kernel, the initramfs... ESP_DIR="esp/EFI/arch" #ALL_config="/etc/mkinitcpio.conf" ALL_kver="${ESP_DIR}/vmlinuz-linux" [[ -e /boot/intel-ucode.img ]] && cp -af /boot/intel-ucode.img "${ESP_DIR}/" [[ -e /boot/amd-ucode.img ]] && cp -af /boot/amd-ucode.img "${ESP_DIR}/" PRESETS=('default' 'fallback') #default_config="/etc/mkinitcpio.conf" default_image="${ESP_DIR}/initramfs-linux.img" default_options="" #fallback_config="/etc/mkinitcpio.conf" fallback_image="${ESP_DIR}/initramfs-linux-fallback.img" fallback_options="-S autodetect"
To test that, just run:
# rm /boot/initramfs-linux-fallback.img /boot/initramfs-linux.img # mv /boot/vmlinuz-linux esp/EFI/arch/ # mkinitcpio -p linux
Another example
/etc/mkinitcpio.d/linux.preset
ESP_DIR="esp/EFI/arch" #ALL_config="/etc/mkinitcpio.conf" ALL_kver="$ESP_DIR/vmlinuz-linux$suffix" PRESETS=('default') default_config="/etc/mkinitcpio.conf" default_image="$ESP_DIR/initramfs-linux$suffix.img"
/etc/mkinitcpio.d/linux-zen.preset
suffix='-zen' source /etc/mkinitcpio.d/linux.preset
Using pacman hook
A last option relies on the pacman hooks that are run at the end of the transaction.
The first file is a hook that monitors the relevant files, and it is run if they were modified in the former transaction.
/etc/pacman.d/hooks/999-kernel-efi-copy.hook
[Trigger] Type = Path Operation = Install Operation = Upgrade Target = usr/lib/modules/*/vmlinuz Target = usr/lib/initcpio/* Target = boot/*-ucode.img [Action] Description = Copying linux and initramfs to EFI directory... When = PostTransaction Exec = /usr/local/bin/kernel-efi-copy.sh
The second file is the script itself. Create the file and make it executable:
/usr/local/bin/kernel-efi-copy.sh
#!/bin/sh # # Copy kernel and initramfs images to EFI directory # ESP_DIR="esp/EFI/arch" for file in /boot/vmlinuz* do cp -af "$file" "$ESP_DIR/$(basename "$file").efi" [ $? -ne 0 ] && exit 1 done for file in /boot/initramfs* do cp -af "$file" "$ESP_DIR/" [ $? -ne 0 ] && exit 1 done [ -e /boot/intel-ucode.img ] && cp -af /boot/intel-ucode.img "$ESP_DIR/" [ -e /boot/amd-ucode.img ] && cp -af /boot/amd-ucode.img "$ESP_DIR/" exit 0
Troubleshooting
ESP on software RAID1
It is possible to make the ESP part of a RAID1 array, but doing so brings the risk of data corruption, and further considerations need to be taken when creating the ESP. See [8] and [9] for details and UEFI booting and RAID1 for an in-depth guide with a solution.
The key part is to use --metadata 1.0
in order to keep the RAID metadata at the end of the partition, otherwise the firmware will not be able to access it:
# mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sdaX /dev/sdbY
Firmware does not see the EFI directory
If you give the FAT file system a volume name (i.e. file system label), be sure to name it something other than EFI
. That can trigger a bug in some firmwares (due to the volume name matching the EFI directory name) that will cause the firmware to act like the EFI directory does not exist.