我需要创建一个包含两个空文件系统的磁盘映像。我已使用以下方式创建它
dd if=/dev/zero of=./disk.img bs=1MiB count=1024
接下来,我使用 创建了 2 个主分区fdisk disk.img
;一个是 FAT32,另一个是 EXT3。现在,我必须格式化这两个分区才能创建要挂载为 的文件系统-o loop devices
。但我不明白如何格式化它们?我不能使用mkfs.vfat
。disk.img
所以我完全糊涂了。
解决方案:感谢@pjc50 的回答,我找到了非常简单的解决方案:
sudo aptitude install multipath-tools
sudo kpartx -a disk.img #it maps (mounts) found partitions to /dev/mapper/loop...
sudo mkfs.vfat -F 32 -n boot /dev/mapper/loop0p1
sudo mkfs.ext3 -L rootfs /dev/mapper/loop0p2
该解决方案的缺点是需要超级用户权限。
答案1
看来您可以使用 kpartx 工具: http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/
Kpartx 可用于为任何分区块设备的分区设置设备映射。它是 Linux 多路径工具的一部分。使用 kpartx -l imagefile,您可以概览映像文件中的分区,使用 kpartx -a imagefile,可以通过 /dev/mapper/loop0pX(X 是分区编号)访问分区。现在,您可以使用 mount /dev/mapper/loop0pX /mnt/ -o loop,ro 来安装它。卸载后,您可以使用 kpartx -d imagefile 断开映射器设备的连接。
答案2
您可以通过首先使用选项将分区挂载到 来/dev/loop?
执行此操作,losetup
该选项用于-o
指定分区的合适偏移量。可以根据fdisk -l disk.img
( start_sector * sector_size
) 的输出计算偏移量。
例如:
losetup -o32256 /dev/loop1 ./disk.img # mount first partition
安装后,您可以使用以下命令格式化分区mkfs.*
:
mkfs.vfat -F32 /dev/loop1
有关更多详细信息和示例,请参阅以下文章:
答案3
我会采用我想到的工具:
- 在 Virtualbox 中创建一个具有一个磁盘的新虚拟机,通常是
/dev/sda
- 使用 GParted Live CD 启动虚拟机
- 根据您的需要对虚拟机中的磁盘进行分区和格式化(2 个分区、不同的文件系统等)
- 然后用于
dd
导出/dev/sda
到文件
根据有根据的猜测,这将需要大约 15 分钟。
答案4
最小可运行文件sfdisk
+mke2fs
示例sudo
在此示例中,我们将创建一个包含两个 ext2 分区的图像文件(无需sudo
或)setsuid
,每个分区都填充了来自主机目录的文件。
然后我们将使用sudo losetup
它来挂载分区来测试 Linux 内核是否真的可以读取它们,如下所述:https://stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265
有关详细信息,请参阅:
sfdisk
:处理分区表:如何使用 bash 脚本创建和格式化分区?mke2fs
:处理分区的 EXT 格式:如何在没有超级用户权限的情况下创建 ext2 映像?
这个例子:
#!/usr/bin/env bash
# Input params.
root_dir_1=root1
root_dir_2=root2
partition_file_1=part1.ext2
partition_file_2=part2.ext2
partition_size_1_megs=32
partition_size_2_megs=32
img_file=img.img
block_size=512
# Calculated params.
mega="$(echo '2^20' | bc)"
partition_size_1=$(($partition_size_1_megs * $mega))
partition_size_2=$(($partition_size_2_megs * $mega))
# Create a test directory to convert to ext2.
mkdir -p "$root_dir_1"
echo content-1 > "${root_dir_1}/file-1"
mkdir -p "$root_dir_2"
echo content-2 > "${root_dir_2}/file-2"
# Create the 2 raw ext2 images.
rm -f "$partition_file_1"
mke2fs \
-d "$root_dir_1" \
-r 1 \
-N 0 \
-m 5 \
-L '' \
-O ^64bit \
"$partition_file_1" \
"${partition_size_1_megs}M" \
;
rm -f "$partition_file_2"
mke2fs \
-d "$root_dir_2" \
-r 1 \
-N 0 \
-m 5 \
-L '' \
-O ^64bit \
"$partition_file_2" \
"${partition_size_2_megs}M" \
;
# Default offset according to
part_table_offset=$((2**20))
cur_offset=0
bs=1024
dd if=/dev/zero of="$img_file" bs="$bs" count=$((($part_table_offset + $partition_size_1 + $partition_size_2)/$bs)) skip="$(($cur_offset/$bs))"
printf "
type=83, size=$(($partition_size_1/$block_size))
type=83, size=$(($partition_size_2/$block_size))
" | sfdisk "$img_file"
cur_offset=$(($cur_offset + $part_table_offset))
# TODO: can we prevent this and use mke2fs directly on the image at an offset?
# Tried -E offset= but could not get it to work.
dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_1))
rm "$partition_file_1"
dd if="$partition_file_2" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_2))
rm "$partition_file_2"
# Test the ext2 by mounting it with sudo.
# sudo is only used for testing, the image is completely ready at this point.
# losetup automation functions from:
# https://stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265
loop-mount-partitions() (
set -e
img="$1"
dev="$(sudo losetup --show -f -P "$img")"
echo "$dev" | sed -E 's/.*[^[:digit:]]([[:digit:]]+$)/\1/g'
for part in "${dev}p"*; do
if [ "$part" = "${dev}p*" ]; then
# Single partition image.
part="${dev}"
fi
dst="/mnt/$(basename "$part")"
echo "$dst" 1>&2
sudo mkdir -p "$dst"
sudo mount "$part" "$dst"
done
)
loop-unmount-partitions() (
set -e
for loop_id in "$@"; do
dev="/dev/loop${loop_id}"
for part in "${dev}p"*; do
if [ "$part" = "${dev}p*" ]; then
part="${dev}"
fi
dst="/mnt/$(basename "$part")"
sudo umount "$dst"
done
sudo losetup -d "$dev"
done
)
loop_id="$(loop-mount-partitions "$img_file")"
sudo cmp /mnt/loop0p1/file-1 "${root_dir_1}/file-1"
sudo cmp /mnt/loop0p2/file-2 "${root_dir_2}/file-2"
loop-unmount-partitions "$loop_id"
在 Ubuntu 18.04 上测试。GitHub 上游。