Duangw

livecd

前言

构建一张量身定做的Linux启动光盘,是我由来已久的想法。碰巧的是,本人使用的Linux发行版是Slackware,刚好有一个现成的livecd项目Slax,也是基于Slackware,所以我顺理成章的首先使用了Slax。

不过,对Slax大概使用后,觉得跟自己的要求还是有些差距。Slax是使用linux-live脚本制作的。经过对linux-live的一番了解,我决定也通过linux-live来构建自己的livecd。

宿主系统使用slackware 11.0,当然原则上并不局限于具体的Linux发行版。

索引:

  1. 相关资源
  2. 制作内核
  3. 定制linux-live
  4. 准备具体内容
  5. 制作ISO映像文件

1.相关资源

(1).linux-live

首先,从www.linux-live.org下载linux-live-5.5.0.tar.gz。

根据linux-live官方网页的说明,linux-live脚本还依赖于下面的一些工具。

官方原文是这样的:

At first, I need busybox with ASH shell to be able to execute my scripts from small initrd image. The most important software is unionFS. It allows me to make all img files "pseudo-writable". The CD is booting in non-emulation mode by using isolinux. MO files (aka modules) are created and compressed by using squashFS tools.

(2).busybox

www.busybox.netbusybox-1.2.2.tar.bz2。由于busybox不涉及内核,所以这次并没有更新该包。

(3).ASH

在宿主系统或将要安装的Slackware系统中确定安装了ash软件包。

(4).unionFS

www.unionfs.org下载unionfs-1.3.tar.gz。

(5).isolinux

网址是:http://syslinux.zytor.com/iso.php。在制作过程中,该部分没有修改,所以没有下载东西。

(6).squashFS

squashfs.sourceforge.net下载squashfs3.1-r2.tar.gz。

(7).Linux内核

内核版本需要2.6的,可以从www.kernel.org下载。但unionfs-1.3当时只支持到2.6.17,所以我直接使用了slackware11.0中的2.6.17.13。

 

2.制作内核

运行livecd要求的内核版本必须是2.6以上,首先在宿主机上制作一个满足要求的内核。

(1).内核源代码

安装slackware11.0自带的2.6.17.13内核,目录:

/usr/src/linux-2.6.17.13

其他相关软件包放在/sources目录下。

由于livecd会在不同硬件的机器上运行,所以,内核需要支持大多数的硬件环境。linux-live提供了一个内核配置文件configs/.config.kernel,以它为基础开始配置自己的内核是不错的主意。

除了支持通用的硬件,livecd还需要内核支持squashfs和unionfs,这是通过对内核打补丁实现的。

(2).unionfs

参考unionfs软件包中的安装说明INSTALL文件,对内核进行patch:

# cd /sources/unionfs-1.3
# ./patch-kernel.sh /usr/src/linux-2.6.17.13

(3).squashfs

参考squashfs软件包的安装说明INSTALL文件,对内核进行patch:

# cd /usr/src/linux-2.6.17.13
# patch -p1 < /sources/squashfs3.1-r2/\
linux-2.6.17/squashfs3.1-patch

(4).配置内核

使用linux-live提供了一个内核配置文件configs/.config.kernel:

# cd /usr/src/linux-2.6.17.13
# make mrproper
# cp /sources/linux-live-5.5.0/configs/.config.kernel .config
# make menuconfig

在文件系统的子菜单miscellaneous中确定加入了unionfs和squashfs支持。驱动程序方面基本沿用初始配置。其他方面依据自己需要定制。

在linux-live的DOC/requirements.txt文件中,对内核列出了一些必要条件,开始后面的工作之前,再复查一下比较稳妥。

(5).编译测试

编译内核:

# make

安装之前,先备份之前的2.6.17.13模块:

# cd /lib/modules/
# mv 2.6.17.13 2.6.17.13-slak

安装模块:

# cd /usr/src/linux-2.6.17.13
# make modules_install

测试新内核

# cp .config /boot/config-livecd-2.6.17.13
# cp System.map /boot/System.map-livecd-2.6.17.13
# cp arch/i386/boot/bzImage /boot/vmlinuz-livecd-2.6.17.13

编辑/boot/grub/menu.lst,为新内核增加条目。

重启机器,测试新内核是否正常。

测试正常之后,把新内核的相关文件备份到/newpkg/kernel/2.6.17.13-livecd目录下。

现在启动的是新内核,以后如果要恢复使用旧内核,注意恢复对应的模块目录:

