GRUB (简体中文)/Tips and tricks (简体中文)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


其它安装方式

安装到 U 盘

BIOS

假设 U 盘的第一个分区是 FAT32格式,其分区是/dev/sdy1

# mkdir -p /mnt/usb
# mount /dev/sdy1 /mnt/usb
# grub-install --target=i386-pc --debug --boot-directory=/mnt/usb/boot /dev/sdy
# grub-mkconfig -o /mnt/usb/boot/grub/grub.cfg

可以选择将配置备份到 grub.cfg

# mkdir -p /mnt/usb/etc/default
# cp /etc/default/grub /mnt/usb/etc/default
# cp -a /etc/grub.d /mnt/usb/etc
# sync; umount /mnt/usb

EFI

在你运行 grub-install 的时候使用 --removable 选项,就可以让 GRUB 把它的 EFI 映像写入到 /boot/efi/EFI/BOOT/BOOTX64.efi,这样启动固件就可以在没有 UEFI 启动条目的的情况下找到。

安装到分区上或者无分区磁盘上

警告: GRUB 极不推荐 将其安装到分区启动扇区或者无分区磁盘上(Grub Legacy 和 syslinux 相反)。这种安装方式不安全,当升级时可能会损坏。Arch 开发人员也 不支持 这种方式.

下面的命令将会将 GRUB 安装到分区扇区或者无分区磁盘(也称作超级软盘),或者安装到软盘上。下面例子中以 /dev/sdaX 作为 /boot 分区。

# chattr -i /boot/grub/i386-pc/core.img
# grub-install --target=i386-pc --debug --force /dev/sdaX
# chattr +i /boot/grub/i386-pc/core.img
注意:
  • /dev/sdaX 仅用作示例。
  • --target=i386-pcgrub-install 仅为 BIOS 系统安装。建议总是使用这个选项来排除 grub-install 命令中的模糊性。

你应该使用 --force 选项来启用对 blocklists(块列表)的支持,而不应该使用 --grub-setup=/bin/true,后者类似于单纯地生成 core.img

grub-install 会生成以下警告,来提醒你哪里有可能出现问题。

/sbin/grub-setup: warn: Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.
/sbin/grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists.
                        However, blocklists are UNRELIABLE and their use is discouraged.

不使用 --force 选项则可能会出现以下错误,并且 grub-setup 不会将启动代码安装到启动扇区上:

/sbin/grub-setup: error: will not proceed with blocklists

而指定了 --force,会出现:

Installation finished. No error reported.

grub-setup 默认不启用这个选项,是因为在分区或者无分区磁盘上,grub 依赖于嵌入分区引导扇区的块列表 (blocklists) 来定位 /boot/grub/i386-pc/core.img 和前缀目录 /boot/grub。而 core.img 在分区上的扇区位置很有可能随着分区文件系统的更改而变化(复制文件,删除文件等)。详情请参考 https://bugzilla.redhat.com/show_bug.cgi?id=728742https://bugzilla.redhat.com/show_bug.cgi?id=730915.

临时解决方案是给 /boot/grub/i386-pc/core.img 文件加“不可变”(immutable) 标志(按照上面提过的,使用 chattr 命令)。这样 core.img 文件的位置就不会变。只有当将 GRUB 安装到分区启动扇区或者无分区磁盘上时才需要给 /boot/grub/i386-pc/core.img 加上“不可变”标志,在安装到 MBR 或者单纯地生成 core.img 而不嵌入到其他引导扇区里的时候,就不用添加(正如上面所述)。

然而即使没有报错,生成的 grub.cfg 文件也不会包含正确的 UUID。参考 https://bbs.archlinux.org/viewtopic.php?pid=1294604#p1294604 。 要解决这个问题,使用如下命令:

# mount /dev/sdxY /mnt        #Your root partition.
# mount /dev/sdxZ /mnt/boot   #Your boot partition (if you have one).
# arch-chroot /mnt

现在,安装linux,然后:

# grub-mkconfig -o /boot/grub/grub.cfg

只生成 core.img

