最近在搞LFS,就是通过自己动手,亲自编译源代码的方式,建立自己的linux发行版。通过这个过程可以详细的深入了解linux内部的工作方式,对理解操作系统的机制有很大的帮助。
做这个项目,光是建立合适的宿主系统环境就是花了一个星期,因为LFS也不是从无到有直接凭空构造出来的,需要一个宿主操作系统。搞了一个星期,用过ubuntu做个宿主系统,后来换了kali linux,还是跌在了第一步上,只是编译通过了binutils,但是编译gcc怎么都同不过。后来,终于过了这一关。原来是宿主系统的gcc版本太高了。我换成了gcc-4.4就没问题了,之后的工作主要就是编译、安装,不断的重复。
按照LFS手册做好之后,主要的工作就是设法启动起来。因为我是用loop文件来模拟一个分区做的,所以我将其复制到优盘上,想从优盘启动。于是,我想法现将grub写入优盘。没有分分区的优盘貌似难以写入,于是我用fdisk分了一个区:
fdisk /dev/sdb
n :命令n建立一个新的分区,然后一直回车下去就可以了
a :命令a将第一个分区设为可启动的
w:将新的分区信息写入设备
mkfs -t ext4 /dev/sdb1
将sdb1分区格式化为ext4文件系统,然后才可以i将此分区挂载使用。不分区的话会出现一下错误信息:
/usr/sbin/grub2-bios-setup: warning: this GPT partition label contains no BIOS Boot Partition; embedding won't be possible.
/usr/sbin/grub2-bios-setup: warning: 无法嵌入。在此次安装中 GRUB 只能通过使用块列表安装。但是块列表是不可信赖的,不推荐使用。.
/usr/sbin/grub2-bios-setup:错误: will not proceed with blocklists.
将grub写入优盘的方法:
mount /dev/sdb1 /media/disk 将sdb1分区挂载到/media/disk 目录
grub-install --root-directory=/media/disk --no-floppy /dev/sdb --force
--root-directory=/media/disk 选项指定将grub的配置文件信息生成到/media/disk目录下
/dev/sdb 指定将启动程序写入到/dev/sdb的mbr中
grub2-mkconfig -o /media/disk /boot/grub/grub.cfg
此命令将自动扫描系统中的分区,检查各个分区中是否安装有系统,然后根据检测到的信息生成或者更新grub的配置文件grub.cfg。具体而言,就是生成开机时由grub引导程序显示的选项。
然后,使用一下命令将由LFS生产的所有目录文件复制到sdb1分区中:
cp -rf /mnt/lfs* /media/disk
一定要使用-f选项,强制复制所有文件,否则有一些特殊文件无法复制。
然后更改优盘上的grub.cfg文件(/media/disk/boot/grub/grub.cfg),将和lfs有关的启动项信息的根分区修正,因为我们是在宿主系统中检查并更新的grub.cfg文件的,这种情况下是将硬盘识别为hd0,而优盘识别为hd1的,但是如果从优盘启动的话,就反过来了,这时优盘是hd0,硬盘是hd1.所以我们手动修正gurb.cfg:
menuentry "unknown Linux distribution (on /dev/sdb1)" --class gnu-linux --class gnu --class os {
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)' #之前是set root='(hd1,msdos1)'
search --no-floppy --fs-uuid --set=root 7972d858-eb3f-49b4-8f90-6805a8661946
linux /boot/vmlinuz-3.16.2-lfs-7.6 root=/dev/sdb1 #这里一定要对,不管宿主系统中的优盘分区被标识成什么,比如/dev/sdb /dev/sdc,这里都要写/dev/sdb1。这样才能正确的加载根文件系统。
initrd /boot/initrd.img-3.14-kali1-686-pae #下面将对此进行详细介绍
}
上面的:initrd /boot/initrd.img-3.14-kali1-686-pae 这一行是我们手动加载的,原生的LFS制作出来是没有考虑这个的。但我们要从优盘启动,就要使用这种技术--initrd,即init ram disk。如果从硬盘分区启动,这个就没必要了。因为我们要从优盘启动,所以需要虚拟内存磁盘,用于系统启动时作为临时的根文件系统,否则无法加载根文件系统,因为这种情况下我们是将优盘这种介质作为根文件系统介质的,但是系统启动时,还未加载优盘的驱动程序,这就导致系统无法识别优盘,也就无法加载根文件系统。所以我们用到了initrd。具体的initrd的详细介绍请自行百度。我们这里使用的initrd.img-3.14-kali1-686-pae文件是从宿主系统中的/boot目录下直接复制过来的,嗯,版本差距不大,实践证明可以直接正确的使用。
注意,LFS根文件系统中的/etc/inittab和/etc/fstab内容要正确,尤其是/etc/fstab文件中要正确的指定根文件系统(/dev/sdb)
好了,准备好之后就可以重启从优盘启动了。
利用次方法,我还将优盘分了两个区,将LFS装载在了第二个分区,修改了grub的配置文件,指定了正确的根文件系统,成功启动。
因为我的宿主系统还配置了6G的交换分区,所以我将这个分区重新格式化为ext4文件系统并将其设置为可启动的活动分区,将LFS复制到了次分区之下,更新grub配置文件,这种情况只需要指定正确的根文件系统就可以了。
通过这个过程,我也深刻的理解了linux命令行工作方式的强大。