构建LFS7.7过程的总结

目录
  1. 构建准备
  2. 构建工具链
  3. 构建LFS系统
  4. 让LFS系统可引导

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

Linux From Scratch旨在帮助用户更好得理解Linux如何正常运转,里面的程序如何协同工作以及程序之间如何相互依赖的。了解 Linux 系统如何工作的关键就是知道每个软件包的作用以及为什么你(或系统)需要它。本文总结了构建LFS 7.7-systemd的注意事项,而不是对构建过程中使用的命令进行记录。

构建准备

要进行LFS的构建,用户需要对Linux系统有一定的了解,不然会在构建过程中遇到各种各样的问题。
构建LFS 7.7-systemd的宿主系统需要满足一定需求,我构建的过程使用的宿主机是CentOS7(内核版本3.10.0-327.36.3)的VMware Workstation 12.0虚拟机,使用version-check.sh脚本检查后,建立了指向/usr/bin/bison的名为/usr/bin/yacc的软链接,其它工具基本满足构建所需。
在分区时,根据书中第二章的要求在虚拟机上添加了一个的硬盘,VMware虚拟机添加硬盘时默认为SCSI硬盘,根据第八章编译内核使用的默认选项和GRUB的配置,不能正常启动系统,主要的原因可能是内核编译参数的配置没有对或缺少某些主要驱动程序所导致的。后面再来看解决方法。
分区完成后,在新的分区创建了ext4类型的文件系统。然后挂载新分区,设置$LFS变量。然后根据第三章下载软件包和补丁。
第四章在宿主机添加了lfs普通用户以降低编译过程中可能导致的风险,对该用户的环境进行了设置,主要目的是设置该用户独有的环境变量,不使用宿主机原有的环境变量。

构建工具链

第五章构建了用于构建LFS系统使用的工具链。其中的Binutils和GCC都构建了两遍,这主要是为了解决循环依赖的问题:因为需要一个编译器来编译一个编译器。
构建过程的第一步是构建一个宿主系统无关的新工具链,它是通过先安装交叉编译的Binutils和GCC,使用它们编译glibc等库,然后第二遍编译Binutils和GCC,这次它们被链接到刚才编译好的glibc等库上。这样与宿主系统无关的新工具链就构建成功了。其中5.2节工具链技术备注解释了一些基本原理和技术细节,需要重点理解。
第二步使用这个第二遍编译好的工具链,构建其它剩下的基础工具。
第五章编译的工具都安装在$LFS/tools目录中,这些工具可以用来构建第六章的正式的LFS系统。

构建LFS系统

第六章的前几节目的是准备一个虚拟环境,这个环境通过执行chroot命令进入,从而可以方便地在宿主机和LFS虚拟chroot环境中进行切换。同时本章也介绍了各种不同的包管理器的实现。后面很大的篇幅是具体编译每个软件使用的命令和每个软件包包含的大概内容。最后本章介绍了如何剥离可执行程序中的调试符号,从而使可执行文件的大小减小很多。
第七章对系统进行了简单的配置,先是网络包括主机名,ip地址,主机名,DNS解析,hosts表等。之后介绍了系统设备的管理(由于这部分比较接近于硬件,我对于这部分的理解还很浅),配置了时间区域等内容,然后创建了/etc/inputrc和/etc/shells文件。

让LFS系统可引导

第八章首先创建了/etc/fstab文件,系统启动后会根据此文件的内容挂载根文件系统。然后就是编译内核和配置GRUB了。根据书中make defconfig命令创建了默认的.config文件,选择了书中建议的内核选项后,系统仍然无法启动,无法挂载根文件系统。
由于宿主机的内核可以正常启动虚拟机,所以该内核中包含的驱动可以识别虚拟机的SCSI硬盘,于是便想到直接使用宿主机的内核来启动系统。宿主机的/boot分区是独立的。此分区只包含内核及GRUB相关的文件,可以修改GRUB的配置,待内核启动完成后挂载LFS的分区即可,下面是操作过程:

1
2
3
4
5
6
[root@centos7 ~]# cd /boot/
[root@centos7 boot]# cp vmlinuz-3.10.0-327.36.3.el7.x86_64 vmlinuz-3.10.0-327.36.3.lfs-7.7-systemd.x86_64
[root@centos7 boot]# cp System.map-3.10.0-327.36.3.el7.x86_64 System.map-3.10.0-327.36.3.lfs-7.7-systemd.x86_64
[root@centos7 boot]# dracut -v --filesystems "ext4" initramfs-3.10.0-327.36.3.lfs-7.7-systemd.img 3.10.0-327.36.3.el7.x86_64
...
[root@centos7 boot]# cp /lib/modules/3.10.0-327.36.3.el7.x86_64/ /mnt/lfs/lib/modules/3.10.0-327.36.3.lfs-7.7-systemd.x86_64/

上面的第2、3行命令分别复制当前宿主机的内核和map文件,重命名用于我们的LFS系统;
第4行命令使用CentOS系统自带的dracut命令制作initramfs文件,在此文件中包含可以识别ext4文件系统的模块,以便能正确读出LFS硬盘分区上的文件。dracut命令的详细用法可以参考鸟哥的私房菜
第6行命令将与宿主机内核相关的模块也全部复制到LFS分区上。
最后是修改grub.cfg文件,来添加一个启动菜单选项,来使用刚才我们复制的内核文件及initramfs文件。详细的GRUB2的设定也参考鸟哥grub2设定,可以先使用grub2-mkconfig命令生成新的grub.cfg文件,然后修改包含刚才复制的内核文件名称的菜单项,最后的菜单项为:

1
2
3
4
5
6
7
8
9
10
menuentry 'LFS (3.10.0-327.36.3.el7.x86_64) 7.7-systemd' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-327.36.3.el7.x86_64-advanced-024f0010-39fa-472e-b2b0-fda255b4a8a3' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
linux16 /vmlinuz-3.10.0-327.36.3.lfs-7.7-systemd.x86_64 root=/dev/sdc1 ro
initrd16 /initramfs-3.10.0-327.36.3.lfs-7.7-systemd.img
}

另外,也可以按照LFS8.3.1的建议,可以拷贝主机系统的内核配置文件 .config(如果有的话)到解压后的 linux-3.19 目录下来跳过内核配置(使用make oldconfig命令),再编译内核。不过最后仍然需要制作initramfs文件来辅助启动。如何编译内核可以参考鸟哥核心编译一章。
最后,别忘记根据第九章的说明,配置/etc/os-release文件,缺少了该文件,系统仍然无法正常启动!经过以上操作后,LFS系统便可以通过与宿主机完全相同的内核来进行启动,不会出现无法识别硬盘,无法识别ext4分区的现象。