配置引导
5.2.1 创建/etc/fstab 文件
/etc/fstab 文件的作用是让其他程序确定存储设备的默认挂载点、挂载参数和检查信息(例如完整性检测)。 以下是笔者的 fstab 文件为例讲解,请根据自己的分区情况进行更改。一个取巧的方法是参考宿主机中的 fstab 文件,进行更改。
cat > /etc/fstab << "EOF"
# Begin /etc/fstab
# file system mount-point type options dump fsck
# order
/dev/sda5 / ext4 defaults 1 1
/dev/sda1 /boot ext2 defaults 0 2
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs defaults 0 0
devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
# End /etc/fstab
EOF
其中的 sda1、sda5 和 ext2、ext4 请使用适当的值替换。关于文件中 6 个字段的含义,请查看 man 5 fstab1 。
基于 MS-DOS 或者是来源于 Windows 的文件系统(例如:vfat,ntfs,smbfs,cifs,iso9660,udf)需要在挂载选项中添加 iocharset,才能让非 ASCII 字符的文件名正确解析。此选项的值应该与语言区域设置的值相同,以便让内核能正确处理。此选项在相关字符集定义已为内核内建或编译为模块时生效(在文件系统→本地语言支持中查看)。此外,vfat 和 smbfs 还需启用 codepage,同样也是为了解决文字的正常显示问题。例如,想要挂载 USB 闪存设备,zh-CN.GBK 用户需要在/etc/fstab 中添加以下挂载选项:
noauto,user,quiet,showexec,iocharset=gbk,codepage=936
对于 zh_CN.UTF-8 用户的对应选项是:
noauto,user,quiet,showexec,iocharset=utf8,codepage=936
需要注意的是,iocharset 默认值是 iso8859-1(其保证文件系统大小写敏感),而 utf8 这个参数告知内核使用 UTF-8 转换文件名,以便可以在 UTF-8 语言环境中解释它们。 此外,还有可能在内核的配置过程中就指定一些文件系统的默认 codepage 和 iocharset 值。相关参数有“默认 NLS 选项”(CONFIG_NLS_DEFAULT),“默认远程 NLS 选项”(CONFIG_SMB_NLS_DEFAULT),“FAT 默认代码页”(CONFIG_FAT_DEFAULT_CODEPAGE),和“FAT 默认 IO 字符集”(CONFIG_FAT_DEFAULT_IOCHARSET)。不过,无法在内核编译阶段指定 ntfs 文件系统的设置。 另外,一些硬盘类型在遇到电源故障时,假如在/etc/fstab 中使用 barrier=1 这个挂载选项,则会让 ext3 文件系统的数据更加安全。如需检查磁盘是否支持此选项,请运行 hdparm。例如:
hdparm -I /dev/sda | grep NCQ
如果有输出内容,则代表选项可用。
注意:基于逻辑卷管理(LVM)的分区不可使用 barrier 选项。
5.2.2 使用 GRUB 设置启动过程
这一步可以算是临门一脚,也是最容易功亏一篑的一步,因为这步配置问题会直接导致系统无法启动。这也是为什么笔者非常推荐使用虚拟机来完成构建的原因。如果是实机环境,就不得不面临使用 CD 或者 USB 来救场的情况。不过需要明确的是这一步出错绝没有严重到需要推倒重来的地步,出现无法引导的情况只需要通过 USB 等的方法挂载分区,重新配置 Grub 即可。
GRUB 对于硬盘和分区,自身有一套命名规则 (hdn,m),其中 n 是硬盘数,m 是分区号。硬盘数 N 从 0 开始计数,分区数需要区别对待——主分区从 1 开始计数而扩展分区从 5 开始计数。需要注意的是,和早期版本相比,计数方式有所变化。例如,分区 sda1 是 (hd0,1),sdb3 是 (hd1,3)。Linux 下,并不将 CD-ROM 设备假想为硬盘。例如,就算已有 CD 设备挂载为 hdb,第二块硬盘挂载为 hdc,Grub 依旧将第二块硬盘称为 (hd1)。
GRUB 会将一些数据写入硬盘的第一个物理扇区。这一部分不属于任何一个操作系统,在启动时,该部分数据激活,然后寻找 Grub 的模块,GRUB 模块的默认位置为/boot/grub/。
引导分区的位置会影响配置和使用。
一种建议是使用一个独立的小分区(建议大小 100MB)专用于存放引导信息,则每一个发行版,不论是 LFS 还是其他的商业发行版都能访问相同的引导文件,而且任何已经启动的系统都能访问该分区中的内容。如果你选择这么做,你需要挂载这个独立分区,移动所有的文件从当前的/boot 目录(比如说你上一节刚编译的 Linux 内核)到新的分区。你然后要卸载这个新分区,重新挂载它为/boot。如果你这么做,一定要更新/etc/fstab。本书采用的就是这种方式 。 另一种则是直接使用当前的 lfs 分区,但这种方式在配置多系统启动的时候比较麻烦。
以上两种不同的方式需要注意的分区也不同,如果你使用单独的分区,需要知道引导分区的磁盘位置;如果使用当前的 lfs 分区,也需要明确当前分区的磁盘位置,以下假定根分区(或者是磁盘分区)是 sda2。
将 GRUB 文件安装到/boot/grub 然后设置引导扇区:
grub-install /dev/sda
如果系统是通过 UEFI 引导的,grub-install 将会尝试安装 x86_64-efi 的文件,但是这些文件并未在第 4 章中安装。所以在在这种情况下,请在上述命令后面追加--target i386-pc。 创建 GRUB 配置文件:
cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod ext2
set root=(hd0,1)
menuentry "GNU/Linux, Linux 5.2.8-lfs-9.0" {
linux /boot/vmlinuz-5.2.8-lfs-9.0 root=/dev/sda2 ro
}
EOF
请参照上述对于 Grub 的介绍,并根据自己的分区情况、是否使用 UEFI 等因素,修改自己的 grub.cfg 文件。
fsck 列的数值来决定需要检查的文件系统的检查顺序。允许的数字是 0, 1,和 2。根目录应当获得最高的优先权 1,其他所有需要被检查的设备设置为 2。0 表示设备不会被 fsck 所检查。