我正在尝试使用我找到的以下脚本从 tarball 制作 .img:
#!/bin/bash
# Packages required
# dosfstools parted
# Can be run on any Linux system
# loop.max_part=15 must be in kernel cmdline (cmdline.txt for rpi)
# then reboot
echo "creating image to fit on 2Gb card"
dd if=/dev/zero of=arch-rpi.img bs=1M count=1850
echo "Partitioning"
fdisk arch-rpi.img <<EOF
o
n
p
1
+100M
t
c
n
p
2
w
EOF
sleep 5
losetup -f arch-rpi.img
sleep 5
echo "Formatting vfat"
mkfs.vfat /dev/loop0p1
sleep 5
mkdir boot
echo "Mounting boot"
mount /dev/loop0p1 boot
echo "Installing"
echo "Formatting ext4"
mkfs.ext4 /dev/loop0p2
sleep 5
mkdir root
echo "Mounting root"
mount /dev/loop0p2 root
wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
echo "Installing"
bsdtar -xpf ArchLinuxARM-rpi-latest.tar.gz -C root
sync
mv root/boot/* boot
sync
umount boot root
losetup -d /dev/loop0p1
losetup -d /dev/loop0p1
losetup -d /dev/loop0
echo "All complete, image arch-rpi.img created, compressing...."
zip -9 arch-rpi.img.zip arch-rpi.img
我正在我的 Raspberry Pi - Raspbian Wheezy 上执行此操作。当它到达该行时,mkfs.vfat /dev/loop0p1
它说没有这样的文件/目录。我已经在 Linux 上阅读了足够多的内容,知道我正在尝试将 .img 安装为循环设备,然后使用 mkfs 为 tarball 准备图像,但我不太清楚为什么不存在 Loop0p# 文件,它们由 列出fdisk -l
。我需要做什么才能让我发现的这个脚本正常工作?
答案1
您需要用于losetup -P
创建-P
分配的循环设备,否则您需要对原始循环设备进行分区,然后partx -u
更新内核的分区表。设备/dev/loop0p
将出现后内核识别出该分区实际上已被分区。也许这部分是其背后的意图sleep 5
- 但几乎肯定应该是一个sync
- 或两者兼而有之。
无论如何,为了证明:
sudo sh -s <<\IN
losetup -D
fallocate "-l$((1024*1024*1024))" loop
printf %s\\n n '' '' '' '' w y | gdisk loop
sync; losetup -f loop
lsblk /dev/loop*
IN
所以上面的序列首先-D
蚀刻所有电流环路设备(如果有的话) fallocate
sa 1GB tmp 文件,向其写入 GPT 分区表并对其进行单个分区,然后sync
创建文件系统并将其分配给-f
第一个可用的循环设备,然后尝试列出lsblk
所有可用的循环设备。它打印:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 1G 0 loop
但如果我将该losetup
行更改为:
losetup -fP loop
...它改为打印:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 1G 0 loop
├─loop0p1 259:0 0 1023M 0 loop
└─loop0p2 259:1 0 1007K 0 loop
...因为losetup
首先扫描备份文件中的分区表。正如你所看到的,它并不是很擅长——而不是注意到额外的 1M(实际上,这几乎肯定是最后一次迭代的分区表)作为未分配的空间,它将其解释为一个单独的分区,但这可能是因为我正在写入 tmpfs(连续两次)在 1GB 文件洞的顶部 - 使用实际数据进行工作会更加精确(并将支持文件清零,就像您的脚本所做的那样,dd
无论如何都会处理这个问题)。无论如何 - 我可以自由地mkfs.whatever
在真正的分区上然后mount
它。partx -u
上/dev/loop0
会达到相同的结果。
答案2
在驱动程序中,对分区的支持是可选的,由加载驱动程序时的参数loop
决定。max_part
默认值为 0,因此循环驱动程序甚至不会查找分区;如果值为非零,则驱动程序支持那么多分区。根据内核构建选项,驱动程序可能包含在内核中,在这种情况下,您需要loop.max_part=…
在引导时传递内核命令行,或者作为模块加载,在这种情况下,您需要max_part=…
在模块启动时传递已加载。
在 Debian 上 wheezyloop
是一个模块,max_part
参数未传递。要获得分区支持,请卸载模块并使用参数将其加载回来max_part
(您需要首先使用 停用任何现有的循环设备losetup -d
):
if lsmod | grep -wq loop; then rmmod loop; fi
modprobe loop max_part=31
您可以通过添加到options loop max_part=31
来将其设置为默认值/etc/modprobe.conf
。
如果您无法卸载模块(或者在loop
内核内置的发行版上重新启动),您可以手动计算分区的偏移量并-o
使用losetup
.看
从整个磁盘映像读取文件系统
使用较新的发行版,losetup -P
您可以在设置循环设备时使用:
…
losetup -P -f arch-rpi.img
…
但是util-linux
Debian wheezy 上的软件包太旧了,没有这个选项。