当前位置: 首页 > 工具软件 > GNU arch > 使用案例 >

将Arch GNU/Linux 安装到磁盘文件(loop)

茹元魁
2023-12-01

用途:


1、多系统爱好者(比如俺),不希望磁盘分区太复杂,但又想使用多系统;
2、为测试系统方便;
3、方便删除系统(删除一个文件,修改启动配置);
4、可以做成类似PE的ROM系统;
。。。
还可以发展更多。。。

背景:
1、GRUB2 bootloader 已经支持loop设备启动(不知道其他的支持得如何);
2、 Arch GNU/Linux 官方的启动脚本无法从loop设备启动

实现的效果: 启动文件中存放的Arch GNU/Linux 

实现步骤:

1、 创建loop文件

dd if=/dev/zero of=/mnt/sda9/Arch/Arch-i686.img bs=1M count=3500
创建一个3.5GB大小的磁盘文件Arch-i686.img 存放到 /mnt/sda9/Arch 目录下


2、 建立文件系统

mkfs.reiserfs /mnt/sda9/Arch/Arch-i686.img

这里只用reiserfs, 要看bootloader的支持程度, 本打算用btrfs的,结果用grub2-btrfs测试启动不成功
ext2 ext3 ext4 reiserfs 应该是支持的, 很盼望将来grub2-btrfs能完美支持btrfs的loop设备

3、安装(移植)系统到磁盘文件
sudo mount /mnt/sda9/Arch/Arch-i686.img /tmp/install

     安装: 不赘述, 很多文档介绍
     移植现有Arch GNU/Linux 系统:

sudo tar cvpf - / --exclude=/mnt --exclude=/media --exclude=/sys --exclude=/proc --exclude=/var/abs --exclude=/var/cache/pacman/pkg --exclude=/var/lib/pacman/sync | sudo tar xvpf - -C /tmp/install

4、修改相关配置
sudo mkdir /tmp/install/sys

修改fstab (/tmp/install/etc/fstab),将挂载/的那行改为

/dev/loop0          /             reiserfs          defaults   0    1

5、修改启动内核和loop设备的系统

这个就是重中之重了, 因为目前Arch 官方的启动脚本不支持。 这里就添加一个hook来实现挂在loop设备

1) 新建 /tm/install/lib/initcpio/hooks/automount 内容:

run_hook ()
{
    # 启动参数指定 real_root=loop=/dev/sda1 loopfile=Arch/archlive.disk
    case ${real_root} in loop/=*) 
	loop=${real_root/loop=}
	if [ -e $loop ]; then
		fstype=$(blkid -u filesystem -o value -s TYPE -p "${loop}")
		if [ "${readwrite}" = "no" ]; then rwopt="ro"; else rwopt="rw"; fi
		mount -t $fstype -o $rwopt $loop $HOST
		if [ -f $HOST/$loopfile ]; then
			loopfile="$HOST/$loopfile"
			fstype=$(blkid -u filesystem -o value -s TYPE -p "${loopfile}")
			if [ "${fstype}" = "squashfs" ]; then rwopt="ro"; fi
			mount -t $fstype -o $rwopt $loopfile $UNION
			mkdir -p $UNION$HOST
			mkdir -p $UNION$loop
			mount -o bind $HOST $UNION$loop
			MOUNTED=1
		fi
	fi
	;;
	esac
}

随便写的, 快速实现需要的功能就可以了

2) 新建文件 /tmp/install/lib/initcpio/install/automount 内容如下:

install ()
{
    BINARIES="blkid"
    FILES=""
    SCRIPT="automount"
}

help ()
{
cat<<HELPEOF
  This hook auto mount the root device base on cmdline.
  Can support:
	1. Boot from normal harddisk or USB disk;
	2. Boot from CD-ROM or DVD-ROM;
	3. Boot from loop device file (made by dd or other tools);
	4. Boot from squashfs files;
   ...
HELPEOF
}

3) 修改 /tmp/install/etc/mkinitcpio.conf 在hooks 最后加入 automount

HOOKS="base udev autodetect pata scsi sata filesystems automount"

4) 修改 /tmp/install/lib/initcpio/init

在 # set default mount handler 前面加入

export HOST="/host"
           export UNION="/new_root"
           mkdir -p $HOST
           # 挂载根成功后 MOUNTED=1
           export MOUNTED="0"

将 ${mount_handler} /new_root 改成

# 如果hook已经完成root 则跳过Arch 默认的root侦测
                   if [ "$MOUNTED" = "0" ]; then ${mount_handler} $UNION; fi

5) 重新创建内核镜像

sudo mount -o bind /sys /tmp/install/sys
          sudo chroot /tmp/install mkinitcpio -p kernel26

到现在为止,磁盘文件准备完成

6、 配置启动

有几种方式:
1) 直接grub2 启动
2) ntldr --> g2ldr 来启动
3) grub --> grub2 启动
。。。 还有好几种

我用的方法2),需要制作g2ldr (不赘述,有相关文档介绍)
grub2 启动配置文件 grub.cfg 启动loop 设备项内容:

menuentry "Arch i686 (on loop 虚拟盘)" {
	insmod part_msdos
	insmod reiserfs
	insmod loopback
	loopback loop0 (hd0,msdos9)/Arch/Arch-i686.img
	set root=(loop0)
	linux /boot/vmlinuz26 real_root=loop=/dev/sda9 loopfile=Arch/Arch-i686.img  quiet 
	initrd /boot/kernel26-fallback.img
}

重新启动即可。


后话:

1、 启动脚本automount 稍作变化, 可以扩展出更多更强的功能, 比如从squashfs 启动, 再挂载可写分区保存。。。 或者直接挂载内存做成类似PE的rom系统。。。

2、。。。


在此抛砖引玉了, 欢迎探讨。。。

 

 类似资料: