本文转自:http://linux.chinaunix.net/ebook/doc/2009/04/02/1095757.shtml

  GNU/Linux开源,这个意义实在是非常的广泛,目前在distrowatch上表现活跃的300个发行版代表了GNU/Linux的主流,然而细心的Linux爱好者会发现CentOS-based distribution designed based on Slackware Linuxa distribution built from source software packages for Red Hat Enterprise Linuxa user-friendly Ubuntu-based distributionan Debian-based distribution等关键词汇,目前大多数的发行版基本上都是源于RedhatDebian/UbuntuSuseSlackware等版本的衍生态,而构建Based Distribution的目的有很多,不乏有技术交流、功能完善、以及管理、更新Bug软件包等需求,同样这些Based Distribution也为Linux爱好者构建自己的Linux发行版本提供了很好的参照。本文作为独辟蹊径的系列文章,将带领大家初探基于Cenotos 5.2Linux发行版构建方式,为进一步深入研究提供一个基础。
  要实现基于CentosLinux发行版本的构建,首先需要了解一下Linux启动过程以及Linux启动文件相关的了解,同时要对Linux发行版本的光盘结构以及软件包的结构进行了解分析。从主机加电到系统服务加载运行,Linux的启动(Linux安装的过程雷同)大致需要经历如下的过程:

第一阶段:
加载bios的硬件信息,并获取第一个启动的设备的代号;读取第一个启动设备的mbr的引导加载程序(lilogrub)的启动信息;加载核心操作系统的核心信息,核心开始解压缩,并且尝试驱动所有硬件设备;
 
分析此阶段是很有价值的,即便是 Linux 系统的安装也需要加载内核并解压内核、加载各类外设的驱动信息,构建一个最小化的 Linux 的文件系统以执行第二阶段的进程。
第二阶段:
核心执行init程序并获取运行信息;init执行/etc/rc.d/rc.sysinit文件;启动核心的外挂模块(/etc/modprobe.conf)init执行运行的各个批处理文件(Scripts);init执行/etc/rc.d/rc.local文件;执行/bin/login程序,等待用户登陆;登陆之后开始以shell控制主机。
 
  通俗的一个说法, Linux 的光盘安装就是在第一阶段由 stage2.img 构建产生的最小化的 Linux 文件系统之上运行 anaconda 之类的安装程序,完成 Linux 系统的安装过程。在 Linux 安装过程中第二阶段就是运行 anaconda 并配合系统安装预设选项完成对系统安装。
  构建 Base Centos Distribution Linux 发行版可以简单分为两种方式,第一种是通过结合 Kickstart 安装预配置文件对 Centos 系统安装的软件包并结合 Kickstart post pre 的脚本对安装的系统进行初始化的配置;第二种方式是通过添加修改 stage2.img 所生成的 Linux 文件系统达到定制内核、在安装过程添加定义的向导信息等。第一种方式实现便捷、 Kickstart X 界面工具操作也相对简单,如要略去光盘中不安装不需要的软件包,并添加第三方的 rpm 或者 tar.gz 源码包,就需要深入研究 repodata 中的 comps.xml 的基于 yum 的软件包依赖关系的定义,并能够有基本的 shell 脚本的累加能力,将要安装的软件包及设置通过脚本实现。相对第二种方式的不足之处就是还是使用 Centos 的系统并没有对内核或其他参数做明确的发布调整,故此第二种方式就深入修改 stage2.img anaconda 相关的配置实现,以达到发布独立有别于 Base Centos Distribution Linux 版本。
  基于 Cenotos Linux 发行版的目的是为了在系统中能够快速,正确地建立 Linux 系统环境。实现的方式以分析 Centos 的安装光盘为起点,在掌握对应的技巧方法,同时建立相应的测试环境。
   centos 5.2 DVD 介质为例,光盘中包含的主要与定制相关的目录如下:

isolinux目录存放光盘启动时的安装界面信息

repodata目录是与RPM包安装相关的依赖信息

p_w_picpaths目录包括了必要启动映像文件

CentOS目录存放安装软件包信息

.discinfo文件是安装介质的识别信息,此文件不可缺少。

  下面将重点剖析一下 p_w_picpaths isolinux 的目录中的文件及其作用,相对 Centos repodata 的目录在深度定制时的意义要大得多。
p_w_picpaths 文件夹包含了引导启动的映像文件,主要的为 boot.iso 文件其中包含信息如下:
|----vmlinuz Linux内核
|----ldlinux.sys 引导Linux的系统文件
|----syslinux.cfg Linux内核引导参数配置文件
|----initrd.img 内存虚拟文件系统映像文件
|----*.msg文件 引导时的各种提示信息文件
其中,initrd.imgLinux ext2文件系统,构成如下:

initrd.img
|----/bin
|----/dev
|----/etc
|----/module
|----/sbin ------ loader
安装程序装载器
|----/tmp
|----/var
可执行文件/sbin/loader的任务是判断安装介质的有效性,并从中执行安装程序。
 
  在系统启动时被执行后在内存建立起了 Linux 内核 , 并根据配置文件 syslinux.cfg 装载虚拟文件系统,形成了完整的 Linux 系统,为后续的工作提供了必要的操作系统环境。可以通过如下命令查看 boot.iso 中的文件:
#mount -o loop boot.iso /mnt
#cd /mnt
## tree
.
|-- TRANS.TBL
`-- isolinux
|-- TRANS.TBL
|-- boot.cat
|-- boot.msg
|-- general.msg
|-- initrd.img
|-- isolinux.bin
|-- isolinux.cfg
|-- memtest
|-- options.msg
|-- param.msg
|-- rescue.msg
|-- splash.lss
`-- vmlinuz
 
p_w_picpaths 文件夹的 stage2.img 是当安装介质为 CD-ROM 时的安装程序映像文件。
这里主要讨论stage2.img的内容
stage2.img        
  |----/etc
        |----/modules
        |----/proc
        |----/usr----/bin----anaconda        
安装程序主执行文件
        |
        |------/lib-----/anaconda               
安装程序脚本文件目录
     |          |----/installclasses        
        |          |----/iw
        |          |----/texttw               
         |          |----*.py
        |
        |------/share---/anaconda               
安装程序资源文件目录
         |         |----/help
        |                   |----/pixmaps

安装引导图形资源目录,包括安装过程中使用到的所有位图,图标,可以通过GMIP等工具修改
 
   stage2.img 映像文件中的主要部分是安装程序 anaconda ,它的主执行体是 /usr/bin 下的 anaconda ,由其调用的大量例程分布在 /usr/lib/anaconda 下,而安装过程中要用到的资源文件分布在 /usr/share/anaconda 下。可以通过执行如下命令具体查看 stage2.img 中的内容:
#mount -o loop -t squashfs stage2.img /mnt
#cd /mnt
#ls
etc lib modules proc usr var
 
顺带说一下 anaconda 安装程序,主要用 Python 语言写成,它是一种解释性的,面向对象的脚本语言,在其源码目录中有很多 py 的文件就是。要全面完成基于 Centos Linux 发行版,使用和学习 shell Python 是很有必要的, :-D
 


图:基于CentosLinux发行版构建流程
  通过上面的内容分析,接下俩具体定制一个基于CentosLinux发行版本的实践过程,并通过脚本安装open***
一、导入Centos yum源的验证密码信息,并安装必要的软件包

#rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*
#yum -y install anaconda anaconda-runtime
#yum -y install createrepo
 
二、将 Centos DVD 光盘镜像文件复制到硬盘 Centos5 制作目录中
#mkdir /CentOS5
#mount -o loop /home/CentOS-5.2-i386-bin-DVD.iso /mnt
#cp -ar /mnt/* . 操作结束需要检查.discinfo是否复制
#tar -cf - .|(cd /CentOS5; tar -xvpf -)
 
三、依据完整的安装日志 /root/install.log 记录的软件包信息,结合 shell 脚本将 rpm 软件包复制到构建目录 CentOS 中,通过 createrepo 生成 comps.xml
根据目标主机的 install.log 文件生成 package.list 软件包清单
#cat install.log | grep Installing | sed 's/Installing //g' > packages.list
 
建立 RPM 目录,临时存放复制需要 rpm 软件包,
#mkdir /RPM
 
cprpm.sh 脚本清单
cat cprpm.sh

#!/bin/bash
DEBUG=0
DVD_CD=/mnt
ALL_RPMS_DIR=/mnt/CentOS
DVD_RPMS_DIR=/RPM
packages_list=/root/packages.list
number_of_packages=`cat $packages_list | wc -l`
i=1
while [ $i -le $number_of_packages ] ; do
line=`head -n $i $packages_list | tail -n -1`
name=`echo $line | awk '{print $1}'`
version=`echo $line | awk '{print $3}' | cut -f 2 -d :`
if [ $DEBUG -eq "1" ] ; then
echo $i: $line
echo $name
echo $version
fi
if [ $DEBUG -eq "1" ] ; then
ls $ALL_RPMS_DIR/$name-$version*
if [ $? -ne 0 ] ; then
echo "cp $ALL_RPMS_DIR/$name-$version* "
fi
else
echo "cp $ALL_RPMS_DIR/$name-$version* $DVD_RPMS_DIR/"
cp $ALL_RPMS_DIR/$name-$version* $DVD_RPMS_DIR/
# in case the copy failed
if [ $? -ne 0 ] ; then
echo "cp $ALL_RPMS_DIR/$name-$version* "
cp $ALL_RPMS_DIR/$name* $DVD_RPMS_DIR/
fi
fi
i=`expr $i + 1`
done

 
执行脚本将目标系统必要的 rpm 复制到 /Centos5/CentOS 目录
#rm -rf /CentOS5/CentOS
#cp -a /myRPM/* /CentOS5/CentOS
 
返回到 /CentOS5 目录下,执行 createrepo 程序生成 repodata 下的 comps.xml 文件
#cd /CentOS5
#createrepo -g repodata/comps.xml .
 