通过添加 --grub-setup=/bin/true 选项,grub-install 命令会填充 /boot/grub 文件夹并生成 /boot/grub/i386-pc/core.img,但是 不会 将 GRUB 启动引导代码嵌入到 MBR、MBR 后部区域或者分区引导扇区中。

# grub-install --target=i386-pc --grub-setup=/bin/true --debug /dev/sda
注意:
  • /dev/sda 仅是示例。
  • --target=i386-pcgrub-install 仅为 BIOS 系统安装。建议总是使用这个选项来排除 grub-install 命令中的模糊性。

生成后,Grub Legacy 或者 syslinux 就可以通过链式加载 GRUB 的 core.img 来间接加载 Linux 内核或者多启动内核了。参阅Syslinux (简体中文)#链式加载

图形化配置工具

  • grub-customizer — GRUB 或者 BURG 的 GTK 定制器
https://launchpad.net/grub-customizer || grub-customizer

视觉配置

GRUB 默认支持改变菜单外观。如果你没有初始化,请务必以视频模式 gfxmode 初始化 GRUB 图形终端 gfxterm。此视频模式由 GRUB 通过 gfxpayload 传递给 Linux 内核,任何视觉配置都需要这种模式才能够有效果。

设置帧缓冲分辨率

GRUB 既可以为自己,也可以为内核设定帧缓冲。现在已经不使用老的 vga= 配置了,推荐方法是在 /etc/default/grub 文件中按照下面的例子编辑,来设定宽度(像素)x高度(像素)x颜色深度

GRUB_GFXMODE=1024x768x32
GRUB_GFXPAYLOAD_LINUX=keep

可以指定多种分辨率,包括默认的 auto,所以建议你编辑成这个样:GRUB_GFXMODE=心仪的分辨率,后备分辨率比如 1024x768,auto。更多信息请见 GRUB gfxmode 文档gfxpayload 属性可以确保内核也保持该分辨率。

注意:
  • 只有显卡通过 VESA BIOS 拓展支持的模式才能用。要查看所支持的模式列表,安装 hwinfo 然后以 root 权限运行 hwinfo --framebuffer。或者进入 GRUB 命令行运行 videoinfo 命令。
  • 早期版本的 NVIDIA 专有驱动(使用显卡 GeForce GTX 970,驱动 nvidia 370 进行了测试)支持的 GRUB_GFXMODE 格式为 x-色深(例如 1920x1200-24,而不是 1920x1200x24)。这应该不会影响新的显卡和驱动。使用比较新的驱动的 Pascal 显卡(以 GeForce GTX 1060 显卡和 nvidia 381.22 驱动测试)没法使用上文建议的格式,而且会引发严重的问题,包括但不限于系统崩溃以及 hard lock。当前的驱动和显卡最好使用标准的 xx色深 格式来配置 GRUB_GFXMODE
  • 确保在修改完后运行 grub-mkconfig -o /boot/grub/grub.cfg

这种方法不管用的话,可以试试老的 vga= 方法。将它添加到 /etc/default/grub 文件中的 "GRUB_CMDLINE_LINUX_DEFAULT=" 一行就行了。比如 "GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=792" 可以将系统的分辨率设定为 1024x768

915resolution 破解

有些时候,Intel 显卡无法通过 # hwinfo --framebuffervbeinfo 显示你需要的分辨率。这种情况下,你可以使用 915resolution 破解。这种破解会临时性的修改显卡 BIOS 来添加所需的分辨率。详情请参考915resolution 主页。这个包可以在这里找到:915resolutionAUR

首先,找一个你想要修改的视频模式。为此需要在 GRUB 命令行模式下运行:

sh:grub> 915resolution -l
Intel 800/900 Series VBIOS Hack : version 0.5.3
[...]
Mode 30 : 640x480, 8 bits/pixel
[...]

然后,使用 1440x900 分辨率覆盖 Mode 30

/etc/grub.d/00_header
[...]
915resolution 30 1440 900  # Inserted line
set gfxmode=${GRUB_GFXMODE}
[...]

