本文主要记录了怎样自己创建一个 Linux 系统的 ISO。
isolinux制作:
1、首先下载linux kernel,定制自己的kernel,用make bzImage 生成bzImage。
[root@localhost testOS]# ls boot/
bzImage grub initrd.gz initrd.img
2、从Ubuntu或者其他linux发行版中找到 isolinux.bin 以及 isolinux.cfg,isolinux.cfg 按自己的需求定制。
[root@localhost testOS]# ls isolinux/
efiboot.img isolinux.bin isolinux.cfg ldlinux.c32
3、busybox生成的rootfs制作成 initrd.img 的脚本:
makeInitrdImg.sh脚本如下:
dd if=/dev/zero of=disk bs=1M count=2
mkfs.ext2 -m0 disk
mount -o loop disk /mnt
cp -R rootfs/* /mnt
umount /mnt
dd if=disk of=initrd.img
4、制作自己的isolinux启动盘的脚本。
利用makeInitrdImg.sh 生成 initrd.img ,利用 makeMiniLinux.sh 生成 miniLinux.iso
makeMiniLinux.sh脚本:将miniLinux目录制作成 miniLinux.iso
#!/bin/sh
mkdir -p miniLinux/isolinux
cp isolinux.bin isolinux.cfg vmlinuz initrd.img miniLinux/isolinux
mkisofs -o minilinux.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table miniLinux
-o 生成镜像文件名称。
-b 开机映像文件。
-c 开机文件名称。
5、让ISO可以直接写入U盘启动
syslinux提供的isobybrid工具可以让ISO直接写入U盘进行启动,直接运行
$isohybrid minilinux.iso
[root@localhost boot]# ls
bzImage grub initrd.gz initrd.img
方法:
gunzip initrd.gz
mkdir tmp
mount -o loop initrd tmp
在tmp目录下修改文件,最终的initrd文件会发生变化;
[root@localhost boot]# vim tmp/bin/install_smartos.sh 修改下面信息
kernel /bzImage root=LABEL=SmartOS_I selinux=0 console=ttyS0,115200n8
umount initrd
gzip -c initrd > initrd.gz
[root@localhost boot]# rm -rf initrd tmp/
$mkdir -p isolinux-test/isolinux
下面复制的文件从syslinux的源码目录中来,可能需要编译。
$cp core/isolinux.bin isolinux-test/isolinux
$cp com32/menu/menu.c32 isolinux-test/isolinux
$cat > isolinux.cfg <UI menu.c32
>label isolinux-test
> menu label isolinux-test
>EOF
$genisoimage -no-emul-boot -boot-info-table -boot-load-size 4 \
>-o isolinux-test.iso -b isolinux/isolinux.bin -c isolinux/boot.cat \
>isolinux-test
上面命令创建一个可以启动的ISO, -c参数是可选的,如果没有指定,那么将 在ISO的根目录下生成boot.catalog文件。
$qemu -M pc -cdrom isolinux-test.iso -boot d
应该可以看到虚拟机从光盘启动,并且显示了isolinux的启动菜单。 选择启动后会发现系统不能启动,这是因为没有可以启动的系统内核。
isolinux做为一个bootloader,可以很方便的配置可以启动的内核。
$cp /boot/vmlinuz isolinux-test/isolinux
$cp /boot/initrd isolinux-test/isolinux
复制kernel和initramfs文件,这两个文件可以直接从系统/boot目录下获得, 注意内核架构应该和将要模拟的一致,这里我们模拟的是pc,在qemu中默 认为i686,如果kernel在编译时已经包含了正确的initramfs,那么可以不复 制相应的initramfs文件。现在,应该修改isolinux的配置文件,让其启动 kernel。
$cat >> isolinux-test/isolinux/isolinux.cfg < kernel vmlinuz
> append initrd=initrd root=CDLABEL=isolinux-test rootfstype=iso9660 ro
>EOF
然后,使用genisoimage创建ISO文件。
$genisoimage -no-emul-boot -boot-info-table -boot-load-size 4 \
>-o isolinux-test.iso -b isolinux/isolinux.bin -c isolinux/boot.cat \
>-V "isolinux-test" isolinux-test
最后,用qemu模拟虚拟机
$qemu -M pc -cdrom isolinux-test.iso -boot d
启动虚拟机后,可以看到虚拟机可以正常启动,但是最后由于没有可以挂载 的根文件系统,虚拟机进入initramfs提供的shell环境。
自己创建一个可以运行的ISO系统比较复杂,主要的复杂性在系统启动阶段,initramfs要能够正确的引导系统,分析ISO文件中的内容,正确的挂载文件系统,还要使根文件系统可写,这可以使用device mapper的snapshot和aufs等来实现。
syslinux提供的isobybrid工具可以让ISO直接写入U盘进行启动,直接运行
$isohybrid image.iso
即可。
linux-live项目让Linux live CD/USB变得可写,可以存储用户数据,从而变得非常易用,linux-live只是一些列脚本,通过aufs来实现可写。基本思想是利用aufs可以将不同的文件系统分支挂载到同一地点,例如,ISO是只读的,如果将它和另一个可写的文件系统挂载在一起,那么对ISO的写入将会通过COW存储在另一个可写文件系统中。如果能够让挂载后的aufs成为Live CD/USB的根文件系统,那么表面上只读的Live CD/USB就变成了可以保存持久化数据的可写文件系统,许多Live CD都使用aufs和tmpfs来实现读写,但是由于tmpfs存储在内存中,所以一般的LiveCD不能将数据持久化,而Linux-Live的目标正是如此。这里有一个简单的aufs使用的例子,从aufs文档而来
$ mkdir /tmp/rw/tmp/aufs
# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
在/tmp/aufs中可以读写文件,但是$HOME目录却没有任何改变,而在/tmp/rw目录下可以发现所做的修改。 另外,也有一些Live CD/USB使用device mapper来实现文件系统可写,使用device mapper的snapshot机制即可,例如MeeGo。
genisoimage基本用法
mkisofs (or genisoimage) -o image.iso /path/of/folder
如有中文不能显示尝试(建议使用):
mkisofs (or genisoimage) -J -o image.iso /path/of/folder
完整命令查看:
mkisofs (or genisoimage) --help 或 man genisoimage
命令: mkisofs(make iso file system)
功能说明:建立ISO 9660映像文件。
语 法:mkisofs [-adDfhJlLNrRTvz][-print-size][-quiet][-A <应用程序ID>][-abstract <摘要文件>][-b <开机映像文件>][-biblio ][-c <开机文件名称>][-C <盘区编号,磁区编号>][-copyright <版权信息文件>]
[-hide <目录或文件名>][-hide-joliet <文件或目录名>][-log-file <记录文件>][-m <目录或文件名>][-M <开机映像文件>][-o <映像文件>][-p <数据处理人>][-P <光盘发行人>][-sysid <系统ID >]
[-V <光盘ID >][-volset <卷册集ID>][-volset-size <光盘总数>][-volset-seqno <卷册序号>][-x <目录>][目录或文件]
补充说明:mkisofs可将指定的目录与文件做成ISO 9660格式的映像文件,以供刻录光盘。
参 数:
-r或-rational-rock 使用Rock Ridge Extensions,并开放全部文件的读取权限。
-o<映像文件>或-output<映像文件> 指定映像文件的名称。
-x<目录或文件>。
-c<开机文件名称> 制作可开机光盘时,mkisofs会将开机映像文件中的全-eltorito-catalog<开机文件名称>全部内容作成一个文件。
-b<开机映像文件>或-eltorito-boot<开机映像文件> 指定在制作可开机光盘时所需的开机映像文件。
-no-emul-boot 非模拟模式启动。
-boot-load-size 即设置载入部分的数量。
-boot-info-table 在启动的图像中显示信息。
-a或--all mkisofs通常不处理备份文件。使用此参数可以把备份文件加到映像文件中。
-A<应用程序ID>或-appid<应用程序ID> 指定光盘的应用程序ID。
-abstract<摘要文件> 指定摘要文件的文件名。
-biblio 指定ISBN文件的文件名,ISBN文件位于光盘根目录下,记录光盘的ISBN。
-C<盘区编号,盘区编号> 将许多节区合成一个映像文件时,必须使用此参数。
-copyright<版权信息文件> 指定版权信息文件的文件名。
-d或-omit-period 省略文件后的句号。
-D或-disable-deep-relocation ISO 9660最多只能处理8层的目录,超过8层的部分,RRIP会自动将它们设置成ISO 9660兼容的格式。使用-D参数可关闭此功能。
-f或-follow-links 忽略符号连接。
-h 显示帮助。
-hide<目录或文件名> 使指定的目录或文件在ISO 9660或Rock RidgeExtensions的系统中隐藏。
-hide-joliet<目录或文件名> 使指定的目录或文件在Joliet系统中隐藏。
-J或-joliet 使用Joliet格式的目录与文件名称。
-l或-full-iso9660-filenames 使用ISO 9660 32字符长度的文件名。
-L或-allow-leading-dots 允许文件名的第一个字符为句号。
-log-file<记录文件> 在执行过程中若有错误信息,预设会显示在屏幕上。
-m<目录或文件名>或-exclude<目录或文件名> 指定的目录或文件名将不会房入映像文件中。
-M<映像文件>或-prev-session<映像文件> 与指定的映像文件合并。
-N或-omit-version-number 省略ISO 9660文件中的版本信息。
-p<数据处理人>或-preparer<数据处理人> 记录光盘的数据处理人。
-print-size 显示预估的文件系统大小。
-quiet 执行时不显示任何信息。
-R或-rock 使用Rock Ridge Extensions。
-sysid<系统ID> 指定光盘的系统ID。
-T或-translation-table 建立文件名的转换表,适用于不支持Rock Ridge Extensions的系统上。
-v或-verbose 执行时显示详细的信息。
-V<光盘ID