跳转至内容

EFI 系统分区

来自 ArchWiki
(重定向自 ESP)

The EFI 系统分区 (也称为 ESP) 是一个与操作系统无关的分区,它作为 UEFI 引导加载程序、应用程序和驱动程序的存储位置,由 UEFI 固件启动。UEFI 引导是强制性的。

检查现有分区

如果您正在 UEFI 兼容的计算机上安装 Arch Linux,并且该计算机已安装操作系统,例如 Windows 10,那么您很可能已经有一个 EFI 系统分区。

要查找磁盘分区方案和系统分区,请以 root 用户身份在要从中启动的磁盘上使用 fdisk

# fdisk -l /dev/sdx

命令返回

  • 磁盘分区表:如果分区表是 GPT,则显示 Disklabel type: gpt;如果是 MBR,则显示 Disklabel type: dos
  • 磁盘上的分区列表:在列表中查找 EFI 系统分区,它通常至少有 100 MiB 大小,并且类型为 EFI SystemEFI (FAT-12/16/32)。要确认这是 ESP,请 挂载它并检查它是否包含名为 EFI 的目录,如果有,那么这绝对是 ESP。
提示 要确定它是 FAT12、FAT16 还是 FAT32 文件系统,请遵循 FAT#检测 FAT 类型
警告 在双系统启动时,请尽可能避免重新格式化 ESP,因为它可能包含启动其他操作系统所需的文件。如果现有的 ESP 小于建议的最小尺寸,您可能需要将其替换为更大的分区

如果您找到了一个可接受的现有 EFI 系统分区,请继续#挂载分区。如果您没有找到,则需要创建它,请继续#创建分区

创建分区

以下两个部分介绍了如何创建 EFI 系统分区 (ESP)。

警告 EFI 系统分区必须是磁盘主分区表中的物理分区,而不是 LVM 或软件 RAID 等下的分区。

分区大小应提供足够的空间来存储引导加载程序和其他启动所需的文件。

建议将分区大小设置为 1 GiB,以确保其有足够的空间容纳多个内核或统一内核镜像、引导加载程序、固件更新文件以及任何其他操作系统或 OEM 文件。如果您仍有疑问,**4 GiB** 应该足够所有人使用了。

对于像 Limine 引导加载程序与 Snapper 集成以支持 Btrfs(支持创建多个可引导快照)和 ESP 上的 Archiso(用于在无外部介质的情况下进行系统恢复的可引导 ISO 镜像)之类的工具,请考虑更大的尺寸(例如 8 GiB)。

注意 可以使用更小的分区,但要注意潜在的兼容性问题。
  • 对于早期和/或有 bug 的 UEFI 实现,可能需要至少 512 MiB 的大小。[1]
  • 如果您计划将分区挂载到 /boot 并且只安装一个内核,那么 400 MiB 就足够了。
  • 与 Windows 双系统启动时,对于逻辑扇区大小为 4096 的驱动器(高级格式化 4Kn 驱动器),大小应至少为 300 MiB[2],否则至少应为 100 MiB。[3]
  • 为确保分区可以格式化为 FAT32,对于逻辑扇区大小为 512 字节的驱动器,它应至少为 36 MiB;对于逻辑扇区大小为 4096 字节的驱动器,它应至少为 260 MiB。[4]
  • 如果以上情况都不适用,分区大小可以小至 2 MiB,在这种情况下,它只能容纳一个引导加载程序。

GPT 分区磁盘

GUID 分区表上的 EFI 系统分区由分区类型 GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B 标识。

**选择以下方法之一**为 GPT 分区磁盘创建 ESP:

  • fdisk:创建分区并使用 t 命令将分区类型更改EFI System,使用别名 uefi
  • gdisk:创建分区类型为 EF00 的分区。
  • GNU Parted:以 fat32 作为文件系统类型创建分区,并设置 esp 标志。

创建分区后,应将其格式化为文件系统。请继续阅读下面的#格式化分区部分。