最后按照之前描述的方式设置 GRUB_GFXMODE,再重新生成 GRUB 配置文件,重启并测试是否生效。

背景图像和点阵字体

GRUB 原生支持设置背景图像和 pf2 格式的点阵字体。grub 包中包含了 unifont 字体,名为unicode.pf2,(也有可能只包含名为 ascii.pf2 的ASCII字符字体),运行pacman -Ql grub | grep pf2来得到对应的文件路径。

在载入正确的模块之后,GRUB 支持的图像格式有 tga, png 和 jpeg。所支持的最大图像分辨率跟硬件有关。

请确保你已经设定了合适的帧缓冲分辨率

按如下方式编辑 /etc/default/grub

GRUB_BACKGROUND="/boot/grub/myimage"
#GRUB_THEME="/path/to/gfxtheme"
GRUB_FONT="/path/to/font.pf2"
注意: 如果你将 GRUB 安装在单独的分区上,grub.cfg 文件中会自动将 /boot/grub/myimage 改成 /grub/myimage

需要重新生成 grub.cfg 来让修改起作用。如果成功添加了背景图片,用户会在运行命令的终端中看到 "Found background image..."。如果句话没有出现,你设定的图像信息可能没有成功添加进 grub.cfg 文件。

如果图像没有正确显示,执行如下检查:

  • /etc/default/grub 文件中,图像的路径和名字要正确
  • 图像的大小和格式要合适 (tga, png, 8-bit jpg)
  • 图像需要以 RGB 模式存储,而且没有索引
  • /etc/default/grub 文件里面开启了 console 模式
  • 需要执行 grub-mkconfig 命令以将图像信息写入 /boot/grub/grub.cfg 文件
  • grub-mkconfig 脚本不会对 grub.cfg 文件中所写的文件名添加引号,所以要确保这些名字里没有空格

主题

下面的例子将展示如何使用 GRUB 包里面的 Starfield 主题:

编辑 /etc/default/grub

GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"

需要重新生成 grub.cfg 来让修改起作用。如果配置成功的话,在重生成配置过程中,会在终端里出现 Found theme: /usr/share/grub/themes/starfield/theme.txt

一旦使用了主题,你设置的背景图像通常就不起作用了。

菜单颜色

GRUB 支持设置菜单颜色。可使用的颜色能从 GRUB 手册里面找到。示例如下:

编辑 /etc/default/grub

GRUB_COLOR_NORMAL="light-blue/black"
GRUB_COLOR_HIGHLIGHT="light-cyan/blue"

隐藏菜单

GRUB 特性之一就是支持隐藏/跳过菜单,可以在需要的时候按 Esc 来取消隐藏/跳过。同时还支持设置是否显示 timeout 计时器。

按照你的想法来编辑 /etc/default/grub。添加下面的几行可以启动这个功能,其中计时器被设定为 5 秒钟,而且可以被用户看到:

GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE='countdown'

GRUB_TIMEOUT 是设置显示菜单前等待几秒。

禁用 framebuffer

使用 NVIDIA 私有驱动的用户可能希望禁用 GRUB 的 framebuffer,因为它会导致驱动错误。

要禁用 framebuffer,只要在 /etc/default/grub 中取消下面这行的注释:

GRUB_TERMINAL_OUTPUT=console

如果你想保留 GRUB 的 framebuffer,解决方法是在 GRUB 载入内核前进入文字模式。可以通过在 /etc/default/grub 中进行如下修改:

GRUB_GFXPAYLOAD_LINUX=text

通过 GRUB 直接启动 ISO9660 映像文件

GRUB 支持通过 loopback 设备直接从 ISO 映像启动,例如参考 Multiboot USB drive#Using GRUB and loopback devices

用密码保护 GRUB 菜单

警告: 如果有人能对你的机器进行物理上的访问,而且可以使用 Live USB 或磁盘启动(例如 BIOS 允许从外接磁盘启动),而 /boot 又处于一个没有加密的分区上面,那他就可以非常简单地通过编辑 GRUB 设置文件来绕过下面的这些。参考GRUB (简体中文)#/boot 加密Security (简体中文)#磁盘加密

