1.项目整体分析
制作Linux发布的目的是为了在系统中能够快速,正确地建立Linux系统环境。制作Linux发布的主要工作是决定各种软件的去留,因为有
了RPM(RedHat Package Manager)包对其提供优良的管理能力,所以以目前比较成熟的RedHat 7.1(Linux
Kernel Version
2.4.2-12)Linux发布程序作为蓝本,以RPM包作为基本的制定单元,以需求为原则对其进行取舍,得到适合实际需要的Linux系统。
由此,项目自然而然的以分析RedHat
Linux的光盘安装系统为起点,在掌握了其结构和行为的基础上,在包一级(结构部分)和代码一级(行为部分)进行修改,同时建立相应的测试环境,以便对
修改进行及时的规范。
2.项目分步骤实施细节
2.1对Linux光盘安装系统的分析
●结构部分
在安装光盘中,主要的目录结构和文件大致如下:
images/ 此目录下包含了制作启动盘的映像文件(文件后缀img),
其中boot.img是当安装介质为CD-ROM时负责引导系统的映像文件
bootnet.img是当安装介质为FTP,NFS等时负责引导系统的映像文件
driver.img是由一些特殊设备驱动程序模块组成的映像文件,在当前内核不支持这些设备的情况下,提供了对它们进行访问的一种方法
其中,boot.img映像文件中主要包含以下文件:
boot.img |----vmlinuz Linux内核 |----ldlinux.sys 引导Linux的系统文件 |----syslinux.cfg Linux内核引导参数配置文件 |----initrd.img 内存虚拟文件系统映像文件 |----*.msg文件 引导时的各种提示信息文件
|
其中,initrd.img为Linux ext2文件系统,构成如下:
initrd.img |----/bin |----/dev |----/etc |----/module |----/sbin ------ loader 安装程序装载器 |----/tmp |----/var
|
可执行文件/sbin/loader的任务是判断安装介质的有效性,并从中执行安装程序。
其实正是boot.img,在系统启动时被执行,经解析之后在内存建立起了Linux内核,并根据配置文件syslinux.cfg装载虚拟文
件系统,形成了完整的Linux
System,为后续的工作提供了必要的操作系统环境。Boot.img映像的文件系统类型为msdos,而其中的initrd.img映像的文件系统类
型必为Linux系统自己的ext2,所以对于它们的解析操作是不同的,具体请参考附录A 。
RedHat/ 此目录是RedHat Linux发布的核心目录,主要的目录结构都在这里,其中
RPMS/ 包含了RedHat
Linux发布的主要部分,即以RPM包的形式将Linux系统中的二进制可执行文件,配置文件,文档等等组织在一起,形成能完成一定功能的比较独立的软
件包(文件后缀rpm)。这个目录就是把这些软件包都集合在一起,形成了RedHat Linux发布。
base/
包含了在安装过程中要用到的描述组织结构和安装行为的所有文件,其中comps,hdlist和hdlist2是描述RPM包组织结构的文件。
comps
此文件把各个RPM包按一定的原则组织成若干组,即components,这样在安装过程中就不必对每一个包做出取舍,而以组为单位。comps文件为简
单文本格式,它的结构如下所示:
4 表示RPM包的版本号,当前为4
1 base { } base是此component名,{…}中是此component中所包含的RPM包 的名称列表,1表示在安装中默认为选中,即默认安装。
0 –hide IDS sensor{ snort libpcap } 表示IDS sensor组中包含有snort和lipcap这两个RPM包。0表示 这个组在安装中默认为不选中即默认不安装,并且由—hide指出 不在用户界面上显示此组。
|
hdlist和hdlist2
这两个文件维护从RPM包名到真实包文件名的映射过程,例如从snort这个RPM包名到真实包文件名snort-1.8.1-
1.1.2.i386.rpm的映射。这两个文件是用特殊的程序生成的,无法用简单的方法察看其中的内容和结构。具体的生成方法请参考附录D。
stage2.img , hdstg1.img , hdstg2.img , netstg1.img 和netstg2.img
是描述安装行为的映像文件,其中
stage2.img 是当安装介质为CD-ROM时的安装程序映像文件
hdstg1.img 是当安装介质为HardDisk时的安装程序映像文件
hdstg2.img 是当安装介质为HardDisk时的安装程序映像文件
netstg1.img 是当安装介质为FTP,NFS时的安装程序映像文件
netstg2.img 是当安装介质为FTP,NFS时的安装程序映像文件
这里主要讨论stage2.img的内容
stage2.img |----/etc |----/modules |----/proc |----/usr----/bin----anaconda 安装程序主执行文件 | |------/lib-----/anaconda 安装程序脚本文件目录 | |----/installclasses | |----/iw | |----/texttw | |----*.py | |------/share---/anaconda 安装程序资源文件目录 | |----/help | |----/pixmaps
|
如上所示,stage2.img映像文件中的主要部分是安装程序anaconda,它的主执行体是/usr/bin下的anaconda,由其
调用的大量例程分布在/usr/lib/anaconda下,而安装过程中要用到的资源文件分布在/usr/share/anaconda下。
stage2.img 的解析方法请参考附录B。
●行为部分
RedHat
7.1的安装程序被命名为anaconda。如前所述,当boot.img所代表的启动介质被系统引导之后,在内存中就建立了一个完整的Linux系统
(包括Linux内核和一个内存虚拟文件系统),之后便执行文件系统中存在的loader命令,从适当的介质中执行安装程序(例:安装介质是CD-
ROM,就解析CD-ROM上的stage2.img,并从中执行安装程序),即执行anaconda,完成Linux系统的安装任务。
此次利用RedHat
7.1的安装程序源代码的SRPM包形式:anaconda-7.1-5.src.rpm来获得anaconda的源程序,经解包后在/usr/src
/redhat/SOURCES/anaconda-7.1形成了源代码树。
anaconda-7.1 |-------------------/bootdisk 启动盘目录 |-------------------/docs 文档目录 |-------------------/help 安装过程帮助系统目录 |-------------------/installclasses 安装类型分类目录 |-------------------/iw 安装各步骤响应目录 |-------------------/loader 安装程序装载器目录 |-------------------/pixmap 图形资源目录 |-------------------/utils 工具目录 |-------------------*.py 各Python脚本文件
|
分析如下:
anaconda安装程序主要用Python语言写成,它是一种解释性的,面向对象的脚本语言。源文件后缀为.py,也可生成可执行的字节码,
后缀为.pyc或.pyo。其中:
installclasses/ 子目录中各文件定义了在安装过程中用户可选择的安装类型,通常由四个文件workstation.py ,
server.py ,
laptop.py和custom.py来描述workstation(工作站)安装类型,server(服务器)安装类型,laptop(膝上型电脑)
安装类型和custom(自定义)安装类型。每个脚本文件的内部,则是根据自己安装类型的特点对安装步骤,分区策略以及包的取舍做出了不同的方案。
iw/ 子目录中各文件定义了在图形界面安装状态时各步骤对Next(下一步)和Prev(上一步)的响应函数。
loader/ 安装程序装载器的源代码目录,用C语言写成。
pixmap/ 图形资源目录,包括安装过程中使用到的所有位图,图标。
utils/ 安装程序实用工具目录。
anaconda 是安装程序的主执行文件,它建立了Python语言的运行环境,提供了程序的入口点并以模块的方式将各个子系统结合在一起。
gui.py
定义了安装程序图形界面使用的各种窗口类,包括MessageWindow,ProgressWindow,WaitWindow,
ExeceptWindow等,和控制这些窗口及图形界面行为的InstallInterface, InstallControlWindow,
InstallControlState类。总之,控制gui。
todo.py 定义了安装程序的各种行为函数,它是图形界面背后真正进行各项操作的函数集合。
harddrive.py 定义了当安装介质为硬盘时,系统该如何找到安装程序的光盘映像,并从中执行程序。
安装程序源代码的编译由make和make install组成,完成后在/usr/src/RedHat目录下形成了如下目录结构:
instimage |------/etc |------/usr |------/bin |------/sbin |------/lib | |------/anaconda | | |------installclasses | | |------iw | | |------texttw | | |------*.py | | | |------/anaconda-runtime | |------/boot/loader | |------/share------/anaconda |------/help |------/pixmaps
|
此目录结构基本与stage2.img的文件结构相同。
2.2调试环境的建立:
●对源程序的修改
在分析完安装程序的基本构成之后,就要建立相应的调试环境。建立此环境的目的是为了可以方便地对修改过的安装程序及裁减后的RPM包进行随时的
确认。显然,可以选用CD-ROM或本地硬盘作为调试介质,下表比较了两者的差别:
|
CDROM |
硬盘 |
对应的安装界面 |
图形界面 |
菜单界面 |
对应的映像文件 |
stage2.img |
*.iso中的hdstg1.img , hdstg2.img |
优点 |
图形界面,直接使用映像文件stage2.img |
随改随调,调试周期短,效率高 |
缺点 |
每次改动都要求刻盘,调试效率低 |
菜单界面,每次调试都要求提供光盘映像文件*.iso,效率上打折扣 |
在两者各有优缺点的情况下,考虑折衷的方案,即为了首先保证调试的效率,采用硬盘作为调试介质,但对应的映像文件选取stage2.img,这
样能达到效率最大化,同时调试界面采取图形方式。采用此方案时,须修改源代码,以达到预期的效果。
从前面对安装系统的分析,可以看出在initrd.img中的/sbin/loader程序负责判断安装介质的有效性,并从中执行安装程序。所
以要首先修改它的源代码文件loader.c,从中找出硬盘安装时默认读出光盘映像文件*.iso的函数setupIsoImages,并注释掉其中在硬
盘目录中寻找映像文件*.iso的相关操作,具体对应Line 582 至
Line590行中包含sprintf和if(){}循环的语句,以避免打开子目录,并在其后加入mountLoopback
("/tmp/hdimage/RedHat/base/stage2.img","/mnt/runtime",
"loop0");一句以便实现直接使用stage2.img的目的,并注释掉其后从errno=0开始的代码,经过整个while循环到
closedir(dir),但保留umount(“/tmp/hdimage”);注释掉if(!net) return
NULL;一句。以上操作目的是防止程序读出光盘映像文件*.iso。在loader.c的主函数main()中的结尾部分,注释掉if
(!FL_TESTING(flags)) { 和
}的条件判断的两条语句,让程序毫无疑问地执行硬盘上的安装程序。至此,对loader.c修改完毕。
同时还要对Python脚本的一些相关文件进行修改以保证对stage2.img文件的支持。具体的,在harddrive.py的类
class HardDriveInstallMethod中,注释掉函数 mountMedia(self,
cdNum)中的所有内容并加Pass语句的方法使此函数失效,同样方法处理umountMedia函数,mountDirectory函数和
umountDirectory函数,为了保险起见,在其他函数中注释掉有关上面函数的调用。并在类的构造函数(初始化)中的# Go
ahead…语句之前加self.tree=”/tmp/hdimage/”语句,并注释掉后面的所有语句。这样做仍然是要保证废弃iso映像转而对
stage2.img实现控制。不仅如此,最好还注释掉todo.py中的Line1781至Line1783调用
self.method.systemMounted一段,以确保不出差错。接着进行make和make
install,重新编译程序,使修改生效,并把新的loader程序从编译的目标目录中copy到boot.img中initrd.img中的相应目录
并覆盖旧的loader文件。为了启动时的快速,修改boot.img中的syslinux.cfg文件,去掉启动提示,延时和其他Linux启动选项,
修改后的syslinux.cfg文件,请参考附录F
最后,把boot.img做成启动盘,方法请参考附录G。
●建立硬盘介质中的调试目录
在硬盘的Linux分区中建立形如RedHat安装光盘目录结构的调试目录及相关文件,如下所示:
|----/images
| |------boot.img | |----/RedHat |----/base | |------comps , hdlist , hdlist2,stage2.img | |----/RPMS | |----*.rpm
|