当前位置: 首页 > 工具软件 > Devel Live CD > 使用案例 >

开发自己的gentoo LiveCD

姜俊民
2023-12-01

在论坛里发现的(地址:http://www.linuxsir.org/bbs/thread304021.html),觉得有用与大家分享。

 

我上一次呼吁搞一个中文gentoo LiveCD计划后,发觉自己嘴巴说得响了,还是要赶紧做点实事,连忙查资料,弄了一下,这几天做出了可启动的LiveCD,写出这篇文章,跟大家聊聊如何做一张LiveCD.
首先声明我做出来的LiveCD,不是一张通用发行版,很可能在其他机子上不能启动,不过大家知道原理后,根据自己情况,加入相应模块,即可.
大家会问:不是通用版没啥意思啊?
确实是,其实好用的通用版满街都是,SLAX中文版做得不错,我曾经用她来安装gentoo 系统,SLAX启动后会自动挂载你硬盘所有的分区,得umount所需的分区,重新mount进去,才好去安装,有中文环境,可以上网,有音乐,视频播放器,kde界面,这样的环境能满足你的要求的话,就不要重复劳动了,用她就好了.还有一些另类的LiveCD来满足你另类的要求,如GoboLinux,目录结构截然不同传统,大家有兴趣可去下列网站浏览,看看有啥:
http://www.frozentech.com/content/livecd.php
如果你非要自己弄弄的,好跟我一齐来,哈哈~~~~~

以下是参考 gentoo wiki 写成,
http://gentoo-wiki.com/LiveCD
http://gentoo-wiki.com/HOWTO_build_a_LiveCD_from_scratch

现在gentoo 制作LiveCD有两种方法
1.catalyst , 这种方法是把需要的软件打成大包,一次编译出来,脚本化而已(没做研究,留着大家去探讨吧~~~~)
2.全手动,下文所使用的方法,好处是步骤清晰,容易控制.

准备工作:
1.有足够硬盘空间,要根据制作的目标系统大小来估算
2.熟悉如何在stage2安装gentoo
3.熟悉手动编译内核
4.安装调试工具VMware ,或者是其他虚拟机.
5.准备一些工具
squashfs-tools : squashfs压缩文件工具集
mkisofs : 制作可启动光盘文件系统
cdrtools : 光盘刻录工具
splashutils : splashutils 制作Livecd全图形启动界面

设置安装环境:
同步portage树
#emerge --sync

创建安装目录:
livecd的根目录
#mkdir -p /opt/livecd

开发livecd的工作平台
#mkdir /opt/livecd/source


下载:
#cd /opt/livecd/source

在gentoo主站,找到镜像列表,进入找出stage2,下载之:
#wget <<YOUR FAVORITE MIRROR>>/releases/x86/current/stages/stage2-x86-2007.0.tar.bz2

有关portage树,可以有两种方法处理:
1.如果使用你原有的宿主系统在硬盘里的portage,可以不用安装,挂载一下即可.(推荐此方法)
2.下载安装
#wget <<YOUR FAVORITE MIRROR>>/snapshots/portage-latest.tar.bz2

解开gentoo基本架构:
#cd /opt/livecd/source
#tar -jxvpf stage2-XXXXXXX

解开portage :
#cd usr/
# tar -jxvf ../portage-latest.tar.bz2


设置挂载点:
#cd /opt/livecd/source
#mount --bind /proc proc
#mount --bind /dev dev
#mount --bind /sys sys

用下面命令来挂载整个portage,最好原来的portage要同步一下emerge --sync
#mkdir -p usr/portage
#mount --bind /usr/portage usr/portage

#mkdir -p usr/portage/distfiles
#mount --bind /usr/portage/distfiles usr/portage/distfiles

复制一些文件过来:
#cp /etc/resolv.conf /opt/live/source/etc/resolv.conf
#cp /etc/make.conf /opt/live/source/etc/make.conf

根据自己的需要复制文件(略)


编辑 /opt/livecd/source/etc/make.conf 文件:
可以把原系统的文件复制过来,但因应liveCD 的环境要求,修改USE参数,USE="-java -doc livecd -qt -kde"
除非是构建体积少的LiveCD ,而因此用到一些特殊库和工具,否则就不要加入minimal参数了.
根据自己需要修改,但一定要有livecd 参数.

编辑 /opt/livecd/source/etc/locale.gen 文件,设置最少的必须locale
en_US ISO-8859-1
en_US.UTF-8 UTF-8
zh_CN.GB18030 GB18030
zh_CN.GBK GBK
zh_CN.UTF-8 UTF-8
zh_CN GB2312

chroot :
#cd /opt/livecd/source &&
chroot . env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash --login
这里使用了LFS风格的chroot命令,减去宿主系统的环境变量,减少对编译的干扰,特别是locale检测环节.

#env-update && source etc/profile

检查环境变量:
#env

看一下system系统安装了些什么
#emerge --pretend --emptytree system | less

最好是记录下来:
#emerge --pretend --emptytree system >>emerge_list

安装系统:
#emerge -e system

#emerge -e world
#升级了GCC,或者有时间没事干的,执行一下吧

设置系统
#passwd
#ln -sf /usr/share/zoneinfo/<path to time zone file> /etc/localtime

根据自己要求配置系统(略)

安装一些必要的软件,以下是我的emerge_list,可能有些忘了记录,大家要根据自己实际情况增减:
emerge system :
[ebuild N ] sys-libs/zlib-1.2.3-r1 USE="-build"
[ebuild N ] sys-libs/gpm-1.20.1-r5
[ebuild N ] sys-libs/ncurses-5.6-r1 USE="gpm unicode -bootstrap -build -debug -doc -minimal -nocxx -trace"
[ebuild N ] app-shells/bash-3.2_p17 USE="nls -afs -bashlogger -vanilla"
[ebuild N ] sys-libs/readline-5.2_p4
[ebuild N ] virtual/libiconv-0
[ebuild N ] dev-libs/expat-2.0.0
[ebuild N ] sys-devel/gettext-0.16.1 USE="nls -doc -emacs -nocxx"
[ebuild N ] sys-apps/diffutils-2.8.7-r1 USE="nls*"
[ebuild N ] virtual/libintl-0
[ebuild N ] sys-apps/findutils-4.3.3 USE="nls -static"
[ebuild N ] sys-devel/binutils-config-1.9-r3
[ebuild N ] sys-devel/gnuconfig-20070118
[ebuild N ] sys-devel/binutils-2.17 USE="nls -multislot -multitarget -test -vanilla"
[ebuild N ] sys-libs/db-4.5.20_p2 USE="-bootstrap -doc -java -nocxx -tcl -test"
[ebuild N ] sys-libs/gdbm-1.8.3-r3 USE="berkdb"
[ebuild N ] sys-devel/libperl-5.8.8-r1 USE="berkdb* gdbm*"
[ebuild N ] dev-lang/perl-5.8.8-r2 USE="berkdb* gdbm* -build*"
[ebuild N ] dev-libs/openssl-0.9.8e USE="zlib -bindist -emacs -sse2 -test"
[ebuild N ] dev-lang/python-2.4.4 USE="berkdb gdbm ipv6 ncurses readline ssl -bootstrap -build -doc -nocxx -tk -ucs2"
[ebuild N ] dev-python/python-fchksum-1.7.1
[ebuild N ] perl-core/Test-Harness-2.64
[ebuild N ] app-admin/perl-cleaner-1.04.3
[ebuild N ] perl-core/PodParser-1.35
[ebuild N ] app-misc/ca-certificates-20070303
[ebuild N ] sys-apps/sandbox-1.2.18.1
[ebuild N ] dev-libs/popt-1.10.7 USE="nls"
[ebuild N ] net-misc/rsync-2.6.9-r2 USE="ipv6 -acl -static -xinetd"
[ebuild N ] app-misc/pax-utils-0.1.15 USE="-caps"
[ebuild N ] sys-apps/texinfo-4.8-r5 USE="nls -build -static"
[ebuild N ] sys-devel/autoconf-wrapper-4-r3
[ebuild N ] sys-devel/m4-1.4.9 USE="nls -examples"
[ebuild N ] sys-devel/autoconf-2.61 USE="-emacs"
[ebuild N ] sys-devel/automake-wrapper-3-r1
[ebuild N ] dev-perl/Locale-gettext-1.05
[ebuild N ] sys-apps/help2man-1.36.4 USE="nls"
[ebuild N ] sys-devel/automake-1.10
[ebuild N ] sys-devel/libtool-1.5.23b
[ebuild N ] sys-devel/automake-1.9.6-r2
[ebuild N ] sys-apps/groff-1.19.2-r1 USE="-X -cjk"
[ebuild N ] sys-apps/man-1.6e-r3 USE="nls"
[ebuild N ] sys-apps/man-pages-2.46 USE="nls"
[ebuild N ] sys-apps/coreutils-6.9-r1 USE="nls -acl -static -xattr"
[ebuild N ] app-i18n/man-pages-zh_CN-1.5
[ebuild N ] sys-apps/sed-4.1.5 USE="nls -static"
[ebuild N ] dev-python/pycrypto-2.0.1-r5
[ebuild N ] sys-apps/portage-2.1.2.6 USE="-build -doc -epydoc" LINGUAS="-pl"
[ebuild N ] sys-apps/debianutils-2.18 USE="-static"
[ebuild N ] sys-apps/mktemp-1.5
[ebuild N ] dev-util/unifdef-1.20
[ebuild N ] sys-kernel/linux-headers-2.6.21
[ebuild N ] sys-apps/sysvinit-2.86-r8 USE="-static"
[ebuild N ] virtual/init-0
[ebuild N ] sys-apps/baselayout-1.12.10-r3 USE="unicode -bootstrap -build -static"
[ebuild N ] sys-fs/udev-110-r1
[ebuild N ] sys-apps/module-init-tools-3.2.2-r3 USE="-no-old-linux"
[ebuild N ] app-arch/gzip-1.3.12 USE="nls -pic -static"
[ebuild N ] sys-devel/flex-2.5.33-r2 USE="nls -static"
[ebuild N ] sys-apps/hdparm-6.9-r1
[ebuild N ] sys-devel/make-3.81 USE="nls -static"
[ebuild N ] app-crypt/hashalot-0.3-r2
[ebuild N ] sys-libs/com_err-1.40_pre20070411 USE="nls"
[ebuild N ] sys-libs/ss-1.40_pre20070411 USE="nls"
[ebuild N ] sys-fs/e2fsprogs-1.40_pre20070411 USE="nls -static"
[ebuild N ] sys-apps/util-linux-2.12r-r6 USE="crypt nls perl -old-crypt -static"
[ebuild N ] sys-libs/timezone-data-2007e USE="nls"
[ebuild N ] sys-devel/gcc-config-1.3.16
[ebuild N ] dev-libs/gmp-4.2.1-r1 USE="-doc -nocxx"
[ebuild N ] sys-devel/bison-2.3 USE="nls -static"
[ebuild N ] dev-libs/mpfr-2.2.1_p5
[ebuild N ] sys-devel/gcc-4.1.2 USE="fortran nls -bootstrap -build -d -doc -gcj -gtk -hardened -ip28 -ip32r10k -mudflap -multislot -nocxx -objc -objc++ -objc-gc -test -vanilla"
[ebuild N ] sys-libs/glibc-2.5-r2 USE="nls nptl nptlonly -build -debug -glibc-compat20 -glibc-omitfp -hardened -profile"
[ebuild N ] app-arch/bzip2-1.0.4 USE="-static"
[ebuild N ] sys-apps/which-2.16
[ebuild N ] app-arch/tar-1.16.1 USE="nls -static"
[ebuild N ] sys-devel/patch-2.5.9-r1 USE="-build -static"
[ebuild N ] sys-process/psmisc-22.5 USE="ipv6 nls -X"
[ebuild N ] dev-util/pkgconfig-0.21-r1 USE="-hardened"
[ebuild N ] dev-libs/libpcre-7.0 USE="unicode -doc"
[ebuild N ] sys-apps/grep-2.5.1a-r1 USE="nls pcre -static"
[ebuild N ] sys-apps/busybox-1.5.0 USE="-debug -make-symlinks -savedconfig -static"
[ebuild N ] app-arch/cpio-2.7-r2 USE="nls"
[ebuild N ] sys-apps/less-394 USE="unicode*"
[ebuild N ] sys-libs/pwdb-0.62
[ebuild N ] sys-libs/cracklib-2.8.10 USE="nls python"
[ebuild N ] sys-libs/pam-0.99.7.1 USE="nls -vim-syntax"
[ebuild N ] sys-apps/shadow-4.0.18.1 USE="cracklib nls pam -nousuid -skey"
[ebuild N ] sys-apps/tcp-wrappers-7.6-r8 USE="ipv6"
[ebuild N ] net-misc/openssh-4.6_p1-r1 USE="pam tcpd -X -X509 -chroot -hpn -kerberos -ldap -libedit -skey -smartcard -static"
[ebuild N ] sys-process/procps-3.2.7
[ebuild N ] sys-apps/gawk-3.1.5-r3 USE="nls"
[ebuild N ] sys-apps/kbd-1.12-r8 USE="nls"
[ebuild N ] net-misc/wget-1.10.2 USE="ipv6* nls* ssl* -build*"
[ebuild N ] sys-apps/file-4.20-r1 USE="python"
[ebuild N ] sys-apps/net-tools-1.60-r13 USE="nls -static"
[ebuild N ] app-editors/nano-2.0.6 USE="ncurses nls unicode -debug -justify -minimal -slang -spell"
[ebuild N ] net-misc/iputils-20070202 USE="ipv6 -doc -static"

emerge memtest86+ :
[ebuild N ] sys-apps/memtest86+-1.70 USE="-serial" 147 kB
内存测试工具

emerge localepurge :
[ebuild N ] app-admin/localepurge-0.5.3.3 5 kB

emerge livecd-tools :
[ebuild N ] sys-apps/pciutils-2.2.4-r3 USE="zlib -network-cron" 206 kB
[ebuild N ] dev-util/dialog-1.1.20070409 USE="unicode -examples" 357 kB
[ebuild N ] app-misc/livecd-tools-1.0.35-r1 USE="-X -opengl" 10 kB

编译内核:
liveCD内核很讲究,如果是通用版的内核,也就是说能应付各种硬件,要用genkernel来编译整个内核(我没用过此方法,仅列出命令)
#genkernel all --no-bootsplash --no-clean --menuconfig


下面是使用手动方法,仅编译出自己的内核
内核选项(略)
关键在文件系统支持选项,要有SquashFS,其他一些如ext2,ext3 ,iso9660, Initial RAM disk (initrd) support等等
硬件选项
USB 选项,如果要支持USB盘启动
热检支持,用于udev
参考下面网址:
http://lamp.linux.gov.cn/Linux/kernel_options.html

#make && make modules_install,
#cp arch/i386/boot/bzImage /boot/vmlinuz
#cp .config /boot/config

利用genkernel在开机时侦测所有的硬件的功能,运用在initrd. 如果你已经配置了和编译完成内核,可以使用下面命令,只创建initrd :
#emerge genkernel
#genkernel initrd

在/boot目录下,产生有文件:initramfs-genkernel-x86-2.6.21-gentoo,就是initrd.

能生成initrd 还有一个程序是mkinitrd,两者的initrd有什么区别,大家可以去研究研究
有关工具一些说明,有一些工具是一次性的如genkernel,为了能生成initrd,安装了一堆东东,心里有点不爽,用完以后,可以考虑去掉.

清除一下locale:
#localepurge
#makewhatis -u

调试系统
网络
环境变量
等等
(略)


编辑/etc/fstab 文件

/dev/loop0 / squashfs ro,defaults 0 0
none /proc proc defaults 0 0
none /dev/shm tmpfs defaults 0 0

下一个阶段是有关系统启动部分
这一阶段非常关键,LiveCD成败60%在此,哈哈~~~,吓唬人.
首先要补充一些LiveCD知识:

可启动CD-ROM格式规范(Bootable CD-ROM Format Specification)1.0——El Torito规范,该规范中定义了可启动CD-ROM的数据结构与映像数据的配置及光盘制作的一些详细说明。
简单来说,linux启动划分为四个基本步骤:
第一阶段引导加载
第二阶段引导加载
第三阶段内核启动
第四阶段用户空间初始化

当系统首次引导时被重置时,处理器会执行一个位于已知位置处的代码。在个人计算机(PC)中,这个位置是基本输入/输出系统(BIOS),它保存在主板上的闪存中。当找到一个引导设备之后,第一阶段的引导加载程序就被装入 RAM 并执行。这个引导加载程序在大小上小于 512 字节(一个扇区),其作用是加载第二阶段的引导加载程序。当第二阶段的引导加载程序被装入 RAM 并执行时,通常会显示一个动画屏幕,并将 Linux 和一个可选的初始 RAM 磁盘(临时根文件系统)加载到内存中。在加载映像时,第二阶段的引导加载程序就会将控制权交给内核映像,然后内核就可以进行解压和初始化了。在这个阶段中,第二阶段的引导加载程序会检测系统硬件、枚举系统链接的硬件设备、挂载根设备,然后加载必要的内核模块。完成这些操作之后启动第一个用户空间程序(init),并执行高级系统初始化工作。

livecd启动:
设置BIOS光驱启动(第一阶段),光驱没MBR分区,会找到GRUB,插一句,有些livecd是多重启动的,要用syslinux+GRUB启动链(没研究过),
第三阶段内核启动,第四阶段用户空间初始化,第一个init生成.

安装引导器grub
#emerge grub

在/boot/grub 目录中包含很多引导加载程序,其中两个文件最重要:iso9660_stage1_5 --- 光盘多重启动加载程序,stage2_eltorito -- 光盘启动加载程序.
在这里只使用一重引导方式,因此只需stage2_eltorito.

GRUB 菜单配置是通过位于 /boot/grub/grub.conf 的一个配置文件来完成,这个文件是一个指向menu.lst 链接,如果是引导LiveCD ,
不用链接方式,使用实际配置文件,删除原来的链接,重新建立新的menu.lst文件.

default 0
timeout 30
splashimage=/boot/grub/splash.xpm.gz

title=LiveCD

kernel /boot/vmlinuz root=/dev/ram0 \
real_root=/dev/loop0 vga=788 looptype=squashfs \
loop=/livecd.squashfs udev nodevfs cdroot dodmraid
initrd /boot/initramfs-genkernel-x86-2.6.21-gentoo


用grub传递内核参数是一个大课题,老实说,我还没研究透,还可以安排很多选项,根据需要.

补充:
退出chroot环境
#exit &&
#umount sys proc dev usr/portage usr/portage/distfiles &&
#env-update &&
#source /etc/profile

重新进入chroot:
#cd /opt/livecd/source
#mount -o bind /proc proc
#mount -o bind /sys sys
#mount -o bind /dev dev
#mount --bind /usr/portage usr/portage
#mount -o bind /usr/portage/distfiles usr/portage/distfiles
#chroot . env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash --login
#env-update
#source /etc/profile

最后关键阶段是导出系统
livecd目录结构不同于系统结构,类似于软盘启动盘时的结构,每一张盘的容量非常有限,一张盘只能放启动内核,对应是boot目录,另一张盘放些工具,对应就是tools目录了,现在的livecd最起码要把/boot目录放在根目录下,然后看需要设置一个放模块目录,如果硬件完全编译到内核或者像我一样,自己内核,启动没有问题的,可以不用设模块目录.


退出chroot
#exit &&
#umount sys proc dev usr/portage usr/portage/distfiles &&
#env-update &&
#source /etc/profile


建立livecd的根目录:
#cd /opt/livecd
#mkdir /opt/livecd/target

在根目录下建立boot镜像,你也可以用cp命令,但要非常小心保留原系统的完整性,如权限,GID,UID,需要用一些参数,这里使用建立镜像命令,一来速度快,能保留原系统的完整,二是可以方便调试.大家可要看看rsync命令的解释,我也是第一次用,算是大开眼界,哈哈~~~
#rsync -a --delete --progress /opt/livecd/source/boot /opt/livecd/target/

建立根分区镜像,exclude参数是不包含的目录,有目的选则镜像什么内容,很明显是不镜像portage,包数据库在livecd里没什么用.其他的可以适当增减.
#mkdir -p /opt/livecd/target/files/source
#rsync -a --delete --progress --exclude "var/tmp/*" --exclude "var/cache/*" --exclude "*.h" --exclude "usr/portage" --exclude "etc/portage" --exclude "usr/share/doc" --exclude "usr/src" /opt/livecd/source/ /opt/livecd/target/files/source/

压缩系统的根区,大多数livecd都有压缩,压缩的文件系统是squashfs,编译内核时一定要选上此.
cd /opt/livecd/target/files
mksquashfs source/ /opt/livecd/target/livecd.squashfs

建一个空文件,这个文件必须是在livecd 根, 因为init 剧本在initramfs 使用这个文件辨认,cd 登上或不是.
#touch /opt/livecd/target/livecd

现在根分区的压缩文件和boot都出来了,理论上target/files可以删除,劝你还是要保留它,除非你是一次调节到位,否则不要立即删除,删除命令
#rm -rf /opt/livecd/target/files

建立可启动光盘文件
#cd /opt/livecd/
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -iso-level 4 -hide-rr-moved -c boot.catalog -o /opt/livecd/livecd.iso -x files /opt/livecd/target/

-R :使用Rock Ridge Extensions
-b boot/grub/stage2_eltorito :启动器
-x files :不包含files目录

这时iso文件出来了,打开Vmware,设置光驱由iso文件启动并指向iso文件路径,看看能否启动,看见bash符号,恭喜你了,livecd诞生了.


看livecd目录结构:
#mount -o loop xxx.iso /mnt/目录
#cd /mnt/目录
#ls

继续扩展livecd内容,重新进入chroot环境
#cd /opt/livecd/source
#mount -o bind /proc proc
#mount -o bind /sys sys
#mount -o bind /dev dev
#mount --bind /usr/portage usr/portage
#mount -o bind /usr/portage/distfiles usr/portage/distfiles
#chroot . env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash --login
#env-update
#source /etc/profile

继续你的emerge 旅程

完了以后记得rsync,把所修改的内容镜像,再mkisofs
#rsync -a --delete --progress /opt/livecd/source/boot /opt/livecd/target/
#rsync -a --delete --progress --exclude "var/tmp/*" --exclude "var/cache/*" --exclude "*.h" --exclude "usr/portage" --exclude "etc/portage" --exclude "usr/share/doc" --exclude "usr/src" /opt/livecd/source/ /opt/livecd/target/files/source/

好了,livecd能做了,下一步就看大家如何去完善
加入gensplash支持,开机动画,看起来更专业
如果你内存有1G,livecd体积不大,让它完全在内存里跑,这时可以把livecd拿出来是没问题的
设定自动挂载软盘,把设置保留在软盘上,下次可用
制作USB盘的live系统
等等

以上这些都可以去玩玩,我是很懒的,还是先前那个iso放在一边,没有进一步去研究完善,哈哈~~~~~

 

 类似资料: