Difference between revisions of "EFI system partition"

From ArchWiki
Jump to: navigation, search
(Using bind mount: use "esp" pseudo-variable)
(rm uncommon acronym)
 
(64 intermediate revisions by 11 users not shown)
Line 1: Line 1:
 
[[Category:Boot process]]
 
[[Category:Boot process]]
 +
[[es:EFI system partition]]
 +
[[fr:ESP]]
 
[[ja:EFI システムパーティション]]
 
[[ja:EFI システムパーティション]]
[[zh-hans:EFI System Partition]]
+
[[ru:EFI system partition]]
[[fr:ESP]]
+
[[zh-hans:EFI system partition]]
[[ru:EFI System Partition]]
+
{{Related articles start}}
The [[Wikipedia:EFI System partition|EFI System Partition]] (also called ESP or EFISYS) is a FAT32 formatted physical partition (in the main partition table of the disk, not under LVM or software RAID etc.) from where the [[UEFI]] firmware launches the UEFI bootloader and application.  
+
{{Related|Unified Extensible Firmware Interface}}
 +
{{Related|Boot loader}}
 +
{{Related articles end}}
 +
The [[Wikipedia:EFI system partition|EFI system partition]] (also called ESP) is an OS independent partition that acts as the storage place for the EFI bootloaders, applications  and drivers to be launched by the UEFI firmware. It is mandatory for UEFI boot.
 +
 
 +
