创建一个 Linux 系统的 ISO

本文主要记录了怎样自己创建一个 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    

如何修改boot目录下的initrd.gz:

    [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/

安装isolinux

$mkdir -p isolinux-test/isolinux

下面复制的文件从syslinux的源码目录中来,可能需要编译。

$cp core/isolinux.bin isolinux-test/isolinux
$cp com32/menu/menu.c32 isolinux-test/isolinux
$cat > isolinux.cfg <<EOF
>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的启动菜单。 选择启动后会发现系统不能启动,这是因为没有可以启动的系统内核。

安装可启动的Linux内核

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 <<EOF
> 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系统

自己创建一个可以运行的ISO系统比较复杂,主要的复杂性在系统启动阶段,initramfs要能够正确的引导系统,分析ISO文件中的内容,正确的挂载文件系统,还要使根文件系统可写,这可以使用device mapper的snapshot和aufs等来实现。

让ISO可以直接写入U盘启动

syslinux提供的isobybrid工具可以让ISO直接写入U盘进行启动,直接运行

$isohybrid image.iso

即可。

linux-live和aufs

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

猜你喜欢

转载自blog.csdn.net/yangguangmeng/article/details/83305497