I'm trying to make a .img from a tarball using the following script I found:
#!/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
I'm doing this on my Raspberry Pi – Raspbian Wheezy. And when it gets to the line mkfs.vfat /dev/loop0p1
It says there's no such file / directory. I've read enough on Linux to know I'm trying to mount the .img as a loop device and then use mkfs to prepare the image for the tarball, but I don't quite know why loop0p# files are not there, they are listed by fdisk -l
. What do I need to to in order to get this script I found working?
Best Answer
You need to use
losetup -P
for creating a-P
artitioned loop device, or else you need to partition the original loop device thenpartx -u
pdate the kernel's partition table afterward. The/dev/loop0p
devices will appear after the kernel recognizes that the partition has actually been partitioned. Probably this is partly what the intent behind thesleep 5
is - but that should almost definitely be async
- or both - instead.Anyway, to demonstrate:
So the above sequence first
-D
etaches all current loop devices (if any)fallocate
s a 1GB tmp file, writes a GPT partition table to it and does a single partition on it, thensync
s the filesystem and assigns it to the-f
irst available loop device before trying to list withlsblk
all available loop devices. It prints:But if I alter the
losetup
line to read:...it instead prints:
...because
losetup
first scans the backing file for a partition table. As you can see, it's not very good at it - rather than noting the extra 1M (which is almost definitely the last iteration's partition table, actually) as unallocated space it interprets it as a separate partition, but that's probably because I'm writing to a tmpfs (twice in a row) at the top of a 1GB file hole - working w/ actual data will be much more precise (and zeroing the backing file as your script does w/dd
would handle that anyway). In any case - I can freelymkfs.whatever
on the real partition there and afterwardsmount
it.partx -u
on the/dev/loop0
would achieve the same results.