如果您的系统支持 UEFI,且您希望通过 UEFI 引导 LFS,您应该跳过本页中的指令,但仍然阅读本页以学习
grub.cfg
的语法和在该文件中指定分区的方法,并按照
BLFS 页面中的说明,配置支持 UEFI 的 GRUB。
如果您不小心错误地配置了 GRUB,可能导致您的系统完全无法使用,除非使用 CD-ROM 或可引导的 USB 存储器等备用引导设备。本节不是引导您的 LFS 系统的唯一方案,您可能只要修改现有的启动加载器 (如 Grub-Legacy、GRUB2 或 LILO) 配置即可引导 LFS。
您务必保证自己拥有一个紧急引导磁盘,它在计算机不可用 (无法引导) 时能够 “抢修”
计算机。如果您现在还没有引导设备,您可以执行以下命令创建一个。在运行下列命令前,您需要跳到 BLFS,安装包含
xorriso
的
libisoburn 软件包:
cd /tmp grub-mkrescue --output=grub-img.iso xorriso -as cdrecord -v dev=/dev/cdrw blank=as_needed grub-img.iso
GRUB 使用一种独特的命名结构,为驱动器和分区命名。分区名的形式为 (hdn,m),这里 n 是硬盘驱动器编号,m 是分区编号。硬盘驱动器编号从 0 开始,但分区号对于主分区来说从 1 开始
(对于扩展分区来说从 5 开始)。例如,分区 sda1
在 GRUB
中的名字是 (hd0,1),而 sdb3
的名字是 (hd1,3)。和 Linux 不同,GRUB 不认为 CD-ROM
驱动器属于硬盘驱动器。例如,如果在 hdb
上有一个 CD-ROM
驱动器,而 hdc
上有第二个硬盘驱动器,则第二个硬盘驱动器仍然名为
hd1。
GRUB 的工作方式是,将数据写入硬盘的第一个物理磁道。这里不属于任何文件系统,在启动时,第一个物理磁道中的程序从引导分区加载 GRUB 模块,默认在 /boot/grub 中查找模块。
引导分区的位置由负责进行配置的用户自己决定,作者推荐创建一个小的 (建议大小为 200 MB) 分区,专门存放引导信息。这样,不同的
Linux 系统 (无论是 LFS 还是商业发行版)
在启动时和启动后都能访问相同的引导文件。如果您选择这样做,您需要挂载这个单独的分区,将 /boot
中已有的文件 (例如上一节中构建的 Linux 内核)
移动到新的分区中。之后,解除该分区的挂载,并将它挂载为 /boot
。另外,还要注意更新 /etc/fstab
。
直接将 /boot
目录保留在 LFS
分区也是可以的,但这样在配置多系统启动时比较麻烦。
根据以上信息,确定 LFS 根分区 (或 boot 分区,如果使用了独立的 boot 分区) 的名称。下面假设 LFS 根分区 (或
boot 分区) 是 sda2
。
将 GRUB 文件安装到 /boot/grub
并设定引导磁道:
以下命令会覆盖当前启动引导器,如果这不是您希望的,不要运行该命令。例如,如果您使用第三方启动引导器管理主引导记录 (MBR)。
grub-install /dev/sda
如果系统是使用 UEFI 引导的,grub-install 会试图为 x86_64-efi 目标安装文件,但它们并未在第 8 章中安装。如果出现了这类问题,请在以上命令中添加
--target i386-pc
选项。
生成 /boot/grub/grub.cfg
:
cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod part_gpt
insmod ext2
set root=(hd0,2)
menuentry "GNU/Linux, Linux 6.4.12-lfs-12.0-systemd" {
linux /boot/vmlinuz-6.4.12-lfs-12.0-systemd root=/dev/sda2 ro
}
EOF
insmod 命令加载
GRUB 模块 part_gpt
and ext2
。ext2
模块尽管如此命名,实际上却支持 ext2
,ext3
,以及 ext4
文件系统。grub-install
命令已经将一些模块嵌入 GRUB 主映像 (它安装在 MBR 或
GRUB BIOS 分区中),以便在访问其他模块 (这些模块在 /boot/grub/i386-pc
中)
时避免“先有鸡还是先有蛋”的问题。因此,在典型的系统配置中,这两个模块已经被嵌入主映像,此时这两条 insmod
命令不会产生任何效果。但是无论如何它们不会造成损害,而且在一些少见的系统配置中它们可能是必要的。
从 GRUB的视角来看,内核文件的位置相对于它使用的分区。如果您使用了单独的 /boot 分区,需要从上面的 linux 行删除 /boot,然后修改 set root 行,指向 /boot 分区。
如果新增或移除了一些存储设备 (包括 USB 闪存盘等可移动存储设备),则 GRUB
赋予分区的编号可能发生改变。这可能导致引导失败,因为 grub.cfg
仍然在使用“旧的”编号。如果希望避免这种问题,可以使用分区和文件系统的 UUID 指定分区,以代替
GRUB 编号。运行 lsblk -o
UUID,PARTUUID,PATH,MOUNTPOINT 以显示文件系统 (在
UUID
列) 和分区 (在 PARTUUID
列) 的 UUID。之后将 set
root=(hdx,y)
替换为 search --set=root
--fs-uuid
,并将 <内核所在文件系统的
UUID>
root=/dev/sda2
替换为 root=PARTUUID=
。
<构建 LFS
使用的分区的 UUID>
注意分区的 UUID 和该分区中文件系统的 UUID 是完全不同的。一些在线资料可能建议使用 root=UUID=
代替<文件系统
UUID>
root=PARTUUID=
,但是这种方法依赖于 initramfs,而 initramfs 超出了
LFS 的范畴。
<分区
UUID>
/dev
中分区对应的设备节点名也可能发生改变 (和 GRUB
分区编号的变化相比较为少见)。在 /etc/fstab
中,也可以将
/dev/sda1
这样的设备节点路径改为 PARTUUID=
,从而避免设备节点命名发生改变时可能导致的引导失败。
<分区
UUID>
GRUB 是一个很强大的程序,它提供了非常多的选项,可以支持多种设备、操作系统和分区类型,还有很多用于定制启动屏幕、声音、鼠标输入等的选项。这些选项的细节超过了本书的范围,不予讨论。
有一个命令 grub-mkconfig 被用于自动创建配置文件。它使用 /etc/grub.d 中的脚本创建新配置文件,这会覆盖您手动编写的 grub.cfg。这些脚本主要是为非源代码发行版设计的,在 LFS 中不推荐使用。但是,如果您安装了商业发行版,它很可能在发行版中被运行,记得备份 grub.cfg 以防它被覆盖。