Username: Password:

Linux发行版制作指南(上)
来源: ChinaUnix博客  作者: ChinaUnix博客   发布时间:2008-04-24 06:49:04

Linux发行版制作指南
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               
  建立这种目录结构和相关文档的原因是在安装程式中已以代码的形式确定了他们的命名及结构。其中,对boot.img和stage2.img的相关修改如前所述,而涉及到对comps,hdlist,hdlist2的修改,则需在后续的裁剪过程中确定。
  至此,调试环境建立完毕。现在能够用做好的引导盘来引导系统,并且能够从指定的硬盘上测试安装程式和RPM包的正确性。


喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