LFS编后感

来源:互联网 发布:穿越最后的幸存者知临 编辑:程序博客网 时间:2024/05/20 02:22
我已经使用Linux系列的系统一段时间了,一直以来都对它们中的软件包之间的依赖关系特别反感,有时候明明两个不相干的软件也能依赖得上,比如说NVIDIA的显卡驱程和内核文件竟然有关联,不能不装上NVIDIA的显卡驱程,但是我用的是ATI显卡!!

所以决定自己动手编译一个Linux ^_^。这次编译的过程主要是按照LFS-6.3所说的进行,并且是在SUSE10.3下进行的,不是使用光盘启动再编译。但是软件的版本号并不是完全完全按照它所说的。比如编译环境要求的宿主的gcc版本,LFS-6.3并没有测试到,还有,宿主上面的软件的版本号往往比LFS-6.3里面所提到的编译环境的高,并且高得LFS-6.3上面明确说明是没有测试过的。但是这并不妨碍我继续组装LFS。

而且,对于LFS-6.3上面提到的一些软件,我都是编译它的最新版本,而非它提到的版本,当然,这些版本它也没有测试过,并且不保证一定成功。但是,我并不是所有的软件都选用最新版本。一些我认为比较重要的,比如编译器,glibc,sysvinit,grub等就严格按照LFS-6.3上面的版本号进行编译了。因为我觉得这些软件直接关系到整个系统的编译和运行过程,不容差错。以下是选用了最新版本号的软件:
autoconf-2.62
automake-1.10.1
bzip2-1.0.5
e2fsprogs-1.40.8
findutils-4.4.0
gawk-3.1.6
gettext-0.17
iana-etc-2.30
iproute2-2.6.25
less-418
libtool-2.2.2
linux-2.6.25
m4-1.4.11
man-db-2.5.1
man-pages-2.79
tar-1.20
tcl8.4.19

编译过程都是按照LFS-6.3上面所述的进行,在这里就不累赘了。一般情况下,按照它进行编译不会有太大的问题。有一些软件在编译过程中会有make check或者make test进行测试,有些时候会有个别的cases是通不过测试的,比如e2fsprogs这个软件我在编译后通不过所有的测试,但我还是安装它。希望以后不会真的出现问题了。

我觉得比较奇怪的是,它的第一遍编译主要是建立一个编译环境来进行第二遍的编译,第二遍的编译才是真正的编译一个Linux系统。但是为什么不能使用宿主操作系统上面的编译环境呢?不知道,以后研究。

而且关于grub。由于我的宿主系统上面已经单独划分一个分区挂载/boot。并且grub已经安装到了这个分区上了,也已经可以从这个分区引导系统。因此,好像grub可以省吧,但我没有省,安装了但是省了一些配置的工作。

LFS-6.3是到最后才编译内核的。我直接使用当前系统内核的配置文件(/boot/config-X.X.X.-XXX)作为蓝本,再针对机器的一些具体情况进行修改(比如CPU啊,一些驱动啊等)。LFS-3.6上在安装了其中的模块之后,使用cp命令将非压缩的内核映像复制到/boot下,但是,这样做好像不成功。新系统引导到一半就无法继续下去,好像提示说无法找到root分区,并且要求我在引导前指定“root=”,问题是,这些都已经正确设置好了。我对比以下当前系统和新编译的LFS的/boot下面的内容。当前系统的内核映像是压缩了的,而且有一个initrd的文件。LFS系统的没有initrd文件。我猜想应该要为LFS系统添加一个initrd的文件。解决过程如下:

1. 在编译内核时候,不使用cp命令将内核映像复制到/boot下,而是使用make install进行安装,但是,它却提示说找不到LILO,只是将压缩了的内核映像和一个System.map文件添加到/boot下就退出了,于是这种方法行不通。

2. 上网查查initrd,它是一个使用了cpio再用gzip压缩过了的虚拟文件系统,它的目录结构和根目录的类似。实际上,它是在内核挂载根分区的时候,被解压装到内存中,作为一个根文件系统。内核会在这个根文件系统中进行挂载硬盘根分区的工作。就是说,在引导时,initrd会先被装载进内存,并且作为一个根文件系统,接着,内核才真正的挂载硬盘上面的根文件系统。虽然知道了它的功能,但是并不清楚它里面究竟放些什么内容。在网上往往很少有说。但是在当前系统就有一个现成的可以参考。

3. 先说一下如何如何对initrd进行打包和解包。解包的命令gzip -cd initrd | cpio -imd 即可以在当前目录下将initrd里面的内容解压出来。由于initrd是做成一个虚拟的根文件系统,因此最好把它解压到一个单独的目录中,如lfs-initrd。不要把解压后的文件与其它的文件混杂在一起,可以方便打包。打包的命令find . | cpio -H newc -o | gzip -9 -n > filename。这个命令是将当前目录下的所有文件进行打包,因此它应该在包含完整的虚拟文件系统目录树的目录下进行,如上述的lfs-initrd。

4 将当前系统的initrd文件解压后,会出现一些目录bin,lib,usr,var,tmp等,这些都是和根文件系统的目录树一样的。首先对照这个解压出来的目录树和lfs系统的根目录树,将lfs系统的文件替换相应的initrd里面的文件。比如将$LFS/bin/ls替换掉$INITRD/bin/ls。$INITRD是initrd解压的目录。最重要的是修改$INITRD/lib/module,将lfs相应的内核模块替换它,并且module下的文件夹名要和内核的版本号一致。最后再将$INITRD这个文件夹进行打包成一个initrd文件,但是用这种方法依然解决不了问题。在lfs系统引导时,依然要求提供root=命令。

5 由于当前系统下面的initrd包含很多的配置文件,因此,不再对当前的initrd进行最少修改。只修改$INITRD/lib/module下的内核模块。但是,问题依旧。

6 当前系统可以使用命令mkinitrd生成initrd文件,但是lfs系统没有安装,即使将mkinitrd及其相关文件复制到lfs系统的相应的位置,mkinitrd却不能正确使用,无法生成initrd,不是很清楚为什么。

7 最后一个方法,比较费时但是却行得通。首先在宿主系统上面编译内核,安装。保存下它的内核配置文件。在宿主系统中它会在/boot下生成一个initrd的文件。接着在lfs系统上面再次重新编译内核,在配置内核时候只要读入之前在宿主系统中保存的内核配置文件即可,而且也应该读入。这样在宿主系统和lfs系统中编译的内核它们都具有同样的配置。因此我猜想这种环境下生成的内核其相应的initrd文件也应该可以共用了(initrd中有一个/lib/modules目录,里面包含的就是内核模块,它们一定不能在不同内核中共享了)。实际上,这个initrd文件的确可以共享。我用宿主系统生成的initrd文件和lfs系统生成的内核映像来引导新系统成功。

注意在这里initrd是只initrd这一类的文件。请看/boot下面,initrd一般文件名后面会接着内核版本号。这里并不特指哪一个。lfs系统是只使用chroot命令将$LFS文件目录当成根目录之后的环境,而不是已经引导成功之后的lfs系统。
原创粉丝点击