如果你想禁止其他人改变启动参数或者使用 GRUB 命令行,可以给 GRUB 的配置文件关联一个用户名/密码。只需 运行 grub-mkpasswd-pbkdf2,输入密码然后确认:

grub-mkpasswd-pbkdf2
[...]
Your PBKDF2 is grub.pbkdf2.sha512.10000.C8ABD3E93C4DFC83138B0C7A3D719BC650E6234310DA069E6FDB0DD4156313DA3D0D9BFFC2846C21D5A2DDA515114CF6378F8A064C94198D0618E70D23717E82.509BFA8A4217EAD0B33C87432524C0B6B64B34FBAD22D3E6E6874D9B101996C5F98AB1746FE7C7199147ECF4ABD8661C222EEEDB7D14A843261FFF2C07B1269A

修改/etc/grub.d/40_custom的权限以确保只有root能够查看该文件的内容,然后将下面的内容添加到此文件:

/etc/grub.d/40_custom
set superusers="用户名"
password_pbkdf2 用户名 密码

这里的 密码 是由 grub-mkpasswd_pbkdf2 所生成的那个字符串。

然后重新生成主配置文件,现在你的 GRUB 命令行、启动参数和所有的启动条目都得到保护了。

可以参考 GRUB 手册中的 "Security" 部分来将设置放宽或者针对多用户进行更复杂的定制。

只针对编辑 GRUB 和控制台选项进行密码保护

对一个菜单条目添加 --unrestricted 选项将会允许所有的用户启动这个操作系统,但却不能修改这个条目,也不能进入 GRUB 命令行控制台。 只有超级用户或者由 --user 开关指定的用户才能修改这个菜单条目。

/boot/grub/grub.cfg
menuentry 'Arch Linux' --unrestricted --class arch --class gnu-linux --class os ...

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: /etc/grub.d/10_linux 文件不应该被手工编辑,每次升级 grub 包都会自动把它覆盖掉。 (Discuss in Talk:GRUB (简体中文)/Tips and tricks (简体中文))

要给 Linux 启动条目添加 --unrestricted,可以修改 /etc/grub.d/10_linux 文件开头的 CLASS 变量。

/etc/grub.d/10_linux
CLASS="--class gnu-linux --class gnu --class os --unrestricted"

在没有按着 SHIFT 键时隐藏 GRUB 界面

为了获取更快的启动速度,而不用等 GRUB 倒计时,可以命令 GRUB 在启动时隐藏目录,仅在 Shift 被按住的时候才显示。

将如下行添加到/etc/default/grub来启动这个功能:

 GRUB_FORCE_HIDDEN_MENU="true"

然后创建/etc/grub.d/31_hold_shift 文件并写入以下链接中的内容:[1],给它可执行权限,然后重新生成主配置文件:

# chmod a+x /etc/grub.d/31_hold_shift
# grub-mkconfig -o /boot/grub/grub.cfg
注意: 这个设置使用 keystatus 来检测按键事件,所以可能在某些机器上不能用。

将 UUID 和基础脚本结合使用

如果你想要使用 UUID 来避免不可靠的 BIOS 设备命名或者正在研究 GRUB 语法,这里有个使用了 UUID 的启动菜单项,和一个让 GRUB 使用你系统中正确的磁盘分区的小脚本。如果你想要将其移植到自己的系统上,只需要把 UUID 改成你的系统上的就行了。这个例子假设系统的 boot 和 root 文件系统是在不同的分区上,如果你还有其他分区,请相应地修改 GRUB 设置。