MBR 分区磁盘

警告 强烈建议使用 GPT 而不是 MBR。

有关 MBR 的限制以及 GPT 的一般优势,请参阅 Partitioning#选择 GPT 与 MBR

主引导记录(Master Boot Record)分区表上的 EFI 系统分区由分区类型 ID EF 标识。

**选择以下方法之一**为 MBR 分区磁盘创建 ESP:

  • fdisk:创建一个主分区,并使用 t 命令将分区类型更改EFI (FAT-12/16/32)
  • GNU Parted:以 fat32 作为文件系统类型创建主分区,并设置 esp 标志。

创建分区后,应将其格式化为文件系统。请继续阅读下面的#格式化分区部分。

格式化分区

UEFI 规范要求支持 FAT12、FAT16 和 FAT32 文件系统(参见 UEFI 规范 2.11 版,第 13.3.1.1 节),但任何符合规范的供应商都可以选择支持其他文件系统;例如,Apple Mac 中的固件支持 HFS+ 文件系统。

为避免与其他操作系统发生潜在问题,并且由于 UEFI 规范规定 UEFI“包含使用 FAT32 作为系统分区,以及使用 FAT12 或 FAT16 作为可移动介质”[5],建议使用FAT32。使用来自 dosfstoolsmkfs.fat(8) 工具。

# mkfs.fat -F 32 /dev/sdxY

如果您收到消息 WARNING: Number of clusters for 32 bit FAT is less than suggested minimum. 并且无法创建更大的 ESP,请使用 mkfs.fat -s 2 -F 32 ...-s 1 减小簇大小;否则 UEFI 可能无法读取该分区。有关支持的簇大小,请参阅 mkfs.fat(8)

对于小于 32 MiB 的分区,使用 FAT32 可能不可行。在这种情况下,请将其格式化为 FAT16 甚至 FAT12。例如,一个 2 MiB 的 ESP 只能支持 FAT12。

# mkfs.fat -F 12 /dev/sdxY

挂载分区

内核、initramfs 文件以及大多数情况下的处理器微码需要能够被引导加载程序或 UEFI 本身访问,才能成功启动系统。因此,如果您想保持设置简单,您的引导加载程序选择将限制 EFI 系统分区的可用挂载点。

注意 如果 ESP 未挂载到 /boot,请确保在内核升级期间不要依赖 systemd 的自动挂载机制(包括 systemd-gpt-auto-generator)。始终在任何系统或内核更新之前手动挂载它,否则您可能无法在更新后挂载它,从而被锁定在当前运行的内核中,无法更新 ESP 上的内核副本。

或者,在启动时预加载所需的内核模块,例如:

/etc/modules-load.d/vfat.conf
vfat
nls_cp437
nls_ascii

典型挂载点