# cd /lib/modules/
# mv 2.6.17.13 2.6.17.13-livecd
# mv 2.6.17.13-slak 2.6.17.13

 

3.定制linux-live

由于我们使用了新版本的squashfs和unionfs,可能与linux-live自身提供的版本有出入。为了一致,我们同时也对linux-live中原有的相关文件进行更新。

(1).更新内核模板

根据linux-live的DOC/requirements.txt要求,拷贝新内核模板squashfs.ko和unionfs.ko到linux-live的相应目录:

# cd /sources/linux-live-5.5.0/initrd/kernel-modules
# mkdir 2.6.17.13
# rmdir 2.6.16
# cd /lib/modules/2.6.17.13-livecd/kernel/fs/unionfs
# cp unionfs.ko /sources/linux-live-5.5.0/initrd/\
kernel-modules/2.6.17.13/
# cd ../squashfs/
# cp squashfs.ko /sources/linux-live-5.5.0/initrd/\
kernel-modules/2.6.17.13/

(2).更新squashfs工具

参考squashfs软件包的安装说明INSTALL文件,编译squashfs工具,用生成的目标文件更新linux-live中对应文件:

# cd /sources/squashfs3.1-r2/squashfs-tools
# make
# cp mksquashfs /sources/linux-live-5.5.0/tools/
# cp unsquashfs /sources/linux-live-5.5.0/tools/

(3).更新unionfs工具

参考unionfs软件包中的安装说明INSTALL文件,编译unionfs工具,用生成的目标文件更新linux-live中对应文件:

# cd /sources/unionfs-1.3/
# make utils
# cd utils
# cp unionctl /sources/linux-live-5.5.0/initrd/rootfs/bin/
# cp uniondbg /sources/linux-live-5.5.0/initrd/rootfs/bin/

(4).busybox

busybox没有更新。如果要编译busybox工具,可使用linux-live中的configs/.config.busybox配置文件,编译完后用生成的目标文件更新linux-live中对应文件。

备份更改过的linux-live到/newpkg目录下:

# cd /sources
# cp -r linux-live-5.5.0 /newpkg

 

4.准备具体内容

这是定制的核心内容。缺省情况下,linux-live脚本是把当前运行系统的内容制作成livecd,这也是最推荐的做法,因为可以保证将要的制造的系统是可以正常运行的(至少在本机上)。代价就是我们需要事先安装一个专门用来制作livecd的linux,这得耗费至少一个磁盘分区。

当然,也可以把一个目录的内容作为制作的蓝本。这种方法没有上述的问题,但对制作者有更多的要求。下面就两种方式分别进行介绍。

(一).分区方式

这里分区名为/dev/hda12。

(1).安装基础系统

使用slackware11.0的安装盘进行安装。有以下几个要点:

a/软件包列表:

设置时区为中国上海。

重启仍旧进入宿主系统,当前系统这时还不能引导,内核都没有。

(2).复制内核

拷贝制作好的内核到新系统中:

# mount /dev/hda12 /mnt
# cd /newpkg/kernel/2.6.17.13-livecd
# cp config-livecd-2.6.17.13 /mnt/boot
# cp System.map-livecd-2.6.17.13 /mnt/boot
# cp vmlinuz-livecd-2.6.17.13 /mnt/boot
# mkdir /mnt/lib/modules
# cp modules-livecd-2.6.17.13.tar.bz2 /mnt/lib/modules
# cd /mnt/lib/moudles
# tar xjvf modules-livecd-2.6.17.13.tar.bz2
# rm modules-livecd-2.6.17.13.tar.bz2

为上述文件创建必要的符号链接。

编辑/boot/grub/menu.lst,为新系统增加条目。

重启,这次可以进入新系统了。

一切正常的话继续后面的工作。

(3).安装软件包

我们这次制作的是一张含有开发系统,不支持XWindow图形,支持网络,支持命令行中文的CD。

安装其他软件包,列表如下:

ap/

d/

l/

n/

当前使用的内核头文件是2.4版的,以防不时之需,我们拷贝了一份2.6的头文件在/root下:

kernel-headers-2.6.17.13-i386-1.tgz
kernel-headers.WARNING

注意不要直接安装它,它会直接覆盖2.4头文件。开始之前,可以看看WARNING文件。

(4).配置网络

# netconfig

我们这里假定目标系统至少有一块网卡,设置静态IP为10.111.111.111/24。如果使用dhcp,则启动后执行相关命令进行设置。

