[备忘]Hiweed的casper目录和ISO镜像的优盘和硬盘引导

Ubuntu各种衍生版本
回复
xiaoyong
帖子: 515
注册时间: 2006-05-20 10:38

[备忘]Hiweed的casper目录和ISO镜像的优盘和硬盘引导

#1

帖子 xiaoyong » 2007-08-02 2:09

概述:Hiweed是目前配置最为完善、使用最为方便的中文linux系统,它基于xubuntu──ubuntu的xfce版,采用livecd技术,可以脱离硬盘从光盘启动、运行,不再需要独立的linux分区,也不对硬盘进行任何操作,并能适应不同的硬件环境,不经安装就可以使用linux系统,是一项有趣的技术。ubuntu的desktop发行版属于livecd,是一个经过定制、压缩的完整linux系统,能够检测和识别不同的硬件环境,自动完成系统的配置,并生成配置文件,因而可以从光盘启动、运行。在desktop的光盘镜像内的casper目录下的文件filesystem.squashfs,就是那个应用squashfs压缩的linux系统,压缩比达到1:3,可以在700MB的光盘内压缩2G左右的文件,如果应用squashfs的lzma补丁,还可以压缩更多的文件。光盘镜像内的isolinux目录,用于引导光盘上的casper系统。isolinux是syslinux在光盘上的实现,目录中的vmlinuz是一个压缩的linux内核,在引导时由isolinux装入,可以识别并支持不同的硬件;而initrd.img是一个压缩的小型linux系统,用于生成针对不同硬件环境的配置文件,并装入、解压casper目录内的filesystem.squashfs,最终完成系统的启动。本文的目的就是将livecd迁移到优盘或硬盘上,以livecd的方式启动系统,可以称之为liveUSB和liveHD。livecd运行时对squashfs系统的装入和配置,是由initrd.img内的casper脚本完成的,本文所讨论的操作就是编辑casper脚本,使其能够识别优盘和硬盘上的casper目录或ISO镜像,进而完成系统的引导和装入。本文所述技术,来源于ubuntu中文论坛的gnix_oag、lvjinhua和ptptptpt的帖子,本文仅仅进行一些整理,方便自己和他人使用。gnix_oag对这项技术做了很大的发展,不但能够完成系统的引导,还能进行软件的安装和升级,但本文的原则是把对livecd的改动限制到最小的程度,最大程度的保留livecd的原始运行环境。

一、修改inird.gz

gnix_oag的帖子《修改 initrd.gz 文件 (法二)》viewtopic.php?p=98012#98012,写的很细,照着做就是。

首先,从Hiweed光盘内的isolinux目录复制initrd.gz文件,如果ISO镜像文件尚未刻录成光盘,windows下,可以用winrar、7-zip等解压缩软件或虚拟光驱软件打开镜像文件;linux下,可以用mount命令装配镜像文件,例如:
# mount -t iso9660 -o loop /media/hda1/hiweed.iso /mnt
是把/media/hda1下的hiweed.iso装配到/mnt目录下,这样在/mnt下就是光盘内的目录和文件。
# cp /mnt/isolinux/initrd.gz .
复制initrd.gz到当前目录。

解压initrd.gz文件(ubuntu内的相应文件是initrd.img),可以用linux内图形界面的解压缩软件Xarvhiver;或者直接使用gzip命令,
# gzip -d initrd.gz
它会释放出解压的initrd文件,并删除原先的initrd.gz。现在得到的initrd是用cpio命令压缩的文件,我们需要使用cpio继续解压缩,
# mkdir tmp
# cd tmp
# cpio -i < ../initrd
以上三条命令用来在当前目录下创建tmp目录,然后在tmp目录内释放initrd。

我们会看到tmp目录内出现了很多目录和文件,它们就是用来装入squashfs压缩文件的小型linux系统,casper脚本在目录scripts下,用文本编辑器对casper脚本进行修改,脚本内有一段find_cd(),用来搜寻光盘上的casper目录,而我们要把它替换成gnix_oag和lvjinhua修改后的程序,使它能够扫描所有的优盘和硬盘分区,去寻找casper目录。修改后的find_cd()见《制作从硬盘起动 ubuntu live_cd 的 initrd.gz》7楼,viewtopic.php?t=11906#97712