挂载 EFI 系统分区的三个典型场景是:

  • 挂载 ESP 到 /boot
    • 这有助于系统维护和管理,因为 /boot微码包放置 CPU 微码 initramfs 文件的默认路径,也是 mkinitcpio 放置内核initramfs 镜像的路径。
    • 这确保了大多数引导加载程序都可以访问上述文件,因为并非所有引导加载程序都能访问其他卷上的文件。
    • 这可以防止设置文件特定的权限和/或扩展属性,因为 FAT 在挂载时设置全局权限。
    • 这会增加 ESP 的大小要求,因为通常安装在 /boot 的文件将与用于 UEFI 引导的文件一起占用空间。
    • 这会使内核和 initramfs 镜像暴露在可启动驱动器或双系统启动时的其他操作系统可能造成的危险操作之下。
    • 这使得加密 /boot 不可能,因为固件必须能够访问引导加载程序及其文件。
    • 这使得根卷快照(使用 BtrfsBcachefsZFSLVM)的效果降低,因为 /boot 内容不会被包含在内。在内核更新时,返回到包含旧内核版本的快照将导致系统无法启动,并需要使用外部介质手动降级内核
  • 挂载 ESP 到 /efi
    • 注意 目前只有 GRUBrEFInd 支持此方案。
    • 它确保了操作系统文件和 UEFI 文件之间的关注点分离,UEFI 文件可能包含其他操作系统更好地不触碰的文件。
    • 通过不将安装到 /boot 的文件放在 ESP 中,它避免了增加 ESP 的大小要求:只有 EFI 二进制文件(引导加载程序(可选驱动程序)和/或统一内核镜像)将存储在 ESP 上,从而节省了存储空间。
    • 它允许为位于 /boot 的文件保留 Linux 特定的文件系统权限,避免了 FAT 的限制。
    • 它允许根据需要单独挂载 ESP,*例如*,仅在升级引导加载程序时。
    • 如果使用系统加密并进行了适当的设置,它允许只保留少量必需文件未加密,而 /boot 保持受保护:这对于统一内核镜像或具有能够访问存储在其他地方的内核和文件的文件系统驱动程序的引导加载程序可能很有用。
  • 挂载 ESP 到 /efi,并另外挂载一个“扩展引导加载程序分区”(XBOOTLDR)到 /boot。当以前创建的 ESP 太小而无法容纳多个引导加载程序和/或内核,但 ESP 又无法轻松调整大小时(例如,在 Windows 安装 Linux 以双系统启动后),此方法可能很有用。至少 systemd-boot 支持此方法。
  • /efi 是对历史上的(现已不推荐使用)ESP 挂载点 /boot/efi 的替代[6][7]
  • /efi 目录默认不可用,您需要先创建它,然后才能将其挂载到 ESP。

替代挂载点

如果您不使用#典型挂载点之一,您需要将引导文件复制到 ESP(下文称 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/
注意 如果您使用外部微码 initramfs 镜像,它们也需要被复制到引导条目位置。

此外,您需要使 ESP 上的文件与后续的内核更新保持同步。否则可能导致系统无法启动。以下各节讨论了几种自动化此过程的机制。

使用绑定挂载

与其将 ESP 本身挂载到 /boot,不如使用绑定挂载(参见 mount(8))将 ESP 的一个目录挂载到 /boot。这允许 pacman 直接更新内核,同时保持 ESP 按您的喜好组织。

注意 这需要一个兼容 FAT32 的内核引导加载程序。对于常规的 Arch 安装来说这不成问题,但对于其他发行版(特别是那些需要在 /boot/ 中使用符号链接的发行版)可能会有问题。请参阅论坛帖子 [8]

#替代挂载点中的一样,将所有引导文件复制到 ESP 上的一个目录,但将 ESP 挂载在 /boot **之外**。然后绑定挂载该目录:

# mount --bind esp/EFI/arch /boot

验证成功后,编辑您的Fstab 以使更改持久化。

/etc/fstab
esp/EFI/arch /boot none defaults,bind 0 0

使用 systemd

systemd 具有事件触发的任务。在这种特定情况下,路径更改检测能力用于在 EFISTUB 内核和 initramfs 文件更新时将它们同步到 /boot/。观察更改的文件是 initramfs-linux-fallback.img,因为这是 mkinitcpio 最后构建的文件,以确保在开始复制之前所有文件都已构建。要创建的 systemd 路径和服務文件是:

/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/

然后启用启动 efistub-update.path

提示 对于使用您自己的密钥进行安全启动,您可以使用 sbsigntools 设置服务以对镜像进行签名。
ExecStart=/usr/bin/sbsign --key /path/to/db.key --cert /path/to/db.crt --output esp/EFI/arch/vmlinuz-linux /boot/vmlinuz-linux

使用文件系统事件

文件系统事件可用于运行一个脚本,在内核更新后同步 EFISTUB 内核。以下是一个使用 incron 的示例。

/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 是要监视的文件。第二个参数 IN_CLOSE_WRITE 是要监视的动作。第三个参数 /usr/local/bin/efistub-update 是要执行的脚本。
/etc/incron.d/efistub-update.conf
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update