menuentry "Arch Linux 64" {
    # Set the UUIDs for your boot and root partition respectively
    set the_boot_uuid=ece0448f-bb08-486d-9864-ac3271bd8d07
    set the_root_uuid=c55da16f-e2af-4603-9e0b-03f5f565ec4a

    # (Note: This may be the same as your boot partition)

    # Get the boot/root devices and set them in the root and grub_boot variables
    search --fs-uuid $the_root_uuid --set=root
    search --fs-uuid $the_boot_uuid --set=grub_boot

    # Check to see if boot and root are equal.
    # If they are, then append /boot to $grub_boot (Since $grub_boot is actually the root partition)
    if [ $the_boot_uuid == $the_root_uuid ] ; then
        set grub_boot=($grub_boot)/boot
    else
        set grub_boot=($grub_boot)
    fi

    # $grub_boot now points to the correct location, so the following will properly find the kernel and initrd
    linux $grub_boot/vmlinuz-linux root=/dev/disk/by-uuid/$the_root_uuid ro
    initrd $grub_boot/initramfs-linux.img
}

多个启动条目

取消子菜单

如果你安装了多个内核,比如说 linux 和 linux-lts,那么 grub-mkconfig 默认会把他们分成一组建立一个子菜单。如果你不想这样,可以在 /etc/default/grub 文件里添加下面这行来回到仅有一个菜单的情形:

 GRUB_DISABLE_SUBMENU=y

调用之前的启动条目

GRUB 能够记住你最近一次使用的启动项,并且在下次启动时将其作为默认项。当你使用多个内核或操作系统时(比如当前的 Arch 和一个用来做后备选项的 LTS 内核),这个特性很有用。要开启这个功能,编辑 /etc/default/grub 中的 GRUB_DEFAULT 选项:

GRUB_DEFAULT=saved

上面的命令会告诉 GRUB 使用记住的启动项为默认启动项。要想让 GRUB 记住当前选择的启动项,将下面的行添加到 /etc/default/grub

GRUB_SAVEDEFAULT=true

仅当 /boot 不是 btrfs 文件系统的时候才能用,因为 GRUB 没法对 btrfs 进行写入操作。但它会生成一个容易误导人的错误信息:"sparse file not allowed. Press any key to continue."

注意: 手动添加启动项到 /etc/grub.d/40_custom/boot/grub/custom.cfg中,比如添加 Windows 启动项,需要先添加savedefault选项。

修改默认菜单条目

可以通过修改 /etc/default/grub 中的 GRUB_DEFAULT 值来改变默认启动项:

使用菜单标题:

GRUB_DEFAULT='Advanced options for Arch Linux>Arch Linux, with Linux linux'

使用数字编号:

 GRUB_DEFAULT="1>2"

GRUB 启动项序号从 0 开始计数,0 代表第一个启动项,也是上述选项的默认值,1 表示第二个启动项,以此类推。主菜单和子菜单项之间用 > 隔开。

上面的例子启动的是主菜单项 'Advanced options for Arch Linux' 下子菜单的第三项。

自动启动非默认启动条目(仅一次)

如果你想在下一次启动的时候启动一个非默认的启动项,命令 grub-reboot 非常有用。当系统下一次启动时,GRUB 会自动载入这个命令后的第一个参数所指的那个启动项,而以后再次启动时,GRUB 会回到正常状态加载默认条目。这样就不用修改配置文件或者在启动时进行手动选择了。

注意: 这个功能需要在 /etc/default/grub 中设定 GRUB_DEFAULT=saved,然后重新生成grub.cfg;或者在手动生成的 grub.cfg 中, 使用 set default="${saved_entry}"

演奏一曲

通过修改 GRUB_INIT_TUNE 变量,你可以在启动时(在引导菜单显示之前)让扬声器播放音乐。比如要演奏柏辽兹《幻想交响曲》“妖魔夜宴”乐章片段(大管部分),你可以添加下面的设置:

GRUB_INIT_TUNE="312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5"

Tango-edit-cut.pngThis section is being considered for removal.Tango-edit-cut.png

Reason: 这里应当只有一个链接,相关示例应当在其他地方查看(而不是在此页面中)。 (Discuss in Talk:GRUB (简体中文)/Tips and tricks (简体中文))

你可以通过创建以下文件,然后重新运行grub-mkconfig,添加一个菜单项来播放这些常见的GRUB_INIT_TUNE