四、使用 Kickstart ,创建一个包含自动应答信息的典型的安装配置脚本。结合使用 Kickstart 文件中的 %post 安装后的脚本,可以通过默认的 shell 脚本语法实现文件的下载、软件包的编译等工作,进一步达到发布定制的需求。
建立 Kickstart 文件并命名为 ks1483.cfg
# Kickstart file automatically generated by anaconda.

install
cdrom
lang en_US.UTF-8
keyboard us
network --device eth0 --bootproto static --ip 172.16.1.148 --netmask 255.255.0.0 --gateway 172.16.1.9 --nameserver 172.16.1.9 --hostname trs.lvs.local
reboot
rootpw --iscrypted $1$t5sWRB7u$MJAcDD0IBMivcTMP65YBC.
firewall --enabled --port=22:tcp
authconfig --enableshadow --enablemd5
selinux --enforcing
timezone --utc Asia/Shanghai
bootloader --location=mbr --driveorder=sda
# The following is the partition information you requested
# Note that any partitions you deleted are not expressed
# here so unless you clear all partitions first, this is
# not guaranteed to work
zerombr yes
clearpart --all --drives=sda
part /boot --fstype ext3 --size=100 --ondisk=sda
part pv.2 --size=0 --grow --ondisk=sda
volgroup VolGroup00 --pesize=32768 pv.2
logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=1000 --grow --maxsize=1984
logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow

%packages
@editors
@text-internet
@core
@base
@development-libs
@development-tools
device-mapper-multipath
-sysreport
%post
mount /dev/cdrom /mnt
cp -rf /mnt/lvsheat /usr/local/src
cd /usr/local/src/lvsheat
tar zxvf lzo-2.03.tar.gz -C /usr/src
cd /usr/src/lzo-2.03
./configure && make && make install
cd -
tar zxvf open***-2.0.9.tar.gz -C /usr/src
cd /usr/src/open***-2.0.9
./configure && make && make install
 
将光盘中的 lvsheat 目录中的 open*** 编译需要的软件包通过脚本复制到系统的 /usr/local/src/lvsheat 目录并解压编译对应的源码包,完成对 open*** 的编译安装操作。
ks1483.cfg 添加进入到 isolinux.cfg ,已实现定制的 Kickstart 脚本能够被正确的执行。
cat isolinux.cfg
default auto
prompt 1
timeout 600
display boot.msg
F1 boot.msg
F2 options.msg
F3 general.msg
F4 param.msg
F5 rescue.msg
label linux
kernel vmlinuz
append initrd=initrd.img
label text
kernel vmlinuz
append initrd=initrd.img text
label auto
kernel vmlinuz
append ks=cdrom:/isolinux/ks1483.cfg initrd=initrd.img
label ks
kernel vmlinuz
append ks initrd=initrd.img
label local
localboot 1
label memtest86
kernel memtest
append -
 
五、制作生成 ISO 文件
#cd /CentOS5/
#mkisofs -R -J -T -r -l -d -allow-multidot -allow-leading-dots -no-bak -o ../home/CentOS.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table .
 

扩展方式:
1 、关于修改 anaconda 中的资源如定义安装界面的方式
安装 yum install squashfs-tools
anaconda资源修改:
加载anaconda文件
#mkdir /mnt/anaconda
#mount -o loop -t squashfs stage2.img /mnt/anaconda
然后进入到/mnt/anaconda中修改定制具体的文件。
打包anaconda文件
#mkfs.cramfs /mnt/anaconda stage2.img
或者执行
#mksquashfs /mnt/anaconda /tmp/stage2.img.new -all-root -no-fragments


图:简单定制的安装过程背景图
2、定制开机启动界面方式
启动画面用的是一种比较奇怪的格式lss16,它限制图片使用16种颜色,除去前景和背景色只能有14种颜色。我们需要ppmtolss16 giftopnm等程序,系统一般默认都安装了。
一般用gimp生成一个index模式的gif图形,颜色限制为14, 然后通过如下的办法进行转:
安装yum -y install syslinux
giftopnm < splash.gif | ppmtolss16 > splash.lss
如果要编辑一个lss文件先用lsstoppm转成ppm格式,然后用gimp进行编辑.
另外你还需要修改isolinux/boot.msg文件如下

^L
^Xsplash.lss

-  Babel Com Australia Fedora Core Linux installer.

-  Use the function keys listed below for more information.

^O02[F1-Main] [F2-Options] [F3-General] [F4-Kernel] [F5-Rescue]^O07

 


图:简单修改的开机启动画面
六、测试制作的安装光盘,通VMwareXENVirtualBox虚拟机测试如果没有出现问题,在PC上就可以顺利的安装。


图:安装后的目录信息
后记:本文讨论的是一个实现Base Centos Linux发行版的实现方法,同时再次提醒奔放是基于Centos 5.2的实现方式。也欢迎爱好Linux发行版实现探究的朋友一起来交流。
作者简介:CU网友kns1024wh,目前从事Linux群集方面的具体工作,之前做过多年的IT技术支持、MCT讲师、及REDFLAG的技术合作,技术专长群集、unix主机、AD部署等,您可以通过电子邮件lvsheat@qq.com或者Chinaunix社区与他取得联系。