GRUB
GRUB (GRand Unified Bootloader) 是一个引导加载程序。当前的 GRUB 也被称为 GRUB 2。最初的 GRUB,或 GRUB Legacy,对应于 0.9x 版本。本页专门描述 GRUB 2。
esp
表示EFI 系统分区,又名 ESP 的挂载点。支持的文件系统
GRUB 捆绑了对多种文件系统的支持,特别是 FAT32、ext4、Btrfs 或 XFS。有关一些注意事项,请参阅#不支持的文件系统。
/boot
。这通常可以通过使用单独的 /boot 分区和通用支持的文件系统(如 FAT32)来避免。UEFI 系统
- 建议阅读并理解统一可扩展固件接口、分区#GUID 分区表和 Arch 启动过程#UEFI 2 页面。
- 当安装以使用 UEFI 时,以 UEFI 模式启动安装介质非常重要,否则 efibootmgr 将无法添加 GRUB UEFI 启动项。即使在 BIOS 模式下,安装到备用启动路径仍然有效,因为它不接触 NVRAM。
- 要使用 UEFI 从磁盘启动,需要 EFI 系统分区。按照EFI 系统分区#检查现有分区来了解您是否已经有一个,否则您需要创建它。
- 整篇文章都假定可以通过
insmod
插入额外的 GRUB2 模块。正如在 #Shim-lock 中讨论的那样,在启用安全启动的 UEFI 系统上情况并非如此。如果您想在安全启动系统上使用任何未包含在标准 GRUB EFI 文件grubx64.efi
中的其他 GRUB 模块,您必须使用grub-mkstandalone
重新生成 GRUB EFIgrubx64.efi
,或者使用grub-install
重新安装 GRUB,并包含额外的 GRUB 模块。
安装
- UEFI 固件在不同制造商之间的实现方式不一致。下面描述的过程旨在在各种 UEFI 系统上工作,但尽管应用此方法仍遇到问题的用户,我们鼓励他们分享详细信息,如果可能的话,分享针对其特定硬件情况找到的解决方法。/EFI 示例文章已针对此类情况提供。
- 本节假设您正在为 x64(64 位)UEFI 安装 GRUB。对于 IA32(32 位)UEFI(不要与 32 位 CPU 混淆),请在适当的地方将
x86_64-efi
替换为i386-efi
。按照统一可扩展固件接口#检查固件位数中的说明来确定您的 UEFI 的位数。
首先,安装软件包 grub 和 efibootmgr:GRUB 是引导加载程序,而 efibootmgr 由 GRUB 安装脚本用于将启动项写入 NVRAM。
然后按照以下步骤将 GRUB 安装到您的磁盘
- 挂载 EFI 系统分区,在本节的剩余部分中,将
esp
替换为其挂载点。 - 选择一个启动加载程序标识符,此处命名为
GRUB
。将在esp/EFI/
中创建一个以此名称命名的目录,用于存储 EFI 二进制文件,并且此名称将显示在 UEFI 启动菜单中,以标识 GRUB 启动项。 - 执行以下命令以将 GRUB EFI 应用程序
grubx64.efi
安装到esp/EFI/GRUB/
,并将其模块安装到/boot/grub/x86_64-efi/
。
- 注意
- 确保从将要安装 GRUB 作为引导加载程序的系统上安装软件包并运行
grub-install
命令。这意味着如果您从 live 安装环境启动,则在运行grub-install
时需要位于 chroot 中。如果由于某种原因需要在已安装的系统外部运行grub-install
,请附加--boot-directory=
选项,并指定已挂载的/boot
目录的路径,例如--boot-directory=/mnt/boot
。 - 某些主板无法处理启动加载程序 ID 中带有空格的情况。
- 确保从将要安装 GRUB 作为引导加载程序的系统上安装软件包并运行
# grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=GRUB
在上述安装完成后,主 GRUB 目录位于 /boot/grub/
。阅读 /技巧和提示#替代安装方法 以了解如何指定替代位置。请注意,grub-install
还会尝试在固件启动管理器中创建一个条目,在上述示例中命名为 GRUB
– 但是,如果您的启动项已满,这将失败;使用 efibootmgr 删除不必要的条目。
在完成配置后,请记住#生成主配置文件。
--removable
选项,则 GRUB 将安装到 esp/EFI/BOOT/BOOTX64.EFI
(对于 i386-efi
目标,则为 esp/EFI/BOOT/BOOTIA32.EFI
),并且您将额外拥有从驱动器启动的能力,以防 EFI 变量被重置或您将驱动器移动到另一台计算机。通常,您可以通过选择驱动器本身来执行此操作,类似于您使用 BIOS 的方式。如果与 Windows 双启动,请注意 Windows 通常会在那里放置一个 EFI 可执行文件,但其唯一目的是为 Windows 重新创建 UEFI 启动项。如果您在 Mac 上安装 GRUB,则必须使用此选项。某些台式机主板只会在此位置查找 EFI 可执行文件,从而使此选项成为强制性的,尤其是对于 MSI 主板。如果您执行 UEFI 更新,则此更新可能会删除现有的 UEFI 启动项。因此,启用“可移动”启动项是一种潜在的备用策略。--efi-directory
和--bootloader-id
是 GRUB UEFI 特有的,--efi-directory
替换了已弃用的--root-directory
。- 您可能会注意到
grub-install
命令中缺少 device_path 选项(例如:/dev/sda
)。实际上,任何提供的 device_path 都将被 GRUB UEFI 安装脚本忽略。实际上,UEFI 引导加载程序根本不使用 MBR 引导代码或分区引导扇区。
如果遇到问题,请参阅UEFI 故障排除。此外,请参阅 /技巧和提示#UEFI 进一步阅读。
安全启动支持
GRUB 完全支持使用 CA 密钥或 shim 的安全启动;但是,安装命令根据您打算使用哪种方法而有所不同。
- 错误配置安全启动可能会导致您的系统无法启动。如果由于任何原因在启用安全启动后无法启动,则应在固件中禁用它并重新启动系统。
- 在引导加载程序中加载不必要的模块可能会带来安全风险,仅在您需要它们时才使用这些命令。
CA 密钥
要使用 CA 密钥,命令是
# grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=GRUB --modules="tpm" --disable-shim-lock
Shim-lock
当使用 Shim-lock 时,只有当 GRUB 的 EFI 二进制文件包含读取包含 vmlinuz 和 initramfs 映像的文件系统所需的所有模块时,才能在安全启动模式下成功启动 GRUB。
自 GRUB 版本 2.06.r261.g2f4430cc0
起,不再允许在安全启动模式下通过 insmod
加载模块,因为这将违反不侧载任意代码的期望。如果 GRUB 模块未嵌入到 EFI 二进制文件中,并且 GRUB 尝试侧载/insmod
它们,则 GRUB 将无法启动,并显示消息
error: prohibited by secure boot policy
根据 其官方构建脚本,Ubuntu 在其签名的 GRUB EFI 二进制文件 grubx64.efi
中嵌入了以下 GRUB 模块
- “基本”模块,从 CD 或简单分区的磁盘启动所必需:
all_video
、boot
、btrfs
、cat
、chain
、configfile
、echo
、efifwsetup
、efinet
、ext2
、fat
、font
、gettext
、gfxmenu
、gfxterm
、gfxterm_background
、gzio
、halt
、help
、hfsplus
、iso9660
、jpeg
、keystatus
、loadenv
、loopback
、linux
、ls
、lsefi
、lsefimmap
、lsefisystab
、lssal
、memdisk
、minicmd
、normal
、ntfs
、part_apple
、part_msdos
、part_gpt
、password_pbkdf2
、png
、probe
、reboot
、regexp
、search
、search_fs_uuid
、search_fs_file
、search_label
、sleep
、smbios
、squash4
、test
、true
、video
、xfs
、zfs
、zfscrypt
、zfsinfo
- x86_64-efi 架构的“平台特定”模块,例如,
play
:在启动期间播放声音cpuid
:用于启动时的 CPUtpm
:支持 Measured Boot / 可信平台模块
- “高级”模块,由以下模块组成
您必须以 shell 变量的形式构建您的 GRUB 模块列表,我们将其表示为 GRUB_MODULES
。您可以将 最新的 Ubuntu 脚本 作为起点,并删除系统上不需要的模块。省略模块将使启动过程相对更快,并节省 ESP 分区上的一些空间。
您还需要一个 安全启动高级目标 (SBAT) 文件/部分,包含在 EFI 二进制文件中,以提高安全性;如果 GRUB 是从 UEFI shim 加载程序启动的。此 SBAT 文件/部分包含有关 GRUB 二进制文件的元数据(版本、维护者、开发者、上游 URL),并使 shim 更容易阻止加载某些具有安全漏洞的 GRUB 版本[1][2],如 shim 的 UEFI shim 引导加载程序安全启动生命周期改进 文档中所述。
如果 grubx64.efi
中缺少 SBAT 部分,则第一阶段 UEFI 引导加载程序 shim 将无法启动 grubx64.efi
!
如果安装了 GRUB,则在 /usr/share/grub/sbat.csv
下提供了一个示例 SBAT .csv 文件。
使用提供的 /usr/share/grub/sbat.csv
文件和所有需要的 GRUB_MODULES
重新安装 GRUB 并对其进行签名
# grub-install --target=x86_64-efi --efi-directory=esp --modules=${GRUB_MODULES} --sbat /usr/share/grub/sbat.csv # sbsign --key MOK.key --cert MOK.crt --output esp/EFI/GRUB/grubx64.efi esp/EFI/GRUB/grubx64.efi # cp esp/EFI/GRUB/grubx64.efi esp/EFI/BOOT/grubx64.efi
重新启动,在 MokManager 中选择密钥,安全启动应该可以工作了。
使用安全启动
安装后,请参阅 安全启动#实施安全启动,以获取有关启用它的说明。
如果您正在使用 CA 密钥方法,则可以使用 sbctl 自动化密钥管理、注册和文件签名,有关详细信息,请参阅 安全启动#使用 sbctl 的辅助过程。
BIOS 系统
GUID 分区表 (GPT) 特定说明
在 BIOS/GPT 配置上,需要一个BIOS 启动分区。GRUB 将其 core.img
嵌入到此分区中。
- 在尝试此方法之前,请记住并非所有系统都能够支持此分区方案。阅读更多关于 分区#GUID 分区表 的信息。
- BIOS 启动分区仅在 BIOS/GPT 设置中的 GRUB 上才需要。在 BIOS/MBR 设置中,GRUB 使用 MBR 后间隙来嵌入
core.img
。但是,在 GPT 上,不能保证第一个分区之前有未使用的空间。 - 对于 UEFI 系统,不需要此额外的分区,因为在这种情况下不会发生引导扇区的嵌入。但是,UEFI 系统仍然需要 EFI 系统分区。
在磁盘上创建一个兆字节分区(使用 fdisk 或 gdisk 的 +1M
),没有文件系统,分区类型 GUID 为 21686148-6449-6E6F-744E-656564454649
。
此分区可以位于任何位置顺序,但必须位于磁盘的前 2 TiB 中。此分区需要在 GRUB 安装之前创建。当分区准备就绪后,按照以下说明安装引导加载程序。
第一个分区之前的空间也可以用作 BIOS 启动分区,尽管它将超出 GPT 对齐规范。由于分区不会被定期访问,因此可以忽略性能问题,尽管某些磁盘实用程序会显示有关它的警告。在 fdisk 或 gdisk 中,创建一个从扇区 34 开始并跨越到 2047 的新分区,并设置类型。为了使可查看的分区从基址开始,请考虑最后添加此分区。
主引导记录 (MBR) 特定说明
通常,在许多 MBR 分区系统中,MBR 后间隙(在 512 字节 MBR 区域之后和第一个分区开始之前)为 31 KiB,当分区表中满足 DOS 兼容性柱面对齐问题时。但是,建议使用大约 1 到 2 MiB 的 MBR 后间隙,以便为嵌入 GRUB 的 core.img
提供足够的空间 (FS#24103)。建议使用支持 1 MiB 分区对齐 的分区工具来获得此空间,并解决其他非 512 字节扇区问题(与嵌入 core.img
无关)。
安装
安装 grub 软件包。(如果已安装 grub-legacyAUR,它将替换它。)然后执行
# grub-install --target=i386-pc /dev/sdX
其中 i386-pc
是特意使用的,无论您的实际架构如何,/dev/sdX
是要安装 GRUB 的磁盘(而不是分区)。例如 /dev/sda
或 /dev/nvme0n1
,或 /dev/mmcblk0
。有关块设备命名方案的描述,请参阅 设备文件#块设备名称。
现在您必须生成主配置文件。
如果您为您的 /boot
使用 LVM,您可以在多个物理磁盘上安装 GRUB。
有关 grub-install
命令的更多详细信息,请参阅 grub-install(8) 和 GRUB 手册。
配置
在已安装的系统上,GRUB 每次启动时都会加载 /boot/grub/grub.cfg
配置文件。您可以按照 #生成的 grub.cfg 使用工具,或者按照 #自定义 grub.cfg 手动创建。
生成的 grub.cfg
本节仅介绍编辑 /etc/default/grub
配置文件。有关更多信息,请参阅 /技巧和提示。
生成主配置文件
安装后,需要生成主配置文件 /boot/grub/grub.cfg
。生成过程可能受 /etc/default/grub
和 /etc/grub.d/
中的脚本中的各种选项的影响。有关 /etc/default/grub
中的选项列表以及每个选项的简明描述,请参阅 GNU 的 文档。
如果您没有进行其他配置,则自动生成将确定要启动的系统的根文件系统,以用于配置文件。为了使其成功,重要的是系统已启动或已 chroot 进入。
- 默认文件路径是
/boot/grub/grub.cfg
,而不是/boot/grub/i386-pc/grub.cfg
。 - 如果您尝试在 chroot 或 systemd-nspawn 容器中运行 grub-mkconfig,您可能会注意到它不起作用:
grub-probe: error: failed to get canonical path of /dev/sdaX
。在这种情况下,请尝试使用 arch-chroot,如 BBS 帖子中所述。
使用 grub-mkconfig 工具生成 /boot/grub/grub.cfg
# grub-mkconfig -o /boot/grub/grub.cfg
默认情况下,生成脚本会自动将所有已安装的 Arch Linux 内核的菜单项添加到生成的配置中。
- 在安装或删除内核后,您只需要重新运行上述 grub-mkconfig 命令。
- 有关管理多个 GRUB 条目的提示,例如,当同时使用 linux 和 linux-lts 内核时,请参阅 /技巧和提示#多个条目。
要自动添加其他已安装操作系统的条目,请参阅 #检测其他操作系统。
您可以通过编辑 /etc/grub.d/40_custom
并重新生成 /boot/grub/grub.cfg
来添加其他自定义菜单项。或者您可以创建 /boot/grub/custom.cfg
并在其中添加它们。对 /boot/grub/custom.cfg
的更改不需要重新运行 grub-mkconfig,因为 /etc/grub.d/41_custom
会将必要的 source
语句添加到生成的配置文件中。
/etc/grub.d/40_custom
可以用作创建 /etc/grub.d/nn_custom
的模板,其中 nn
定义了优先级,指示脚本的执行顺序。脚本的执行顺序决定了在 GRUB 启动菜单中的位置。nn
应大于 06
,以确保首先执行必要的脚本。有关自定义菜单项示例,请参阅 #启动菜单项示例。
检测其他操作系统
要让 grub-mkconfig 搜索其他已安装的系统并自动将其添加到菜单中,请安装 os-prober 软件包,并挂载其他系统从中启动的分区。然后重新运行 grub-mkconfig。如果您得到以下输出:Warning: os-prober will not be executed to detect other bootable partitions
,则编辑 /etc/default/grub
并添加/取消注释
GRUB_DISABLE_OS_PROBER=false
然后重试。
- 确切的挂载点无关紧要,os-prober 读取
mtab
以识别要搜索可启动条目的位置。 - 请记住,每次运行 grub-mkconfig 时都挂载分区,以便每次都包含其他操作系统。
- os-prober 在 chroot 中运行时可能无法正常工作。如果您遇到这种情况,请在重新启动到系统后重试。
Windows
对于以 UEFI 模式安装的 Windows,请确保包含 Windows 启动管理器 (bootmgfw.efi
) 的 EFI 系统分区已挂载。以 root 身份运行 os-prober
以检测并为其生成条目。
对于以 BIOS 模式安装的 Windows,请挂载 Windows 系统分区(其文件系统标签应为 System Reserved
或 SYSTEM
)。以 root 身份运行 os-prober
以检测并为其生成条目。
附加参数
要将自定义附加参数传递给 Linux 映像,您可以在 /etc/default/grub
中设置 GRUB_CMDLINE_LINUX
+ GRUB_CMDLINE_LINUX_DEFAULT
变量。这两个变量将相互附加,并在生成常规启动项时传递给内核。对于恢复启动项,仅在生成中使用 GRUB_CMDLINE_LINUX
。
不一定两者都需要使用,但有时会很有用。例如,你可以使用 GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=uuid-of-swap-partition quiet"
,其中 uuid-of-swap-partition
是你的交换分区的 UUID,以在休眠后启用恢复。这将生成一个不带恢复功能且不带 quiet
的恢复启动项,quiet
用于在从该菜单项启动时抑制内核消息。但是,其他(常规)菜单项将包含这些选项。
默认情况下,grub-mkconfig 会确定配置的根文件系统的 UUID。要禁用此功能,请取消注释 GRUB_DISABLE_LINUX_UUID=true
。
为了生成 GRUB 恢复条目,你必须确保在 /etc/default/grub
中 GRUB_DISABLE_RECOVERY
未设置为 true
。
有关更多信息,请参阅 内核参数。
默认情况下,grub-mkconfig 使用 sort -V
对包含的内核进行排序,并将列表中的第一个内核用作顶层条目。这意味着,例如,由于 /boot/vmlinuz-linux-lts
在 /boot/vmlinuz-linux
之前排序,如果你同时安装了 linux-lts 和 linux,则 LTS 内核将成为顶层菜单项,这可能不是你想要的。可以通过在 /etc/default/grub
中指定 GRUB_TOP_LEVEL="path_to_kernel"
来覆盖此设置。例如,要使常规内核成为顶层菜单项,你可以使用 GRUB_TOP_LEVEL="/boot/vmlinuz-linux"
。
LVM
如果你使用 LVM 作为你的 /boot
或 /
根分区,请确保预加载了 lvm
模块
/etc/default/grub
GRUB_PRELOAD_MODULES="... lvm"
RAID
GRUB 提供了方便的 RAID 卷处理。你需要加载 GRUB 模块 mdraid09
或 mdraid1x
以允许你本地寻址卷
/etc/default/grub
GRUB_PRELOAD_MODULES="... mdraid09 mdraid1x"
例如,/dev/md0
变成
set root=(md/0)
而分区 RAID 卷(例如 /dev/md0p1
)变成
set root=(md/0,1)
当使用 RAID1 作为 /boot
分区(或使用位于 RAID1 根分区上的 /boot
)在 BIOS 系统上安装 grub 时,只需在两个驱动器上运行 grub-install,例如
# grub-install --target=i386-pc --debug /dev/sda # grub-install --target=i386-pc --debug /dev/sdb
其中 RAID 1 阵列包含 /boot
,位于 /dev/sda
和 /dev/sdb
上。
加密 /boot
GRUB 还具有对使用加密 /boot
启动的特殊支持。这是通过解锁 LUKS 块设备以读取其配置并从中加载任何 initramfs 和 内核 来完成的。此选项尝试解决拥有 未加密的引导分区 的问题。
/boot
不是 必须放在单独的分区中;它也可以保留在系统的根目录 /
目录树下。要启用此功能,请像往常一样使用 LUKS 加密 /boot
所在的分区。然后将以下选项添加到 /etc/default/grub
/etc/default/grub
GRUB_ENABLE_CRYPTODISK=y
此选项由 grub-install 用于生成 grub core.img
。
修改此选项或加密分区后,请确保 安装 grub。
如果没有进一步的更改,你将被提示两次输入密码:第一次是 GRUB 在早期引导时解锁 /boot
挂载点,第二次是由 initramfs 实现的解锁根文件系统本身。你可以使用 密钥文件 来避免这种情况。
- 如果你使用特殊的键盘映射,默认的 GRUB 安装将不知道它。这与如何输入密码以解锁 LUKS 块设备有关。请参阅 /技巧和窍门#手动配置用于早期引导的 core 镜像。
- 如果你在显示密码提示时遇到问题(关于 cryptouuid、cryptodisk 或“找不到设备”的错误),请尝试重新安装 GRUB 并在
grub-install
命令末尾附加--modules="part_gpt part_msdos"
。
/boot
。LUKS2
使用 #安装 部分中描述的 grub-install
来创建具有 LUKS 支持的可引导 GRUB 镜像。请注意以下注意事项
- 最初的 LUKS2 支持已添加到 GRUB 2.06,但存在一些限制,这些限制仅在 GRUB 2.12rc1 中部分解决。请参阅 GRUB 错误 #55093。
- 自 GRUB 2.12rc1 起,
grub-install
可以创建一个核心镜像来解锁 LUKS2。但是,它仅支持 PBKDF2,不支持 Argon2。 - 不支持 Argon2id(cryptsetup 默认值)和 Argon2i PBKDF(GRUB 错误 #59409),仅支持 PBKDF2。
- 提示: 你可以使用已针对 LUKS2 和 Argon2 支持进行修补的 grub-improved-luks2-gitAUR。请注意,该软件包的 Argon2 支持需要 UEFI 系统。[3]
/boot/grub/grub-pre.cfg
,其中包含对 cryptomount
、insmod normal
和 normal
的调用)的 grub-mkimage
手动创建一个 EFI 二进制文件。现在不再需要这样做,grub-install
就足够了。但是,你可能需要在从 2.06 升级后至少运行一次 grub-mkconfig -o /boot/grub/grub.cfg
。如果在引导期间输入了无效的密码并最终进入 GRUB 救援 shell,请尝试 cryptomount -a
以挂载所有(希望只有一个)加密分区,或使用 cryptomount -u $crypto_uuid
来挂载特定的分区。然后像往常一样继续使用 insmod normal
和 normal
。
如果输入了正确的密码,但立即返回 Invalid passphrase
错误,请确保指定了正确的加密模块。使用 cryptsetup luksDump /dev/nvme0n1p2
并检查哈希函数(SHA-256、SHA-512)是否与已安装的模块(gcry_sha256
、gcry_sha512
)匹配,以及 PBKDF 算法是否为 pbkdf2。可以使用 cryptsetup luksConvertKey --hash sha256 --pbkdf pbkdf2 /dev/nvme0n1p2
为现有密钥更改哈希和 PBDKDF 算法。正常情况下,密码应在几秒钟后处理。
自定义 grub.cfg
本节介绍如何在 /boot/grub/grub.cfg
中手动创建 GRUB 引导条目,而不是依赖于 grub-mkconfig。
基本的 GRUB 配置文件使用以下选项
(hdX,Y)
是磁盘 X 上的分区 Y,分区号从 1 开始,磁盘号从 0 开始set default=N
是在用户操作超时后选择的默认引导条目set timeout=M
是在默认引导之前等待用户选择的时间 M,以秒为单位menuentry "title" {entry options}
是标题为title
的引导条目set root=(hdX,Y)
设置引导分区,内核和 GRUB 模块存储在该分区中(引导分区不必是单独的分区,而可以只是“根”分区 (/
) 下的目录)
LoaderDevicePartUUID
为了让 GRUB 设置 systemd-gpt-auto-generator(8) 为 GPT 分区自动挂载 所需的 LoaderDevicePartUUID
UEFI 变量,请在 grub.cfg
中加载 bli
模块
if [ "$grub_platform" = "efi" ]; then insmod bli fi
/boot/grub/grub.cfg
时使用。将它们添加到 /etc/grub.d/40_custom
并 重新生成主配置文件 或将它们添加到 /boot/grub/custom.cfg
。有关管理多个 GRUB 条目的提示,例如,当同时使用 linux 和 linux-lts 内核时,请参阅 /技巧和提示#多个条目。
有关 Archiso 和 Archboot 引导菜单条目,请参阅 多启动 USB 驱动器#引导条目。
GRUB 命令
menuentry "System shutdown" { echo "System shutting down..." halt }
menuentry "System restart" { echo "System rebooting..." reboot }
if [ ${grub_platform} == "efi" ]; then menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' { fwsetup } fi
EFI 二进制文件
当在 UEFI 模式下启动时,GRUB 可以链式加载其他 EFI 二进制文件。
if
语句中if [ ${grub_platform} == "efi" ]; then place UEFI-only menu entries here fi
UEFI Shell
你可以通过将 UEFI Shell 放置在 EFI 系统分区 的根目录中并添加此菜单项来启动它
menuentry "UEFI Shell" { insmod fat insmod chain search --no-floppy --set=root --file /shellx64.efi chainloader /shellx64.efi }
gdisk
下载 gdisk EFI 应用程序 并将 gdisk_x64.efi
复制到 esp/EFI/tools/
。
menuentry "gdisk" { insmod fat insmod chain search --no-floppy --set=root --file /EFI/tools/gdisk_x64.efi chainloader /EFI/tools/gdisk_x64.efi }
链式加载统一内核镜像
如果你有一个从遵循 安全启动 或其他方式生成的 统一内核镜像,你可以将其添加到引导菜单。例如
menuentry "Arch Linux" { insmod fat insmod chain search --no-floppy --set=root --fs-uuid FILESYSTEM_UUID chainloader /EFI/Linux/arch-linux.efi }
双启动
GNU/Linux
假设另一个发行版在分区 sda2
上
menuentry "Other Linux" { set root=(hd0,2) linux /boot/vmlinuz (add other options here as required) initrd /boot/initrd.img (if the other kernel uses/needs one) }
或者让 GRUB 通过 UUID 或文件系统标签搜索正确的分区
menuentry "Other Linux" { # assuming that UUID is 763A-9CB6 search --no-floppy --set=root --fs-uuid 763A-9CB6 # search by label OTHER_LINUX (make sure that partition label is unambiguous) #search --no-floppy --set=root --label OTHER_LINUX linux /boot/vmlinuz (add other options here as required, for example: root=UUID=763A-9CB6) initrd /boot/initrd.img (if the other kernel uses/needs one) }
如果另一个发行版已经有一个包含已安装 GRUB、grub.cfg
、内核和 initramfs 的有效 /boot
文件夹,则可以指示 GRUB 在启动时动态加载这些其他的 grub.cfg
文件。例如,对于 hd0
和第四个 GPT 分区
menuentry "configfile hd0,gpt4" { insmod part_gpt insmod btrfs insmod ext2 set root='hd0,gpt4' configfile /boot/grub/grub.cfg }
选择此条目时,GRUB 会从另一个卷加载 grub.cfg
文件并显示该菜单。文件中命令所做的任何环境变量更改在 configfile
返回后都不会保留。按 Esc
返回到第一个 GRUB 菜单。
在 UEFI/GPT 模式下安装的 Windows
此模式确定 Windows 启动加载程序的位置,并在选择菜单项后在 GRUB 之后链式加载它。这里的主要任务是找到 EFI 系统分区并从中运行引导加载程序。
if [ "${grub_platform}" == "efi" ]; then menuentry "Microsoft Windows Vista/7/8/8.1 UEFI/GPT" { insmod part_gpt insmod fat insmod chain search --no-floppy --fs-uuid --set=root $hints_string $fs_uuid chainloader /EFI/Microsoft/Boot/bootmgfw.efi } fi
其中 $hints_string
和 $fs_uuid
是通过以下两个命令获得的。
$fs_uuid
命令确定 EFI 系统分区的 UUID
# grub-probe --target=fs_uuid esp/EFI/Microsoft/Boot/bootmgfw.efi
1ce5-7f28
或者,可以运行 lsblk --fs
并从中读取 EFI 系统分区的 UUID。
$hints_string
命令将确定 EFI 系统分区的位置,在本例中为硬盘驱动器 0
# grub-probe --target=hints_string esp/EFI/Microsoft/Boot/bootmgfw.efi
--hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1
这两个命令假定 Windows 使用的 ESP 挂载在 esp
上。Windows 的 EFI 文件的路径可能存在大小写差异,这毕竟是 Windows。
在 BIOS/MBR 模式下安装的 Windows
bootmgr
,并且不再需要 链式加载 分区引导扇区来在 BIOS/MBR 设置中引导 Windows。/bootmgr
的是系统分区,而不是你的“真实” Windows 分区(通常是 C:
)。系统分区的 文件系统标签 是 System Reserved
或 SYSTEM
,并且分区大小只有大约 100 到 549 MiB。有关更多信息,请参阅 Wikipedia:系统分区和引导分区。在本节中,假定你的 Windows 分区是 /dev/sda1
。不同的分区将更改每个 hd0,msdos1
的实例。
在两个示例中,XXXX-XXXX
都是文件系统 UUID,可以使用命令 lsblk --fs
找到。
对于 Windows Vista/7/8/8.1/10
if [ "${grub_platform}" == "pc" ]; then menuentry "Microsoft Windows Vista/7/8/8.1/10 BIOS/MBR" { insmod part_msdos insmod ntfs insmod ntldr search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 XXXX-XXXX ntldr /bootmgr } fi
对于 Windows XP
if [ "${grub_platform}" == "pc" ]; then menuentry "Microsoft Windows XP" { insmod part_msdos insmod ntfs insmod ntldr search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 XXXX-XXXX ntldr /ntldr } fi
\boot\bcd
错误(错误代码 0xc000000f
),则无法引导 Windows。你可以通过转到 Windows 恢复控制台(来自安装盘的 cmd.exe
)并执行以下操作来修复它X:\> bootrec.exe /fixboot X:\> bootrec.exe /RebuildBcd
不要 使用 bootrec.exe /Fixmbr
,因为它会擦除 GRUB。或者你可以使用故障排除菜单中的启动修复功能 - 它不会擦除 GRUB,但会修复大多数错误。此外,你最好只插入目标硬盘驱动器和你的可引导设备。如果连接了任何其他设备,Windows 通常无法修复引导信息。
使用标签
可以使用文件系统标签(附加到文件系统的用户可读字符串),方法是使用 search
命令的 --label
选项。首先,确保你的文件系统具有标签。
然后,添加使用标签的条目。这是一个例子
menuentry "Arch Linux, session texte" { search --label --set=root archroot linux /boot/vmlinuz-linux root=/dev/disk/by-label/archroot ro initrd /boot/initramfs-linux.img }
使用命令行 shell
由于 MBR 太小,无法存储所有 GRUB 模块,因此只有菜单和一些基本命令驻留在那里。GRUB 的大部分功能保留在 /boot/grub/
中的模块中,这些模块是根据需要插入的。在错误情况下(例如,如果分区布局更改),GRUB 可能无法启动。发生这种情况时,可能会出现命令行 shell。
GRUB 提供多个 shell/提示符。如果读取菜单时出现问题,但引导加载程序能够找到磁盘,你可能会被放入“normal” shell
grub>
如果存在更严重的问题(例如,GRUB 找不到所需的文件),你可能会被放入“rescue” shell
grub rescue>
救援 shell 是 normal shell 的受限子集,提供的功能少得多。如果转储到救援 shell,请首先尝试插入“normal”模块,然后启动“normal” shell
grub rescue> set prefix=(hdX,Y)/boot/grub grub rescue> insmod (hdX,Y)/boot/grub/i386-pc/normal.mod rescue:grub> normal
分页器支持
GRUB 支持分页器,用于读取提供长输出的命令(如 help
命令)。这仅在 normal shell 模式下有效,在救援模式下无效。要启用分页器,请在 GRUB 命令行 shell 中键入
sh:grub> set pager=1
使用命令行 shell 环境引导操作系统
grub>
GRUB 的命令行 shell 环境可用于引导操作系统。常见的场景可能是通过链式加载引导存储在驱动器/分区上的 Windows / Linux。
链式加载意味着从当前引导加载程序加载另一个引导加载程序,即链式加载。
另一个引导加载程序可以嵌入在分区磁盘的开头 (MBR)、分区或无分区磁盘的开头 (VBR),或者在 UEFI 的情况下作为 EFI 二进制文件。
链式加载分区的 VBR
set root=(hdX,Y) chainloader +1 boot
X=0,1,2... Y=1,2,3...
例如,要链式加载存储在第一个硬盘驱动器的第一个分区中的 Windows,
set root=(hd0,1) chainloader +1 boot
类似地,可以链式加载安装在分区中的 GRUB。
链式加载磁盘的 MBR 或无分区磁盘的 VBR
set root=hdX chainloader +1 boot
链式加载在 UEFI 模式下安装的 Windows/Linux
insmod fat set root=(hd0,gpt4) chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi boot
insmod fat
用于加载 FAT 文件系统模块,以便访问 EFI 系统分区上的 Windows 引导加载程序。(hd0,gpt4)
或 /dev/sda4
在此示例中是 EFI 系统分区。chainloader
行中的条目指定要链式加载的 .efi 文件的路径。
正常加载
请参阅 #使用救援控制台 中的示例
使用救援控制台
首先参阅 #使用命令行 shell。如果无法激活标准 shell,一种可能的解决方案是使用 live CD 或其他救援磁盘来纠正配置错误并重新安装 GRUB。但是,这样的引导磁盘并非总是可用(也不是必要的);救援控制台非常强大。
GRUB 救援中可用的命令包括 insmod
、ls
、set
和 unset
。此示例使用 set
和 insmod
。set
修改变量,insmod
插入新模块以添加功能。
在开始之前,用户必须知道其 /boot
分区的位置(无论是单独的分区还是根目录下的子目录)
grub rescue> set prefix=(hdX,Y)/boot/grub
其中 X
是物理驱动器号,Y
是分区号。
/boot
(即键入 set prefix=(hdX,Y)/grub
)。要扩展控制台功能,请插入 linux
模块
grub rescue> insmod i386-pc/linux.mod
或简
grub rescue> insmod linux
这引入了 linux
和 initrd
命令,你应该很熟悉它们。
一个示例,引导 Arch Linux
set root=(hd0,5) linux /boot/vmlinuz-linux root=/dev/sda5 initrd /boot/initramfs-linux.img boot
对于单独的引导分区(例如,当使用 UEFI 时),再次相应地更改行
set root=(hd0,5) linux (hdX,Y)/vmlinuz-linux root=/dev/sda6 initrd (hdX,Y)/initramfs-linux.img boot
linux
命令期间遇到 error: premature end of file /YOUR_KERNEL_NAME
错误,你可以尝试使用 linux16
代替。成功引导 Arch Linux 安装后,用户可以根据需要更正 grub.cfg
,然后重新安装 GRUB。
要重新安装 GRUB 并完全解决问题,请根据需要更改 /dev/sda
。有关详细信息,请参阅 #安装。
GRUB 移除
UEFI 系统
在移除 grub 之前,请确保已安装并配置了其他引导加载程序以接管。
$ efibootmgr
BootOrder: 0003,0001,0000,0002 Boot0000* Windows Boot Manager HD(2,GPT,4dabbedf-191b-4432-bc09-8bcbd1d7dabf,0x109000,0x32000)/File(\EFI\Microsoft\Boot\bootmgfw.efi) Boot0001* GRUB HD(2,GPT,4dabbedf-191b-4432-bc09-8bcbd1d7dabf,0x109000,0x32000)/File(\EFI\GRUB\grubx64.efi) Boot0002* Linux-Firmware-Updater HD(2,GPT,5dabbedf-191b-4432-bc09-8bcbd1d7dabf,0x109000,0x32000)/File(\EFI\arch\fwupdx64.efi) Boot0003* Linux Boot Manager HD(2,GPT,4dabbedf-191b-4432-bc09-8bcbd1d7dabf,0x109000,0x32000)/File(\EFI\systemd\systemd-bootx64.efi)
如果 BootOrder
将 grub 作为第一个条目,请安装另一个引导加载程序将其放在前面,例如上面的 systemd-boot。然后可以使用 grub 的 bootnum 移除 grub。
# efibootmgr --delete-bootnum -b 1
还要删除 esp/EFI/grub
和 /boot/grub
目录。
BIOS 系统
要用任何其他 BIOS 引导加载程序替换 grub,只需安装它们,这将覆盖 MBR 引导代码。
grub-install
创建了 /boot/grub
目录,需要手动删除该目录。但是,如果用户想再次安装 grub,一些用户可能希望保留它。
迁移到 UEFI/GPT 后,你可能想要 使用 dd 移除 MBR 引导代码。
故障排除
不支持的文件系统
如果 GRUB 不支持根文件系统,则必须创建一个具有受支持文件系统的备用 /boot
分区。在某些情况下,GRUB 的开发版本 grub-gitAUR 可能具有对该文件系统的原生支持。
如果 GRUB 与不支持的文件系统一起使用,它将无法提取驱动器的 UUID,因此它会改用经典的非持久性 /dev/sdXx
名称。在这种情况下,你可能必须手动编辑 /boot/grub/grub.cfg
并将 root=/dev/sdXx
替换为 root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
。你可以使用 blkid
命令来获取设备的 UUID,请参阅 持久块设备命名。
虽然 GRUB 自 2.0.4 版本以来支持 F2FS,但它无法从使用启用了 extra_attr
标志创建的 F2FS 分区中正确读取其引导文件。
启用调试消息
添加
set pager=1 set debug=all
到 grub.cfg
。
msdos 风格的错误消息
grub-setup: warn: This msdos-style partition label has no post-MBR gap; embedding will not be possible! grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and its use is discouraged. grub-setup: error: If you really want blocklists, use --force.
当尝试在 VMware 容器中安装 GRUB 时,可能会发生此错误。在此处阅读有关它的更多信息 此处。当第一个分区在 MBR(块 63)之后立即开始时,没有通常的 1 MiB(2048 个块)空间在第一个分区之前时,就会发生这种情况。阅读 #主引导记录 (MBR) 特定说明
UEFI
常见的安装错误
- 在某些 UEFI 设备上可能发生的错误是
Could not prepare Boot variable: Read-only file system
。你必须以读写方式重新挂载/sys/firmware/efi/efivars
。# mount -o remount,rw,nosuid,nodev,noexec --types efivarfs efivarfs /sys/firmware/efi/efivars
请参阅 Gentoo Wiki 上关于安装 引导加载程序 的信息。 - 如果你在运行带有 sysfs 或 procfs 的 grub-install 时遇到问题,并且它说你必须运行
modprobe efivarfs
,请尝试使用上面的命令 挂载 efivarfs。 - 如果没有
--target
或--directory
选项,grub-install 无法确定为哪个固件安装。在这种情况下,grub-install
将打印source_dir does not exist. Please specify --target or --directory
。 - 如果在运行 grub-install 后收到
error: esp doesn't look like an EFI partition
,则该分区很可能不是 FAT32 格式化的。
在固件引导管理器中创建 GRUB 条目
grub-install
会自动尝试在引导管理器中创建菜单条目。如果它没有这样做,请参阅 UEFI#efibootmgr 以获取有关使用 efibootmgr
创建菜单条目的说明。但是,问题很可能是你没有在 UEFI 模式下引导 CD/USB,如 安装指南#验证引导模式 中所述。
作为在固件引导管理器中创建 GRUB 条目的另一个示例,请考虑 efibootmgr -c
。这假定 /dev/sda1
是 EFI 系统分区,并且挂载在 /boot/efi
。这是 efibootmgr
的默认行为。它创建一个名为“Linux”的新引导选项,并将其放在引导顺序列表的顶部。可以传递选项来修改默认行为。默认操作系统加载程序是 \EFI\arch\grub.efi
。
进入救援 shell
如果 GRUB 加载但没有错误地进入救援 shell,则可能是由于以下两个原因之一
- 可能是因为缺少或放错位置的
grub.cfg
。如果使用--boot-directory
安装 GRUB UEFI 并且缺少grub.cfg
,则会发生这种情况, - 如果硬编码到
grubx64.efi
文件中的引导分区已更改,也会发生这种情况。
GRUB UEFI 未加载
一个正常工作的 UEFI 示例
# efibootmgr -u
BootCurrent: 0000 Timeout: 3 seconds BootOrder: 0000,0001,0002 Boot0000* GRUB HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\EFI\GRUB\grubx64.efi) Boot0001* Shell HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\shellx64.efi) Boot0002* Festplatte BIOS(2,0,00)P0: SAMSUNG HD204UI
如果屏幕只黑屏一秒钟,然后尝试下一个引导选项,根据 此帖子,将 GRUB 移动到分区根目录可能会有所帮助。之后必须删除并重新创建引导选项。然后 GRUB 的条目应如下所示
Boot0000* GRUB HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\grubx64.efi)
默认/回退引导路径
一些 UEFI 固件需要在已知位置有一个可引导文件,然后它们才会显示 UEFI NVRAM 引导条目。如果是这种情况,grub-install
将声明 efibootmgr
已添加条目以引导 GRUB,但该条目不会显示在 VisualBIOS 引导顺序选择器中。解决方案是将 GRUB 安装在默认/回退引导路径
# grub-install --target=x86_64-efi --efi-directory=esp --removable
或者,你可以将已安装的 GRUB EFI 可执行文件移动到默认/回退路径
# mv esp/EFI/grub esp/EFI/BOOT # mv esp/EFI/BOOT/grubx64.efi esp/EFI/BOOT/BOOTX64.EFI
无效签名
如果尝试引导 Windows 导致“无效签名”错误,例如在重新配置分区或添加其他硬盘驱动器后,(重新)移动 GRUB 的设备配置并让它重新配置
# mv /boot/grub/device.map /boot/grub/device.map-old # grub-mkconfig -o /boot/grub/grub.cfg
grub-mkconfig
现在应该提到所有找到的引导选项,包括 Windows。如果它有效,请删除 /boot/grub/device.map-old
。
引导冻结
如果在 GRUB 加载内核和初始 ramdisk 后,引导卡住没有任何错误消息,请尝试删除 add_efi_memmap
内核参数。
从其他操作系统找不到 Arch
有些人报告说,其他发行版可能难以使用 os-prober
自动找到 Arch Linux。如果出现此问题,则据报告,/etc/lsb-release
的存在可以改善检测。此文件和更新工具可通过软件包 lsb-release 获得。
在 chroot 中安装时的警告
在 chroot 环境(例如在系统安装期间)中的 LVM 系统上安装 GRUB 时,你可能会收到如下警告
/run/lvm/lvmetad.socket: connect failed: No such file or directory
或
WARNING: failed to connect to lvmetad: No such file or directory. Falling back to internal scanning.
这是因为 /run
在 chroot 内部不可用。如果一切都已正确完成,这些警告不会阻止系统启动,因此你可以继续安装。
GRUB 加载缓慢
当磁盘空间不足时,GRUB 可能需要很长时间才能加载。检查你的 /boot
或 /
分区上是否有足够的可用磁盘空间,当你遇到问题时。
error: unknown filesystem
GRUB 可能会输出 error: unknown filesystem
并拒绝引导,原因有几个。如果你确定所有 UUID 都是正确的,并且所有文件系统都是有效且受支持的,则可能是因为你的 BIOS 引导分区 位于驱动器的前 2 TiB 之外 [4]。使用你选择的分区工具来确保此分区完全位于前 2 TiB 内,然后重新安装和重新配置 GRUB。
此错误也可能是由 ext4 文件系统设置了不支持的功能引起的
large_dir
- 不支持。metadata_csum_seed
- 将在 GRUB 2.11 中支持 (commit)。
/boot
文件系统上启用新的 文件系统 功能之前,请务必检查 GRUB 对这些功能的支持。grub-reboot 未重置
GRUB 似乎无法写入根 Btrfs 分区 [5]。如果你使用 grub-reboot 引导到另一个条目,它将无法更新其磁盘上的环境。可以从另一个条目运行 grub-reboot(例如,在各种发行版之间切换时)或考虑使用不同的文件系统。你可以通过执行 grub-editenv create
并在你的 /etc/default/grub
中设置 GRUB_DEFAULT=0
来重置“粘性”条目(不要忘记 grub-mkconfig -o /boot/grub/grub.cfg
)。
旧 Btrfs 阻止安装
如果驱动器格式化为 Btrfs 而没有创建分区表(例如 /dev/sdx),然后在之后写入分区表,则 BTRFS 格式的某些部分会持久存在。大多数实用程序和操作系统看不到这一点,但 GRUB 将拒绝安装,即使使用 --force 也是如此
# grub-install: warning: Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet.. # grub-install: error: filesystem `btrfs' does not support blocklists.
你可以将驱动器清零,但保留数据的简单解决方案是使用 wipefs -o 0x10040 /dev/sdx
擦除 Btrfs 超级块
找不到 Windows 8/10
Windows 8/10 中名为“Hiberboot”、“Hybrid Boot”或“Fast Boot”的设置可能会阻止挂载 Windows 分区,因此 grub-mkconfig
将找不到 Windows 安装。在 Windows 中禁用 Hiberboot 将允许将其添加到 GRUB 菜单。
GRUB 救援和加密 /boot
当使用 加密 /boot 并且你未能输入正确的密码时,你将被放入 grub-rescue 提示符。
此 grub-rescue 提示符的功能有限。使用以下命令完成引导
grub rescue> cryptomount <partition> grub rescue> insmod normal grub rescue> normal
有关更好的描述,请参阅 此博客文章。
检查 /etc/default/grub
中的 GRUB_TIMEOUT
是否设置为 0
,如果是,则将其设置为正数:它设置加载默认 GRUB 条目之前的秒数。另请检查 GRUB_TIMEOUT_STYLE
是否设置为 hidden
并将其设置为 menu
,以便默认显示菜单。然后 重新生成主配置文件 并重新启动以检查是否有效。
如果它不工作,可能是图形终端存在不兼容问题。在 /etc/default/grub
中将 GRUB_TERMINAL_OUTPUT
设置为 console
以禁用 GRUB 图形终端。
GRUB 已安装,但在较旧的 Lenovo 机器上收到 “ERROR CODE 1962 - No operating system found” 消息
请参阅 通过欺骗 EFI 启动项修复 Lenovo 的 ERROR CODE 1962。