/etc/grub.d/91_tune_demo
#!/bin/sh
exec tail -n +3 $0
menuentry "INIT_TUNE Demos" {
   echo "Close Encounters/5 Tone"
   play 480 900 2 1000 2 800 2 400 2 600 3
   echo "Fur Elise (note long)"
   play 480 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 262 1 315 1 335 3 213 1 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 330 1 315 1 282 3
   echo "Berlioz's extract from Sabbath Night of Symphonie Fantastique"
   play 312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5
   echo "Oldskool Batman tune"
   play 380 120 1 140 1 160 1 200 8 190 4
   echo "Legend of Zelda tune"
   play 12000 440 100 0 1 329 150 440 50 0 1 440 25 493 25 523 25 587 25 659 200
   echo "Super Mario"
   play 1000 334 1 334 1 0 1 334 1 0 1 261 1 334 1 0 1 392 2 0 4 196 2
   echo "Super Mario Alternate"
   play 480 165 2 165 2 165 3 554 1 587 1 554 2 370 1 554 1 523 2 349 1 523 1 494 3 165 2 165 2 165 2
   echo "Mario Mushroom"
   play 1750 523 1 392 1 523 1 659 1 784 1 1047 1 784 1 415 1 523 1 622 1 831 1 622 1 831 1 1046 1 1244 1 1661 1 1244 1 466 1 587 1 698 1 932 1 1175 1 1397 1 1865 1 1397 1
   echo "Star Wars Imperial Death March"
   play 480 440 4 440 4 440 4 349 3 523 1 440 4 349 3 523 1 440 8 659 4 659 4 659 4 698 3 523 1 415 4 349 3 523 1 440 8
   echo "My Little Pony"
   play 2400 587 18 554 4 587 8 659 12 587 16 0 10 587 4 659 4 740 8 587 4 784 12 740 8 659 8 587 4 740 20 587 40
   echo "Wolfenstein 3D"
   play 300 131 1 196 1 196 1 196 1 294 1 196 1 294 1 196 1 131 1
   echo "Mall (Nothing Special)"
   play 180 440 1 554 1 659 1
   echo "Final Countdown"
   play 480 554 1 494 1 554 4 370 6 10 3 587 1 554 1 587 2 554 2 494 6
   echo "Xie-Jelei's Tune"
   play 2000 400 4 0 1 500 4 0 1 600 4 0 1 800 6
   echo "Random tune"
   play 480 220 1 277 1 330 1 440 1 185 1 220 1 277 1 370 1 294 1 370 1 440 1 587 1 330 1 415 1 494 1 659 1
   echo "Fleetwood Mac: The Chain Bass Riff (about 5 seconds)"
   play 304 55 5 0 1 55 1 62 1 65 2 62 1 55 1 49 1 55 1 62 2 41 8
   echo "Fleetwood Mac: The Chain Bass Riff Extended Version (WARNING, 25 SECONDS)"
   play 9120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 60 41 12 42 3 43 3 44 3 45 3 46 6 47 3 48 3 49 6 50 3 51 3 52 6 53 3 54 3 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 240 82 20 0 10 82 26 0 4 82 26 0 4 82 26 0 4 82 56 0 4 82 60 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120
}

更多相关信息可以查看 info grub -n play

为早期启动手动配置核心映像

如果你需要用一个特殊的键盘布局,或者要让 GRUB 环境访问 /boot 的配置步骤太过复杂,导致 GRUB 没法自动配置,你可以自己生成一个核心映像。在 UEFI 系统上,核心映像就是在启动时需要被固件载入的 grubx64.efi 文件。自己建立一个核心映像,就可以嵌入在早期启动过程中需要用到的所有模块,以及用来引导 GRUB 配置脚本。

首先,假设在一个 UEFI 系统中,我们需要在早期启动过程中载入 dvorak 键盘布局,以输入 /boot 加密分区的密码。

从生成的 /boot/grub/grub.cfg 文件中查看需要使用哪些模块来挂载加密的 /boot 分区。例如在你的 menuentry 一项中你应该看到类似下面的内容:

insmod diskfilter cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256
insmod ext2
cryptomount -u 1234abcdef1234abcdef1234abcdef
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'

把这些模块都记下来,他们都应该被包含到核心映像里面。现在把你的键盘布局打包,它应该作为一个 memdisk 来嵌入到核心映像里:

# grub-kbdcomp -o dvorak.gkb dvorak
# tar cf memdisk.tar dvorak.gkb

现在创建需要在 GRUB 核心映像中使用的配置文件。这和正常的 GRUB 配置文件的格式是一样的,但只需要简单几行来载入 /boot 分区里的主配置文件就可以了:

early-grub.cfg
set root=(memdisk)
set prefix=($root)/

terminal_input at_keyboard
keymap /dvorak.gkb

cryptomount -u 1234abcdef1234abcdef1234abcdef
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'
set prefix=($root)/grub

configfile grub.cfg

最后,生成核心映像,列出在 grub.cfg 文件中所需要的所有模块,再加上 early-grub.cfg 脚本中所使用的模块。上例中需要的模块有 memdisk, tar, at_keyboard, keylayoutsconfigfile

# grub-mkimage -c early-grub.cfg -o grubx64.efi -O x86_64-efi -m memdisk.tar diskfilter cryptodisk luks gcry_rijndael gcry_sha256 ext2 memdisk tar at_keyboard keylayouts configfile

生成的 EFI 核心映像可以和由 grub-install 所自动生成的一样使用,把它放在你的 EFI 分区,然后使用 efibootmgr 来启用它,或者依照你的系统固件来适当地进行配置。

另请参阅 Debian cryptsetup docs.

UEFI 延伸阅读

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: 本节还可以更加简明有序。 (Discuss in Talk:GRUB (简体中文)/Tips and tricks (简体中文))

下面是关于通过 UEFI 安装 Arch 的其他相关信息。

另一种安装方法

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: 将GRUB的所有文件放在ESP中的原因是什么? (Discuss in Talk:GRUB (简体中文)/Tips and tricks (简体中文))

通常,不管 EFI 系统分区挂载到哪,GRUB 都会将所有文件包括配置文件放到 /boot

如果你想将所有的文件放在 EFI 系统分区中,请给 grub-install 命令添加 --boot-directory=esp 选项:

# grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=grub --boot-directory=esp --debug

这个命令会将 GRUB 文件放在 esp/grub 而不是 /boot/grub 中。使用这个方法,请确保 grub-mkconfig 将配置文件放在与上面一样的目录里:

# grub-mkconfig -o esp/grub/grub.cfg

其他的配置是完全一样的。

UEFI 固件解决方案

请参阅 GRUB (简体中文)#缺省/后备启动路径

在固件启动管理器中创建 GRUB 条目

grub-install 会自动尝试在启动管理器中创建 GRUB 条目。如果没有成功,请参考 Unified Extensible Firmware Interface (简体中文)#efibootmgr,里面有如何使用 efibootmgr 创建启动目录条目的介绍。一般来说,这个问题都是因为你没有以 UEFI 模式启动 CD/USB 造成的。请参考 Unified Extensible Firmware Interface (简体中文)#从 ISO 创建 UEFI 可启动 USB

独立的 GRUB

本节假设你要为 x86_64 系统 (x86_64-efi) 创建一个独立的 GRUB。至于 32 位 (IA32) EFI 系统,适当地将 x86_64-efi 修改成 i386-efi 就可以了。

你可以建立一个 grubx64_standalone.efi 应用,这个 UEFI 应用将所有的模组嵌入应用内部的一个 tar 包中,所以就不需要使用单独的目录来存放 GRUB UEFI 模组和其他相关文件了。使用 grub 包里的 grub-mkstandalone 命令按照下面的方法操作来实现这个功能:

# echo 'configfile ${cmdpath}/grub.cfg' > /tmp/grub.cfg
# grub-mkstandalone -d /usr/lib/grub/x86_64-efi/ -O x86_64-efi --modules="part_gpt part_msdos" --locales="en@quot" --themes="" -o "esp/EFI/grub/grubx64_standalone.efi" "boot/grub/grub.cfg=/tmp/grub.cfg" -v

