歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 創建Linux系統ISO的主要技術分析

創建Linux系統ISO的主要技術分析

日期:2017/2/28 16:09:07   编辑:Linux教程

1. 安裝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的啟動菜單。
選擇啟動後會發現系統不能啟動,這是因為沒有可以啟動的系統內核。

2. 安裝可啟動的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環境。

3. 創建可以運行的ISO系統
自己創建一個可以運行的ISO系統比較復雜,主要的復雜性在系統啟動階段,initramfs要能夠正確的引導系統,分析ISO文件中的內容,正確的掛載文件系統,還要使根文件系統可寫,這可以使用device mapper的snapshot和aufs等來實現。

4. 讓ISO可以直接寫入U盤啟動
syslinux提供的isobybrid工具可以讓ISO直接寫入U盤進行啟動,直接運行
$isohybrid image.iso即可。

5. 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。

6. meego-netbook ISO分析
/isolinux/initrd/init
1. 創建和掛載虛擬文件系統,例如udev, devpts, proc, sysfs等,建立設備文件。
2. 檢查/etc/fstab,獲取根文件系統掛載信息,如果為/dev/root,則從啟動參數中獲取,這也就是isolinux.cfg中傳遞的root=CDLABEL="LABEL" rootfstype=iso9660信息,掛載的選項rootflags為空,即默認。
3. 分析根設備,添加一條udev規則,然後建立鏈接/dev/root指向真正的根設備。
4. 啟動udevd守護進程,觸發udev。
5. 判斷是否為runlevel 1,如果是,則進入bash。
6. 掛載CDROM到/sysroot。
7. 查找CDROM上的根文件系統,然後losetup,將其掛載到/sysroot,由於根文件系統在CDROM中,所以是只讀的,使用device mapper在內存中創建一個根文件系統的snapshot,然後將重新掛載到/sysroot,這時,根文件系統變得可寫。所有的寫入都通過COW機制發生在snapshot中。
8. 現在/sysroot就可讀寫了,設置locale和復制modprobe.conf,創建udev rules。最後重新掛載/sysroot為只讀。這裡不要疑惑,因為在進入根文件系統執行/sbin/init後,sysvinit然後才會將根文件系統掛載為可讀寫。
9. 殺死udevd然後chroot到根文件系統中並執行init程序。
10. 使用device mapper的snapshot機制讓只讀文件系統可寫例子。
#mkdir /tmp/ISO
#mount -o loop meego-netbook-VERSION.img /tmp/ISO
#mkdir /tmp/squashfs
#mount -o loop /tmp/ISO/LiveOS/squashfs.img/tmp/squashfs
#mkdir /tmp/rootfs
#mount -o loop /tmp/squashfs/LiveOS/ext3fs.img/tmp/rootfs
#mount 可以看到mount包括如下幾行輸出。
/dev/loop0 on /tmp/ISO type iso9660 (rw)
/dev/loop1 on /tmp/squashfs type squashfs (ro)
/dev/loop2 on /tmp/rootfs type ext3 (ro)
盡管顯示/tmp/ISO為rw,但是由於iso9660本身是一個只讀文件系統,所以不可寫。現在光盤中的根文件系統已經掛載到了/tmp/rootfs中,現在要讓它變得可寫。
#umount /tmp/rootfs
#losetup -f /tmp/squashfs/LiveOS/ext3fs.img
#dd if=/dev/zero of=/snapshot.disk bs=4k count=25000
#losetup -f /snapshot.disk
#echo "0 `blockdev --getsize /dev/loop2` snapshot /dev/loop2/dev/loop3 p 8" | dmsetup create rootfs-rw
在上面的命令中,/dev/loop2是ext3fs.img的loopback設備,/dev/loop3是/snapshot.disk的loopback設備,可以使用
#losetup -a來查看。
#mkdir /tmp/rootfs-rw
#mount /dev/mapper/rootfs-rw/tmp/rootfs-rw
#touch /tmp/rootfs-rw/test.file
可以看到,現在rootfs變成可寫的了。

Copyright © Linux教程網 All Rights Reserved