这里有两个版本,一个是gnix_oag最初的程序,它能够自动寻找各个分区根目录下的casper目录,一个是lvjinhua改进后的版本,能够自动寻找各个分区根目录下的ISO镜像文件并进行装入。前者是把包含casper目录的分区当做livecd光盘,因而系统引导后该分区是只读的,用户无法对该分区进行写操作;后者是把分区根目录下的ISO镜像文件当做livecd光盘,因而系统引导后,用户可以对该分区进行写操作,当然ISO镜像文件除外。所以我们可以根据需要选择不同的脚本,注重安全,就选前者,需要复制casper目录到目标分区;注重灵活,就选后者,需要复制ISO镜像文件。

搜寻casper目录的find_cd脚本,

代码: 全选

find_cd() {
   mounted=   
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
            devname=$(sys2dev "${sysblock}")
               for dev in $(subdevices "${sysblock}"); do
                    devname=$(sys2dev "${dev}")
                    case $(get_fstype "${devname}") in    
                        iso9660|ext2|ext3|udf|reiserfs|jfs|xfs)
                            modprobe $(get_fstype "${devname}")
                            mount -t $(get_fstype "${devname}") "${devname}" $mountpoint || continue
                             if find_iso $mountpoint ; then
                                 echo $in_iso_squashfs
                                 return
                             else
                                 umount $mountpoint
                             fi
                                                                         ;;
                         vfat|ntfs)
                             modprobe $(get_fstype "${devname}")
                             mount -t $(get_fstype "${devname}") -o utf8 "${devname}" $mountpoint || continue
                             if find_iso $mountpoint ; then
                                 echo $in_iso_squashfs
                                 return
                             else
                                 umount $mountpoint
                             fi
                                                                  ;;
                                                               *)
                                                                 ;;
                    esac
                done
        done
}
搜寻ISO镜像的find_cd脚本,就是在find_cd前加了个find_iso()

代码: 全选

find_iso()
{
   local isoroot="/iso9660"
   local tmproot=$1
   isos=`ls ${tmproot}/*.iso 2>/dev/null` || return 1
   modprobe loop
   mkdir -p "$isoroot"
   for iso in ${isos}
   do
       mount -t iso9660 -o loop $iso $isoroot 2>/dev/null || continue
       if casper_path "$isoroot"; then
           #echo "$isoroot"/casper/filesystem.squashfs
           in_iso_squashfs="$isoroot"/casper/filesystem.squashfs
           return 0        else
           umount "$isoroot"
       fi
   done
   unset isos
   unset iso
   return 1
}

find_cd() {
   mounted=   
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
            devname=$(sys2dev "${sysblock}")
               for dev in $(subdevices "${sysblock}"); do
                    devname=$(sys2dev "${dev}")
                    case $(get_fstype "${devname}") in    
                        iso9660|ext2|ext3|udf|reiserfs|jfs|xfs)
                            modprobe $(get_fstype "${devname}")
                            mount -t $(get_fstype "${devname}") "${devname}" $mountpoint || continue
                             if find_iso $mountpoint ; then
                                 echo $in_iso_squashfs
                                 return
                             else
                                 umount $mountpoint
                             fi
                                                                         ;;
                         vfat|ntfs)
                             modprobe $(get_fstype "${devname}")
                             mount -t $(get_fstype "${devname}") -o utf8 "${devname}" $mountpoint || continue
                             if find_iso $mountpoint ; then
                                 echo $in_iso_squashfs
                                 return
                             else
                                 umount $mountpoint
                             fi
                                                                  ;;
                                                               *)
                                                                 ;;
                    esac
                done
        done
}
重新生成initrd.gz文件,
# cd tmp
# find . | cpio -L -o -H newc | gzip -9 > ../initrd.gz
这条命令首先使用cpio合成tmp目录下的所有文件和目录,然后用gzip压缩并生成initrd.gz文件。

二、安装引导管理器