然后把 GRUB 配置文件复制到 esp/EFI/grub/grub.cfg,再使用 efibootmgresp/EFI/grub/grubx64_standalone.efi 创建一个 UEFI 启动管理器条目。

注意: 要让 ${cmdpath} 功能正常工作,--modules="part_gpt part_msdos" 选项(包含引号)是必要的。
警告: 如果你在填写 ${cmdpath} 的时候漏掉一个斜杠(比如把 (hd1,msdos2)/EFI/Boot 写成 (hd1,msdos2)EFI/Boot),你就会发现 grub.cfg 文件没法读取,然后被迫进入 GRUB 命令行中。如果出现这样的问题,检查 ${cmdpath} 设置成了什么 (echo ${cmdpath} ),然后手工载入配置文件(例如 configfile (hd1,msdos2)/EFI/Boot/grub.cfg)。

技术信息

GRUB EFI 文件总是要配置文件放在 ${prefix}/grub.cfg。当然在独立的 GRUB EFI 文件中,${prefix} 位于一个 tar 包的内部,嵌入在 GRUB EFI 文件自身之中(在 GRUB 环境中,这被称作 (memdisk))。这个 tar 包包含了所有在正常的 GRUB EFI 下存储在 /boot/grub 中的文件。

因为将 /boot/grub 中的内容嵌入到了独立映像的内部,它就不再对任何实际的(外部的) /boot/grub 有任何依赖了。因此在独立 GRUB EFI 文件的情形下 ${prefix}==(memdisk)/boot/grub,而且独立的 GRUB EFI 文件认为其配置文件存放于 ${prefix}/grub.cfg==(memdisk)/boot/grub/grub.cfg

因此要让独立的 GRUB EFI 文件读取存储在与 EFI 文件相同目录(在 GRUB 环境中用 ${cmdpath} 表示)下的外部 grub.cfg 时,我们创建一个简单的 /tmp/grub.cfg 来让 GRUB 使用 ${cmdpath}/grub.cfg 来做其配置文件。(在 (memdisk)/boot/grub/grub.cfg 中使用 configfile ${cmdpath}/grub.cfg 命令。)然后我们给 grub-mkstandalone 添加 "boot/grub/grub.cfg=/tmp/grub.cfg" 选项,把这个 /tmp/grub.cfg 文件复制到 ${prefix}/grub.cfg(事实上就是 (memdisk)/boot/grub/grub.cfg)。

这样,独立的 GRUB EFI 文件和这个 grub.cfg 可以存放在 EFI 系统分区中的任何一个目录里,只有它们处在同一个目录中就可以。这样它们就变得可移植了。

加快GRUB中的LUKS解密速度

警告: 在阅读本节之前,请确保你了解高熵密码的重要性。关于如何生成安全密码的信息可以在Wikipedia:Password strength找到。

在启动时,GRUB在某些情况下可能需要很长的时间来验证密码。这可能是由于PBKDF的迭代次数太多,你可以按以下方法检查:

# cryptsetup luksDump /dev/sda3

问题是,给定的密钥槽的迭代次数是在添加钥匙时产生的,这个迭代次数需要确保既足够高来防止暴力攻击,也要使你的计算机尽可能快的推导出密钥。然而,当GRUB启动时,它可能没有同样的计算资源在手,因此推导速度会大大降低。

如果你的密码本身能提供足够的熵来对抗常见的攻击,你可以降低迭代次数。

# cryptsetup luksChangeKey --pbkdf-force-iterations 1000 /dev/sda3

根据RFC 2898,建议至少1000次迭代,但如果可以的话,你应该尽可能使用更高的数值(攻击者的成本以及密钥推导的时间是线性扩展的)。

提示: GRUB依次尝试启用密钥槽。在添加密钥时,可以使用--key-slot选项来明确指定一个密钥槽。

参考资料