(5).设置/etc/rc.d/rc.modules

当前系统中,还没有rc.modules文件。我们这里使用宿主机中的rc.modules-2.6.17.13。

(6).修改/etc/rc.d/rc.S

这里需要去掉rc.S中的对root分区的检查,原因在linux-live的DOC/requirements.txt中有说明。修改之前备份一个rc.S到rc.S-old,具体的差别可以diff rc.S rc.S-old看到。原文是这么说的:

You must modify your distro to NOT test the status of root directory(whether it is (is not) writable). For example, Slackware is testing the status of the root partition during boot and if it's read-write, it will display a message and will wait for user input. This is something we don't like, right? Unionfs can't be remounted ro, so I can't avoid this in linux live scripts. I have to patch Slackware rc scripts (rc.S) to skip the test. You will need to do something similar for your distro.

(7).修改/etc/rc.d/rc.M

去掉ldconfig的调用,在一个只读的光盘中是没必要的。修改之前备份一个rc.M到rc.M-old,具体的差别可以diff rc.M rc.M-old看到。

(8).修改/etc/rc.d/rc.6

参照slax系统中的做法,在关机前弹出CD。修改之前备份一个rc.6到rc.6-old,具体的差别可以diff rc.6 rc.6-old看到。

(9).调整linux-live-5.5.0

从宿主机得到linux-live-5.5.0的一个拷贝,放到/tmp目录下。并进行启动参数的一些微调,当前我们只调整启动时的屏幕分辨率。修改的文件有:/tmp/linux-live-5.5.0/cd-root/boot中的splash.cfg和splash.txt。

(10).配置防火墙

从宿主机获得一份/newpkg的拷贝,放在/root目录下,以供在别的地方使用。

配置防火墙iptables

# cp /root/newpkg/rc.iptables-client.ref /etc/rc.d/rc.iptables

修改/etc/rc.d/rc.S文件,在末尾添加模板/root/newpkg/rc.S.ref的内容。

(11).配置系统参数

配置一些系统参数sysctl

# cp /root/newpkg/rc.sysctl.ref /etc/rc.d/rc.sysctl

编辑/etc/rc.d/rc.M,将模板/root/newpkg/rc.M.ref内容加入到rc.inet2的前面。

(12).别的软件包

最后安装几个附加的软件包,在/root/newpkg下获得:

(二).目录方式

Slackware的包管理工具installpkg有一个选项-root可以把软件包安装到指定的地方。我们正是使用这一特性把系统的核心内容都安装到一个目录里,这里使用/livecd目录。

根据自己需要,依次使用installpkg -root安装相应的软件包。

需要注意的是,安装一个初始系统和安装到一个目录是有区别的,区别就在有些软件包的配置脚本上。由于安装到目录时,已经有一个现成运行的宿主系统了,所以一些脚本的运行环境会有所不同,从而可能导致错误的结果。

典型的是glibc-solibs包,该包是必须要装的。其中的脚本依赖于ldconfig,在宿主系统上会得出错误结果(可以查看具体的脚本内容)。为避免这问题,在安装glibc-solibs之前,先执行:

chmod a-x ldconfig

目的是使ldconfig失效。安装该包后,再执行:

chmod a+x ldconfig

恢复ldconfig功能。

其他软件包如果有此问题,也需要相应处理。相比之下,在现有系统上制作的方式就简单多了。

安装的软件包列表同分区方式。

其他一些配置修改同分区方式。

在这里可以用chroot做一个检查,执行:

chroot /livecd

执行一些命令,如果出现"not found"之类的错误,多半就是前面安装glibc-solibs时ldconfig没有处理好,导致关键的动态库没有生成,所谓的"not found"只是假象。

编辑livecd/etc下的hardwareclock、localtime、localtime-copied-from文件,设置时区,这里使用中国时间Asia/Shanghai。

编辑相关文件,进行网络设置。涉及如下:

把前面定制好的内核以及相关模板都放在/livecd/boot和/livecd/lib/modules目录的对应位置上。

把linux-live目录拷贝放到/livecd/tmp下。

修改linux-live中的config配置文件,设置ROOT=/livecd。具体可参阅该文件中的注释说明。

 

5.制作ISO映像文件

现在一切准备就绪,执行runme.sh脚本,生成ISO文件。

如果一切顺利,生成的ISO文件为/tmp/livecd.iso。

把映像文件刻录成光盘使用。