Hiweed光盘的引导,采用isolinux,是linux安装光盘和livecd惯常采用的方式,它在引导的时候,允许用户在boot:后面输入一些引导参数。isolinux是syslinux在光盘上的版本,如果把livecd移植到优盘,可以采用syslinux。syslinux用在fat16/32文件系统上,而优盘通常采用的是fat16文件系统,使用syslinux能够最大限度的再现Hiweed光盘的引导序列。syslinux只支持fat16/32文件系统,如果casper目录或ISO镜像放到ext2/3文件系统的话,也可以试用extlinux,它是syslinux在ext2/3文件系统上的实现。

如果将livecd移植到硬盘,采用grub会更加方便,linux下grub会安装到硬盘的MBR上,windows下可以使用grub4dos的grldr,借助windows本身的ntloader插入对grub的引导。基本上,grub和syslinux的功能是一样的,但它们的界面不同。grub的支持的文件系统更多,几乎包括所有已知的文件系统,grub也可以用于引导优盘,但需根据isolinux的配置文件isolinux.cfg自己编写grub的配置文件menu.lst,并在其中指定优盘分区的设备名称,如果是支持usb-hdd启动的优盘,直接用(hd0,0)就可以,如果优盘仅仅支持usb-zip,可能需要在menu.lst内使用find命令寻找分区。

syslinux和grub的不同:syslinux在引导后能够自动确定其自身所在的分区,然后加载根目录下的vmlinuz和initrd.gz文件,而grub需要在menu.lst内指定vmlinuz和initrd.gz所在的分区。引导优盘,推荐使用syslinux,因为优盘会在不同的机器上使用,而grub配置文件menu.lst内的优盘设备名称在硬盘是sata类型的情况下是不确定的,而syslinux没有这个问题。当然,也可以在grub的menu.lst内使用find命令或用uuid代替优盘分区的设备名称,但还是稍显复杂,具体可以参考ptptptptpt的帖子《把 ubuntu 操作系统装入移动硬盘,并在不同电脑上运行》,viewtopic.php?t=29692,在移动硬盘上安装grub的说明。在硬盘上,不必考虑设备的变化,使用grub就简单了,直接指定vmlinuz和initrd.gz所在的分区。

查询硬盘分区的设备名称和mount路径,可以在终端执行
# mount

# df -h

应用fdisk对优盘分区,oldniu的帖子《U盘启动能保存数据的Hiweed》有详细说明,新手可以参看,viewtopic.php?t=49960,也可以参考《LiveCDPersistence》,https://help.ubuntu.com/community/LiveC ... 备名称可以在终端执行
# dmesg | less
它会显示连接优盘后的内核信息,通常在该信息的最后会有优盘的相关信息。

syslinux在优盘上的安装:
应该是所有的优盘都可以进行USB-ZIP的引导,但需要对优盘进行一些处理,在linux下,使用fdisk命令删除优盘上现有的分区,然后重新建立分区,建议casper目录或ISO镜像放到格式是fat16/32的第一分区,第二分区是ext2/3格式,因为windows系统似乎不能识别优盘上linux分区后的fat16/32分区,所以需要把第一分区格式化为fat16/32的文件系统。也可以采用Gparted这个图形程序来进行分区操作,在Hiweed里有GNOME Partition Editor,我们可以用Hiweed光盘开机来使用此程序。尽管优盘上已经有建立好的文件系统,但为了顺利安装syslinux或grub,使优盘能够引导,应用linux的分区程序重新分区是必要的操作。

在优盘上安装syslinux,需要把ISO镜像内的isolinux目录内的所有文件复制到优盘根目录下,并把isolinux.cfg改名syslinux.cfg,在本地系统上安装syslinux和mbr软件包,
# apt-get install syslinux mbr
连接优盘,建立优盘的MBR,
# install-mbr /dev/sda
再手工把优盘分区卸载,
# umount /dev/sda1
然后执行
# syslinux -f /dev/sda1
这里优盘的设备名称是/dev/sda,而sd1是指优盘第一分区,使第一分区可引导。

syslinux.cfg的示例

代码: 全选

DEFAULT vmlinuz
APPEND  preseed/file=preseed/xubuntu.seed boot=casper initrd=initrd.gz ramdisk_size=1048576 root=/dev/ram rw quiet splash --
LABEL custom
  menu label Start Hiweed in ^persistent mode
  kernel vmlinuz
  append  preseed/file=preseed/xubuntu.seed boot=casper persistent initrd=initrd.gz ramdisk_size=1048576 root=/dev/ram rw quiet splash --