The UEFI specification mandates support for the FAT12, FAT16, and FAT32 filesystems (see [http://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_7_A%20Sept%206.pdf#G17.1019485 UEFI specification version 2.7, section 13.3.1.1]), but any conformant vendor can optionally add support for additional filesystems; for example, Apple [[Mac]]s support (and by default use) their own HFS+ filesystem drivers.
 +
 
 +
== Check for an existing partition ==
 +
 
 +
If you are installing Arch Linux on an UEFI-capable computer with an installed operating system, like [[Dual boot with Windows|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/sd''x''
 +
 
 +
The command returns:
 +
 
 +
* The disk's partition table: it indicates {{ic|Disklabel type: gpt}} if the partition table is [[GPT]] or {{ic|Disklabel type: dos}} if it is [[MBR]].
 +
* The list of partitions on the disk: Look for the EFI system partition in the list, it is a small (usually about 100–550 MiB) partition with a type {{ic|EFI System}} or {{ic|EFI (FAT-12/16/32)}}. To confirm this is the ESP, mount it and check whether it contains a directory named {{ic|EFI}}, if it does this is definitely the ESP.
  
It is an OS independent partition that acts as the storage place for the EFI bootloaders and applications to be launched by the EFI firmware. It is mandatory for UEFI boot.  
+
{{Warning|When dual-booting, avoid reformatting the ESP, as it may contain files required to boot other operating systems.}}
  
{{Warning|If [[Dual boot with Windows|dual-booting]] with an existing installation of Windows on a UEFI/GPT system, avoid reformatting the UEFI partition, as this includes the Windows ''.efi'' file required to boot it. In other words, use the existing partition as is and simply [[#Mount the partition]].}}
+
If you found an existing EFI system partition, simply proceed to [[#Mount the partition]]. If you did not find one, you will need to create it, proceed to [[#Create the partition]].
  
 
== Create the partition ==
 
== Create the partition ==
  
The following two sections show how to create an EFI System Partition (ESP).
+
The following two sections show how to create an EFI system partition (ESP).
 +
 
 +
{{Warning|The EFI system partition must be a physical partition in the main partition table of the disk, not under LVM or software RAID etc.}}
  
 
{{Note|It is recommended to use [[GPT]] for UEFI boot, because some UEFI firmwares do not allow UEFI/MBR boot.}}
 
{{Note|It is recommended to use [[GPT]] for UEFI boot, because some UEFI firmwares do not allow UEFI/MBR boot.}}
  
To avoid potential problems with some EFIs, ESP size should be at least 512 MiB. 550 MiB is recommended to avoid confusion with FAT16 [http://www.rodsbooks.com/efi-bootloaders/principles.html], although larger sizes are fine.
+
To avoid potential problems with some UEFI implementations, the ESP should be formatted with FAT32 and the size should be at least 512 MiB. 550 MiB is recommended to avoid MiB/MB confusion and accidentally creating FAT16 [http://www.rodsbooks.com/efi-bootloaders/principles.html], although larger sizes are fine.
  
According to a Microsoft note[https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions#diskpartitionrules], the minimum size for the EFI System Partition (ESP) would be 100 MiB, though this is not stated in the UEFI Specification. Note that for [[Advanced Format]] 4K Native drives (4-KiB-per-sector) drives, the size is at least 256 MiB, because it is the minimum partition size of FAT32 drives (calculated as sector size (4KiB) x 65527 = 256 MiB), due to a limitation of the FAT32 file format.
+
According to a Microsoft note[https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions#diskpartitionrules], the minimum size for the EFI system partition (ESP) would be 100 MiB, though this is not stated in the UEFI Specification. Note that for [[Advanced Format]] 4K Native drives (4-KiB-per-sector) drives, the size is at least 256 MiB, because it is the minimum partition size of FAT32 drives (calculated as sector size (4KiB) x 65527 = 256 MiB), due to a limitation of the FAT32 file format.
  
 
=== GPT partitioned disks ===
 
=== GPT partitioned disks ===
 +
 +
EFI system partition on a [[GUID Partition Table]] is identified by the [[Wikipedia:GUID Partition Table#Partition type GUIDs|partition type GUID]] {{ic|C12A7328-F81F-11D2-BA4B-00A0C93EC93B}}.
  
 
'''Choose one''' of the following methods to create an ESP for a GPT partitioned disk:
 
'''Choose one''' of the following methods to create an ESP for a GPT partitioned disk:
  
* [[fdisk|fdisk/gdisk]]: Create a partition with partition type EFI System ({{ic|EFI System}} in ''fdisk'' or {{ic|EF00}} in ''gdisk''). Proceed to [[#Format the partition]] section below.
+
* [[fdisk]]: Create a partition with partition type {{ic|EFI System}}.
* [[GNU Parted]]: Create a FAT32 partition and in Parted set/activate the {{ic|boot}} flag ('''not''' {{ic|legacy_boot}} flag) on that partition. Proceed to [[#Mount the partition]] section below.
+
* [[gdisk]]: Create a partition with partition type {{ic|EF00}}.
 +
* [[GNU Parted]]: Create a partition with {{ic|fat32}} as the file system type and set/activate the {{ic|esp}} flag on it.
 +
 
 +
Proceed to [[#Format the partition]] section below.
  
 
=== MBR partitioned disks ===
 
=== MBR partitioned disks ===
  
Create a partition with partition type ''EFI System'' using fdisk. Proceed to [[#Format the partition]].
+
EFI system partition on a [[Master Boot Record]] partition table is identified by the [[Wikipedia:Partition type|partition type ID]] {{ic|EF}}.
 +
 
 +
'''Choose one''' of the following methods to create an ESP for a MBR partitioned disk:
 +
 
 +
* [[fdisk]]: Create a primary partition with partition type {{ic|EFI (FAT-12/16/32)}}.
 +
* [[GNU Parted]]: Create a primary partition with {{ic|fat32}} as the file system type and set/activate the {{ic|esp}} flag on it.
 +
 
 +
Proceed to [[#Format the partition]] section below.
  
 
== Format the partition ==
 
== Format the partition ==
  
After creating the ESP, you '''must''' [[File systems#Create a file system|format]] it as [[FAT32]]:
+
After creating the ESP, you '''must''' [[format]] it as [[FAT32]]:
  
 
  # mkfs.fat -F32 /dev/sd''xY''
 
  # mkfs.fat -F32 /dev/sd''xY''
 
If you used GNU Parted above, it should already be formatted.
 
  
 
If you get the message {{ic|WARNING: Not enough clusters for a 32 bit FAT!}}, reduce cluster size with {{ic|mkfs.fat -s2 -F32 ...}} or {{ic|-s1}}; otherwise the partition may be unreadable by UEFI. See {{man|8|mkfs.fat}} for supported cluster sizes.
 
If you get the message {{ic|WARNING: Not enough clusters for a 32 bit FAT!}}, reduce cluster size with {{ic|mkfs.fat -s2 -F32 ...}} or {{ic|-s1}}; otherwise the partition may be unreadable by UEFI. See {{man|8|mkfs.fat}} for supported cluster sizes.
Line 43: Line 75:
 
== Mount the partition ==
 
== Mount the partition ==
  
The kernels and initramfs files need to be accessible by the [[boot loader]] or UEFI itself to successfully boot the system. Thus if you want to keep the setup simple, your boot loader choice limits the available mount points for EFI System Partition.
+
The kernels and initramfs files need to be accessible by the [[boot loader]] or UEFI itself to successfully boot the system. Thus if you want to keep the setup simple, your boot loader choice limits the available mount points for EFI system partition.
  
The simplest scenarios for mounting EFI System Partition are:
+
The simplest scenarios for mounting EFI system partition are:
  
* [[mount]] ESP to {{ic|/boot/efi}} and use a [[boot loader]] which has a driver for your root file system (eg. [[GRUB]], [[rEFInd]]).
+
* [[mount]] ESP to {{ic|/efi}} and use a [[boot loader]] which has a driver for your root file system (eg. [[GRUB]], [[rEFInd]]).
 
* [[mount]] ESP to {{ic|/boot}}. This is the preferred method when directly booting a [[EFISTUB]] kernel from UEFI.
 
* [[mount]] ESP to {{ic|/boot}}. This is the preferred method when directly booting a [[EFISTUB]] kernel from UEFI.
 +
 +
{{Note|The ESP will usually contain a directory called {{ic|EFI}} at the root of it, thus when mounting ESP to {{ic|/boot}} you may encounter a directory path such as {{ic|/boot/EFI}}. Do not confuse this path with the previously popular (and possibly still used by other Linux distributions) ESP mountpoint {{ic|/boot/efi}}.}}
  
 
=== Alternative mount points ===
 
=== Alternative mount points ===
Line 59: Line 93:
 
  # cp -a /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/
 
  # cp -a /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/
  
{{Note|When using an Intel CPU, you may need to copy the [[Microcode]] to the boot-entry location.}}
+
{{Note|You may also need to copy the [[Microcode]] to the boot-entry location.}}
  
 
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.
 
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.
 +
 +
{{Note|If ESP is not mounted to {{ic|/boot}}, make sure to not rely on the [[fstab#Automount with systemd|systemd automount mechanism]] (including that of {{man|8|systemd-gpt-auto-generator}}). Always have it mounted manually prior to the any system or kernel update, otherwise you may not be able to mount it after the update, locking you in the currently running kernel with no ability to update the copy of kernel on ESP.
 +
 +
Alternatively [[Kernel module#Automatic module handling|preload the required kernel modules on boot]], e.g.:
 +
 +
{{hc|/etc/modules-load.d/vfat.conf|
 +
vfat
 +
nls_cp437
 +
nls_iso8859-1
 +
}}
 +
 +
}}
  
 
==== Using bind mount ====
 
==== Using bind mount ====
Line 68: Line 114:
  
 
{{Note|
 
{{Note|
* This requires a kernel and bootloader compatible with FAT32. This is not an issue for a regular Arch install, but could be problematic for other distributions (namely those that require symlinks in {{ic|/boot/}}). See the forum post [https://bbs.archlinux.org/viewtopic.php?pid=1331867#p1331867 here].
+
* This requires a [[FAT#Kernel configuration|kernel]] and [[bootloader]] compatible with FAT32. This is not an issue for a regular Arch install, but could be problematic for other distributions (namely those that require symlinks in {{ic|/boot/}}). See the forum post [https://bbs.archlinux.org/viewtopic.php?pid=1331867#p1331867 here].
* You ''must'' use the {{ic|1=root=}} [[Kernel parameters#Parameter list|kernel parameter]] in order to boot using this method.}}
+
* You ''must'' use the {{ic|1=root=}} [[Kernel parameters#Parameter list|kernel parameter]] in order to boot using this method.
 +
}}
  
 
Just like in [[#Alternative mount points]], copy all boot files to a directory on your ESP, but mount the ESP '''outside''' {{ic|/boot}}. Then bind mount the directory:
 
Just like in [[#Alternative mount points]], copy all boot files to a directory on your ESP, but mount the ESP '''outside''' {{ic|/boot}}. Then bind mount the directory:
Line 87: Line 134:
 
{{hc|/etc/systemd/system/efistub-update.path|2=
 
{{hc|/etc/systemd/system/efistub-update.path|2=
 
[Unit]
 
[Unit]
Description=Copy EFISTUB Kernel to EFI System Partition
+
Description=Copy EFISTUB Kernel to EFI system partition
  
 
[Path]
 
[Path]
Line 99: Line 146:
 
{{hc|/etc/systemd/system/efistub-update.service|2=
 
{{hc|/etc/systemd/system/efistub-update.service|2=
 
[Unit]
 
[Unit]
Description=Copy EFISTUB Kernel to EFI System Partition
+
Description=Copy EFISTUB Kernel to EFI system partition
  
 
[Service]
 
[Service]
Line 112: Line 159:
 
{{Tip|For [[Secure Boot]] with your own keys, you can set up the service to also sign the image using {{Pkg|sbsigntools}}:
 
{{Tip|For [[Secure Boot]] with your own keys, you can set up the service to also sign the image using {{Pkg|sbsigntools}}:
  
{{bc|1=ExecStart=/usr/bin/sbsign --key ''/path/to/db.key'' --cert ''/path/to/db.crt'' --output ''esp''/EFI/arch/vmlinuz-linux ''esp''/EFI/arch/vmlinuz_linux}}
+
{{bc|1=ExecStart=/usr/bin/sbsign --key ''/path/to/db.key'' --cert ''/path/to/db.crt'' --output ''esp''/EFI/arch/vmlinuz-linux /boot/vmlinuz-linux}}
  
 
}}
 
}}
Line 144: Line 191:
 
#!/usr/bin/env bash
 
#!/usr/bin/env bash
 
build() {
 
build() {
/usr/local/bin/efistub-copy &
+
/usr/local/bin/efistub-copy $$ &
 
}
 
}
  
Line 157: Line 204:
 
#!/usr/bin/env bash
 
#!/usr/bin/env bash
  
wait $PPID
+
<nowiki>if [[ $1 -gt 0 ]]</nowiki>
 +
then
 +
while [ -e /proc/$1 ]
 +
do
 +
sleep .5
 +
done
 +
fi
  
cp -af /boot/vmlinuz-linux ''esp''/EFI/arch/
+
rsync -a /boot/ ''esp''/
cp -af /boot/initramfs-linux.img ''esp''/EFI/arch/
 
cp -af /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/
 
  
echo "Synced kernel with ESP"
+
echo "Synced /boot with ESP"
 
}}
 
}}
  
Line 200: Line 251:
 
build() {
 
build() {
 
cp -af /boot/vmlinuz-linux "${ESP_DIR}/"
 
cp -af /boot/vmlinuz-linux "${ESP_DIR}/"
# If ucode is used uncomment this line
+
[[ -e /boot/intel-ucode.img ]] && cp -af /boot/intel-ucode.img "${ESP_DIR}/"
#cp -af /boot/intel-ucode.img "${ESP_DIR}/"
+
[[ -e /boot/amd-ucode.img ]] && cp -af /boot/amd-ucode.img "${ESP_DIR}/"
 
}
 
}
  
Line 230: Line 281:
 
Target = boot/vmlinuz*
 
Target = boot/vmlinuz*
 
Target = usr/lib/initcpio/*
 
Target = usr/lib/initcpio/*
Target = boot/intel-ucode.img
+
Target = boot/*-ucode.img
  
 
[Action]
 
[Action]
Line 261: Line 312:
  
 
[[ -e /boot/intel-ucode.img ]] && cp -af /boot/intel-ucode.img "$ESP_DIR/"
 
[[ -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
 
exit 0
Line 268: Line 320:
  
 
=== ESP on RAID ===
 
=== ESP on RAID ===
 +
 
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.
 
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 [https://bbs.archlinux.org/viewtopic.php?pid=1398710#p1398710] and [https://bbs.archlinux.org/viewtopic.php?pid=1390741#p1390741] for details.
 
See [https://bbs.archlinux.org/viewtopic.php?pid=1398710#p1398710] and [https://bbs.archlinux.org/viewtopic.php?pid=1390741#p1390741] for details.
Line 273: Line 326:
 
== See also ==
 
== See also ==
  
* [http://blog.uncooperative.org/blog/2014/02/06/the-efi-system-partition/ The EFI System Partition and the Default Boot Behavior]
+
* [http://blog.uncooperative.org/blog/2014/02/06/the-efi-system-partition/ The EFI system partition and the default boot behavior]

Latest revision as of 08:01, 19 October 2018

The EFI system partition (also called ESP) is an OS independent partition that acts as the storage place for the EFI bootloaders, applications and drivers to be launched by the UEFI firmware. It is mandatory for UEFI boot.

The UEFI specification mandates support for the FAT12, FAT16, and FAT32 filesystems (see UEFI specification version 2.7, section 13.3.1.1), but any conformant vendor can optionally add support for additional filesystems; for example, Apple Macs support (and by default use) their own HFS+ filesystem drivers.

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 or Disklabel type: dos if it is MBR.
  • The list of partitions on the disk: Look for the EFI system partition in the list, it is a small (usually about 100–550 MiB) partition with a type EFI System or EFI (FAT-12/16/32). To confirm this is the ESP, mount it and check whether it contains a directory named EFI, if it does this is definitely the ESP.
Warning: When dual-booting, avoid reformatting the ESP, as it may contain files required to boot other operating systems.

If you found an existing EFI system partition, simply proceed to #Mount the partition. 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).

Warning: The EFI system partition must be a physical partition in the main partition table of the disk, not under LVM or software RAID etc.
Note: It is recommended to use GPT for UEFI boot, because some UEFI firmwares do not allow UEFI/MBR boot.

To avoid potential problems with some UEFI implementations, the ESP should be formatted with FAT32 and the size should be at least 512 MiB. 550 MiB is recommended to avoid MiB/MB confusion and accidentally creating FAT16 [1], although larger sizes are fine.

According to a Microsoft note[2], the minimum size for the EFI system partition (ESP) would be 100 MiB, though this is not stated in the UEFI Specification. Note that for Advanced Format 4K Native drives (4-KiB-per-sector) drives, the size is at least 256 MiB, because it is the minimum partition size of FAT32 drives (calculated as sector size (4KiB) x 65527 = 256 MiB), due to a limitation of the FAT32 file format.

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 with partition type EFI System.
  • gdisk: Create a partition with partition type EF00.
  • GNU Parted: Create a partition with fat32 as the file system type and set/activate the esp flag on it.

Proceed to #Format the partition section below.

MBR partitioned disks

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 with partition type EFI (FAT-12/16/32).
  • GNU Parted: Create a primary partition with fat32 as the file system type and set/activate the esp flag on it.

Proceed to #Format the partition section below.

Format the partition

After creating the ESP, you must format it as FAT32:

# mkfs.fat -F32 /dev/sdxY

If you get the message WARNING: Not enough clusters for a 32 bit FAT!, 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.

Mount the partition

The kernels and initramfs files need to be accessible by the boot loader or UEFI itself to successfully boot the system. Thus if you want to keep the setup simple, your boot loader choice limits the available mount points for EFI system partition.

The simplest scenarios for mounting EFI system partition are:

  • mount ESP to /efi and use a boot loader which has a driver for your root file system (eg. GRUB, rEFInd).
  • mount ESP to /boot. This is the preferred method when directly booting a EFISTUB kernel from UEFI.
Note: The ESP will usually contain a directory called EFI at the root of it, thus when mounting ESP to /boot you may encounter a directory path such as /boot/EFI. Do not confuse this path with the previously popular (and possibly still used by other Linux distributions) ESP mountpoint /boot/efi.

Alternative mount points

If you do not use one of the simple methods from #Mount the partition, 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/
Note: You may also need to copy the Microcode to the boot-entry location.

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.

Note: If ESP is not mounted to /boot, make sure to not rely on the systemd automount mechanism (including that of systemd-gpt-auto-generator(8)). Always have it mounted manually prior to the any system or kernel update, otherwise you may not be able to mount it after the update, locking you in the currently running kernel with no ability to update the copy of kernel on ESP.

Alternatively preload the required kernel modules on boot, e.g.:

/etc/modules-load.d/vfat.conf
vfat
nls_cp437
nls_iso8859-1

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.

Note:
  • This requires a kernel and bootloader compatible with FAT32. This is not an issue for a regular Arch install, but could be problematic for other distributions (namely those that require symlinks in /boot/). See the forum post here.
  • You must use the root= kernel parameter in order to boot using this method.

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.

Tip: For Secure Boot with your own keys, you can set up the service to also sign the image using sbsigntools:
ExecStart=/usr/bin/sbsign --key /path/to/db.key --cert /path/to/db.crt --output esp/EFI/arch/vmlinuz-linux /boot/vmlinuz-linux

Using incron

incron can be used to run a script syncing the EFISTUB Kernel after kernel updates.

/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/
Note: The first parameter /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
#!/usr/bin/env bash

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 hook (2)

Another alternative to the above solutions, that is potentially cleaner because there are less copies and does not need a system level daemon to function. The logic is reversed, the initramfs is directly stored in the EFI partition, not copied in /boot/. Then the kernel and any other additional files are copied to the ESP partition, thanks to a mkinitcpio hook.

Edit the file /etc/mkinitcpio.d/linux.preset :

/etc/mkinitcpio.d/linux.preset
# mkinitcpio preset file for the 'linux' package

# Directory to copy the kernel, the initramfs...
ESP_DIR="esp/EFI/arch"

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
default_image="${ESP_DIR}/initramfs-linux.img"
default_options="-A esp-update-linux"

#fallback_config="/etc/mkinitcpio.conf"
fallback_image="${ESP_DIR}/initramfs-linux-fallback.img"
fallback_options="-S autodetect"

Then create the file /etc/initcpio/install/esp-update-linux which need to be executable :

/etc/initcpio/install/esp-update-linux
# Directory to copy the kernel, the initramfs...
ESP_DIR="esp/EFI/arch"

build() {
	cp -af /boot/vmlinuz-linux "${ESP_DIR}/"
	-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}/"
}

help() {
	cat <<HELPEOF
This hook copies the kernel to the ESP partition
HELPEOF
}

To test that, just run:

# rm /boot/initramfs-linux-fallback.img
# rm /boot/initramfs-linux.img
# mkinitcpio -p linux

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 = File
Operation = Install
Operation = Upgrade
Target = boot/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
#!/usr/bin/env bash
#
# 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

Known issues

ESP on RAID

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 [3] and [4] for details.

See also