为了使用此方法,请启用 incrond.service

使用 mkinitcpio 预设

由于 /etc/mkinitcpio.d/ 中的预设支持 shell 脚本,因此可以通过编辑预设来复制内核和 initramfs。

替换 mkinitcpio hook

编辑文件 /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"

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"

要测试此功能,只需运行:

# rm /boot/initramfs-linux-fallback.img /boot/initramfs-linux.img
# mv /boot/vmlinuz-linux esp/EFI/arch/
# mkinitcpio -p linux
另一个示例
/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

使用 mkinitcpio 后置 hook

一个 mkinitcpio 后置 hook 可用于在 initramfs 生成后将内核和 initramfs 镜像复制到所需目录。

创建以下文件并使其可执行

/etc/initcpio/post/copy-kernel-and-initramfs
#!/usr/bin/env bash

kernel="$1"
initramfs="$2"
target_dir="esp/EFI/arch"
files_to_copy=()

for file in "$kernel" "$initramfs"; do
	if [[ -n "$file" ]] && ! cmp -s -- "$file" "${target_dir}/${file##*/}"; then
		files_to_copy+=("$file")
	fi
done

(( ! ${#files_to_copy[@]} )) && exit 0

cp -af -- "${files_to_copy[@]}" "${target_dir}/"

使用 pacman hook

最后一个选项依赖于 pacman hooks,这些 hooks 在事务结束时运行。

第一个文件是一个监视相关文件的 hook,如果在之前的事务中修改了这些文件,它就会被运行。

/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

第二个文件是脚本本身。创建该文件并使其可执行

/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

技巧与提示

用更大的分区替换分区

在预装操作系统的磁盘上,EFI 系统分区可能小于#创建分区中建议的大小。例如,Windows 安装程序在非 4Kn 驱动器上创建一个仅 100 MiB 的 EFI 系统分区。

在这种情况下,创建一个新的、更大的 EFI 系统分区可能是一个好主意,以防止其空间不足。

在 Windows 中为新分区释放空间

在 Windows 中,可以使用 Disk Management (diskmgmt.msc) 图形化管理分区,也可以使用 diskpart.exe 实用程序从命令行管理分区。

以管理员身份运行 diskmgmt.msc

  1. 右键单击“(C:)”分区(默认 Windows 创建的分区中唯一可以在线调整大小的分区),然后选择*Shrink Volume...*(收缩卷...)。
  2. 输入 4096 作为要收缩的量,然后单击*Shrink*(收缩)。

现在 “(C:)”分区后面应该有一个 4 GiB 的未分配空间。

启动到 Arch Linux 或 Arch Linux 安装介质,然后继续创建新分区。

删除旧分区并创建新分区

首先,确保备份 EFI 系统分区的内容。例如,使用 esp 作为其挂载点:

# cp -a esp /esp_backup

卸载 EFI 系统分区

# umount esp
注意 在已安装的系统上,您可能需要额外停止 esp.mountesp.automount 服务单元,以防止 systemd 再次自动挂载它。

运行 blkid 并记下 UUID 和 PARTUUID 值。稍后将重新使用它们给新分区。

# blkid
/dev/sdxY: UUID="XXXX-XXXX" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"

使用 gptfdisk 中的 sgdisk 删除旧分区。

# sgdisk --delete=Y /dev/sdx

在最大的未分配空间中创建一个新分区,同时重新使用旧的 PARTUUID 和 PARTLABEL。

# sgdisk --align-end --largest-new=0 --typecode=0:ef00 --change-name=0:'EFI system partition' --partition-guid=0:YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY /dev/sdx

使用 parted 中的 partprobe(8) 命令让内核重新读取分区表。

# partprobe /dev/sdx

通过使用 fdisk 列出分区,确认新的 4 GiB EFI 系统分区已创建。

# fdisk -l /dev/sdx
...
Device         Start       End   Sectors  Size Type
/dev/sdx1  158099456 166488063   8388608    4G EFI System
/dev/sdx2     206848    239615     32768   16M Microsoft reserved
/dev/sdx3     239616 158099455 157859840 75.3G Microsoft basic data
/dev/sdx4  166488064 167768063   1280000  625M Windows recovery environment
/dev/sdx5  167768064 176156671   8388608    4G Linux swap
/dev/sdx6  176156672 243265535  67108864   32G Linux root (x86-64)

Partition table entries are not in disk order.

删除和创建分区时,分区号不会重新排序,因此磁盘上的 EFI 系统分区号很可能与以前相同。

将分区格式化为 FAT32,并重新使用旧的 UUID(同时删除其中的连字符)。

# mkfs.fat -F 32 -i XXXXXXXX /dev/sdxY

最后,挂载新分区并从备份恢复其内容。

# mount /dev/sdxY esp
# cp -a /esp_backup/. esp/

如果您之前停止了 esp.automount,请重新启动它。

牺牲相邻的 swap 分区来扩大 ESP

如果 EFI 系统分区后面紧跟着一个 swap 分区,您可以牺牲它来为扩大 EFI 系统分区提供空间。例如,对于具有类似以下布局的分区:

# fdisk -l /dev/sdx
...
Device       Start       End   Sectors  Size Type
/dev/sdx1     2048    616447    614400  300M EFI System
/dev/sdx2   616448   9005055   8388608    4G Linux swap
/dev/sdx3  9005056 125827071 116822016 55.7G Linux root (x86-64)

首先,禁用 swap 分区并将其从 fstab 中移除。

使用 fdisk 删除 swap 分区并扩大 EFI 系统分区。

  1. 运行
    # fdisk /dev/sdx
  2. 使用 d 命令删除 swap 分区(在上面的示例布局中是分区号 2)。
  3. 使用 e 命令扩大 EFI 系统分区(在上面的示例布局中是分区号 1)。使用建议的默认值作为新大小,然后按 Enter
  4. 使用 w 命令将更改写入磁盘并退出。

调整分区大小后,您需要调整其中的文件系统大小。由于 fatresize(1) 不起作用,并且 libparted 无法调整某些大小的 FAT 卷,因此唯一的选择是将现有文件系统中的文件备份出来,然后创建一个新的文件系统,该文件系统占用分区的全部空间。

记下文件系统的UUID,以便稍后为新文件系统重新使用它。

$ lsblk -dno UUID /dev/sdxY
XXXX-XXXX

备份 EFI 系统分区的内容。例如,使用 esp 作为其挂载点:

# cp -a esp /esp_backup

卸载 EFI 系统分区

# umount esp
注意 在已安装的系统上,您可能需要额外停止 esp.mountesp.automount 服务单元,以防止 systemd 再次自动挂载它。

擦除分区上的文件系统签名,以避免旧文件系统的任何痕迹。

# wipefs -af /dev/sdxY

将分区格式化为 FAT32,并重新使用旧的 UUID(同时删除其中的连字符)。

# mkfs.fat -F 32 -i XXXXXXXX /dev/sdxY

最后,挂载新分区并从备份恢复其内容。

# mount /dev/sdxY esp
# cp -a /esp_backup/. esp/

如果您之前停止了 esp.automount,请重新启动它。

现在 swap 分区已不存在,请设置交换文件

故障排除

软件 RAID1 上的 ESP

可以将 ESP 作为 RAID1 阵列的一部分,但这会带来数据损坏的风险,并且在创建 ESP 时需要进行进一步的考虑。有关详细信息和解决方案,请参阅 [9][10],以及 UEFI 引导和 RAID1 以获取深度指南。

关键在于使用 --metadata 1.0 以将 RAID 元数据保留在分区末尾,否则固件将无法访问它。

# mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sdaX /dev/sdbY

或者,由于 ESP 不经常更新,可以在相关更新期间将主 ESP 复制到另一个磁盘上的辅助 ESP。然后可以使用 efibootmgr 手动添加辅助 ESP 的引导条目。有关实现示例,请参阅 Debian:UEFI#EFI 系统分区的 RAID。请注意,虽然这可以避免 RAID 方法的一些风险,但它仅在单操作系统使用时有效。

固件无法识别 EFI 目录

如果您为 FAT 文件系统指定了卷名(即文件系统标签),请确保其名称不是 EFI。这可能会触发某些固件中的 bug(因为卷名与 EFI 目录名匹配),导致固件表现得好像 EFI 目录不存在一样。

休眠和多系统引导

如果您正在运行多系统启动(包括但不限于与 Windows 双系统启动),并且希望在主 Arch Linux 进入休眠状态时能够启动到其他系统,您必须格外小心,不要在两个系统都挂载 ESP,因为这很可能导致数据损坏和使用过程中的 I/O 错误。

有三种可能的缓解策略:

  1. 为每个系统使用单独的 EFI 系统分区。大多数 UEFI 支持此功能,只要 ESP 位于物理上不同的磁盘上,但硬件支持和可用性可能有所不同。
  2. 使用 systemd 的自动挂载机制,仅在需要时挂载 ESP。请确保还指定了空闲超时(x-systemd.idle-timeout= 选项),否则 systemd 在使用后不会卸载 ESP。但是,请注意两个限制:首先,除非您将 ESP 挂载到 /boot,否则在内核升级期间不要依赖自动挂载(参见上面的注释)。其次,您必须确保在 systemd 自动卸载 ESP 后(参见自动卸载)系统进入休眠状态之前,不要让系统进入休眠状态。
  3. 将 ESP 挂载到 /efi,并在休眠系统之前卸载它,在系统恢复之后重新挂载它。请参阅下面的说明

通过成功应用上述缓解策略之一,您可以让此系统进入休眠状态,但不能让其他系统进入休眠状态,除非您也对它们应用了缓解策略之一。例如,对您的主 Arch Linux 应用一种解决方案可让您休眠 Arch Linux 并启动到另一个系统(例如 Ubuntu Linux),但不能休眠 Ubuntu Linux 并启动到主 Arch Linux。要让 Windows 实现这一点,需要单独的 EFI 系统分区。

严格来说,同时多次挂载同一文件系统的问题既不限于 EFI 系统分区,也不限于系统休眠。然而,它对于 ESP 尤其重要,因为 ESP 被期望在多个系统之间共享。缓解策略也可以适应其他用例。

休眠时卸载并重新挂载 ESP

如果您选择了上述选项 3,您可以创建并启用以下 systemd 系统服务,该服务会在系统休眠之前卸载 ESP,并在系统恢复之后重新挂载它。

/etc/systemd/system/efi-remount-on-hibernate.service
[Unit]
Description=Unmount and remount EFI system partition on hibernation
Before=hibernate.target hybrid-sleep.target suspend-then-hibernate.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecCondition=/usr/bin/systemctl is-active --quiet efi.mount
ExecStart=/usr/bin/systemctl stop efi.mount
ExecStop=/usr/bin/systemctl start efi.mount

[Install]
WantedBy=hibernate.target hybrid-sleep.target suspend-then-hibernate.target

但是,由于 efi.mount 默认被 local-fs.target 作为要求引入,停止 efi.mount 也会永久禁用 local-fs.target。这可能会导致各种负面影响,包括系统关机时的排序问题,这可能会触发 systemd 将 efi.mount 自动屏蔽为有缺陷。可以通过告诉 systemd efi.mount 不是 local-fs.target 的必需项,而是仅由其期望项来解决此问题。为确保这一点,您必须将以下挂载选项添加到 /etc/fstab 中的 /efi

x-systemd.wanted-by=local-fs.target,x-systemd.after=local-fs-pre.target,x-systemd.before=local-fs.target

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.