LABEL live
  menu label ^Start or install Hiweed
  kernel vmlinuz
  append  preseed/file=preseed/xubuntu.seed boot=casper initrd=initrd.gz ramdisk_size=1048576 root=/dev/ram rw quiet splash --
DISPLAY isolinux.txt
TIMEOUT 300
PROMPT 1
F1 f1.txt
F2 f2.txt
F3 f3.txt
F4 f4.txt
F5 f5.txt
F6 f6.txt
F7 f7.txt
F8 f8.txt
F9 f9.txt
F0 f10.txt
menu.lst的示例

代码: 全选

title 		Hiweed liveHD
kernel 		(hd0,5)/boot/vmlinuz boot=casper ramdisk_size=1048576 root=/dev/ram rw quiet splash
initrd 		(hd0,5)/boot/initrd.gz

title 		Hiweed liveHD, persistent mode
kernel 		(hd0,5)/boot/vmlinuz boot=casper persistent ramdisk_size=1048576 root=/dev/ram rw quiet splash
initrd 		(hd0,5)/boot/initrd.gz
以上grub指定kernel和initrd的位置在(hd0,5)/boot,即第一块硬盘的第二个逻辑分区。

三、casper目录和ISO镜像的安放

因为在casper脚本内的find cd函数内,我们指定了要搜索的文件类型是vfat ntfs ext2/3 jfs xfs reiserfs,因而我们可以在上述文件系统的任意分区根目录下安放casper目录或ISO镜像,系统引导后会把所在分区识别为/cdrom,如果是casper目录,该分区是只读的,如果是ISO镜像,该分区是可写的。

注意:引导文件会自动搜索所有的磁盘分区,并把它首先搜索到的根目录下的ISO镜像文件和caper目录作为默认的系统进行载入,因而如果在不同的根目录下有多个ISO镜像文件和caper目录,需要给它们改名,只保留准备引导的那个。

vmlinuz和initrd.gz按照syslinux.cfg或menu.lst内指定的位置安放。 关于syslinux在优盘上的安装,可以参考《LiveUsbPendrivePersistent》,https://wiki.ubuntu.com/LiveUsbPendrivePersistent

四、引导参数persistent的使用

ubuntu采用的casper允许使用引导参数persistent来保存livecd的用户环境和配置文件,但在feisty中这项功能不再有效,而Hiweed基于dapper,仍然可以使用这项功能。在syslinux或grub的内核引导参数中加上persistent后,livecd引导时会自动搜索卷标为casper-rw的ext2/3分区,把livecd的用户环境和配置文件保存在内,并从中读取,这样用户所做的更改就可以保留下来。这个名为casper-rw的分区可以在优盘或者硬盘上,livecd不做区别。ext2/3分区卷标为casper-rw时,内核引导参数persistent会把livecd运行环境的所有改变都会保存下来,并在以后启动时从中读取;ext2/3分区卷标为home-rw并且已经由用户手工把/home内的所有文件和目录(不含home自身)复制到该分区时,内核引导参数persistent就会从中读取/home目录,并把/home下的变动保存下来。给ext2/3分区设置卷标,可以使用e2label命令。

在hiweed光盘引导系统时使用persistent参数,需要在boot: 出现时,键入live persistent或者custom,这里的live指isolinux配置文件isolinux.cfg内的lived段,如此才可以把persistent加入到live所在段的内核引导参数中,而custom段已经带了persistent参数。根据ubuntu的wiki资料,casper还能够存取分区根目录下名为casper-rw的ext2/3文件系统镜像,但我尝试后没有成功。

五、应用casper-rw/home-rw分区的另类安装

Hiweed的livecd运行后,会把filesystem.squashfs挂载到/rofs下,它就是一个完整的linux系统,但其中没有硬件配置和用户环境──那是由initrd.gz来完成的,但如果使用了persistent引导参数和casper-rw分区,initrd.gz生成的硬件配置和用户环境就会保存在casper-rw分区内,由此我们可以进行Hiweed的另类安装:ubuntu desktop系列的图形安装界面虽然方便,但不稳定,使用中常常会崩溃,特别是硬盘分区的识别有时会有问题,并且grub是直接安装到MBR,但应用desktop又无法使用文本界面的安装程序(alternate是文本界面的安装程序),所以我们可以依次把livecd启动后的/rofs目录下的全部内容和casper-rw分区内的全部内容复制到一个空白linux分区,然后手工安装grub,并修改/etc/fstab,在其中指定根分区和交换分区,就是一个完整的linux系统,这里复制一定要按照先/rofs后casper-rw的顺序来进行。这种安装虽然稍嫌繁琐,但非常可靠,并且可以把使用persistent参数后的用户环境完整复制过去,
# cp -a /rofs/* /media/hda3
# mount /dev/hda5 /mnt
# cp -af /mnt/* /media/hda3
以上操作假设/media/hda3是准备安装的空白分区,/dev/hda5是casper分区。

有经验的用户可以不必进入x window,在命令行下手工解压filesystem.squashfs,这样在小内存的机器上也可完成安装。
# mount -t iso9660 -o loop ~/hiweed.iso /media/cdrom
# mount -t squashfs -o loop /media/cdrom/casper/filesystem.squashfs /mnt
# cp -a /mnt/rofs/* /media/hda3
以上把Hiweed镜像挂载到/media/cdrom,再把Hiweed镜像中的filesystem.squashfs挂载到/mnt,这样不启动x window也可以安装了,当然Hiweed livecd是支持squashfs的。

应用这种安装方式时,casper目录或者ISO镜像不应该放置在casper-rw分区内,如果已经放在那里,可以把它们移到其他分区的根目录下。

补记:本文内的所有命令都是在root权限下的,因而都是shell的提示符都是#,在Hiweed中使用$ sudo是一样的效果。一定要在#下操作的话,可以在syslinux.cfg内append行或者menu.lst内kernel行增加single一词,拿Hiweed光盘引导机器的话,出现boot:时,键入live single即可。
上次由 xiaoyong 在 2007-08-07 23:27,总共编辑 3 次。
xiaoyong
帖子: 515
注册时间: 2006-05-20 10:38

#2

帖子 xiaoyong » 2007-08-02 18:50

为本文制作了引导Hiweed的casper目录和ISO镜像的引导文件,但压缩后有15MB,不能作为附件上传,如何上传到ftp.ubuntu.org.cn,我不会用,会的人,教教我吧。
上次由 xiaoyong 在 2007-08-03 11:17,总共编辑 2 次。
头像
wyg1258
帖子: 654
注册时间: 2006-09-12 19:44
来自: whu

#3

帖子 wyg1258 » 2007-08-02 20:31

不错的文章~~

hiweed 主站就有 硬盘安装的引导文件下载的
linux 学习记录 你的 我的 大家的

http://wyg1258.cublog.cn
xiaoyong
帖子: 515
注册时间: 2006-05-20 10:38

#4

帖子 xiaoyong » 2007-08-02 22:46

回复楼上,Hiweed主站的硬盘引导文件内casper脚本内find_cd()函数中的ext2 ext3写成了etx2 etx3,因而不支持ext2/3分区,虽然gnix_oag后来的脚本更正了这个笔误,但Hiweed的引导文件initrd.gz一直没有更新,所以这个错误遗留到现在。
头像
huangjiahua
帖子: 3294
注册时间: 2005-03-30 0:27
联系:

#5

帖子 huangjiahua » 2007-08-03 18:04

修正
跃过无数的时间断层,只为了在
xiaoyong
帖子: 515
注册时间: 2006-05-20 10:38

#6

帖子 xiaoyong » 2007-08-03 19:03

好,达到目的,我不必上传了, :D
xiaoyong
帖子: 515
注册时间: 2006-05-20 10:38

#7

帖子 xiaoyong » 2007-08-03 19:12

其实有个简单的办法,为了分别引导casper目录和ISO镜像,不用制作两个initrd.gz文件,原始的casper脚本保留不动,把替换了find_cd()函数的casper脚本分别保存为casper-dir和casper-iso,然后一块压到initrd.gz中去,这样引导时,在menu.lst或syslinux.cfg中用boot来选择就可以了:

boot=casper,就是livecd的原始功能,用来引导光盘;
boot=casper-dir,引导casper目录;
boot=casper-iso,引导ISO镜像。
回复