マウントせずにファイルイメージパーティションでmkfsを実行するには?

マウントせずにファイルイメージパーティションでmkfsを実行するには?

空のファイルを作成しています。

dd if=/dev/zero of=${SDCARD} bs=1 count=0 seek=$(expr 1024 \* ${SDCARD_SIZE})

...その後、ドライブイメージに変換します...

parted -s ${SDCARD} mklabel msdos

...そしてそこにパーティションを作成する

parted -s ${SDCARD} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED})
parted -s ${SDCARD} unit KiB mkpart primary $(expr  ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED}) $(expr ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED} \+ $ROOTFS_SIZE)

どのように使用しますかmkfs.extmkfs.vfat いいえこのイメージをインストールしますか?

答え1

高度なツールやルートアクセスを必要としない複数のパーティションを持つイメージを作成するソリューションは、まずファイルシステムを作成してから接続することです。

truncate -s $IMAGE_ROOTFS_ALIGNMENT disk
truncate -s $BOOT_SPACE_ALIGNED part1
mkfs.fat part1
cat part1 >>disk
truncate -s $ROOTFS_SIZE part2
mkfs.ext4 part2
cat part2 >>disk

次に、パーティションを実行partedまたは作成します。fdisk

このアプローチの欠点は、結果画像がリーンではないということである。

答え2

@gillesが提供する回答を拡張するために、フォーマットされたファイルシステムを含むディスクイメージを作成し、最初にファイル(この場合はESPタイプ)にファイルシステムを作成し、それを有効なディスクイメージにまとめる方法があります。 ;デバイスをルーティング、インストール、または循環する必要はありません。

diskimg=diskimg    # filename of resulting disk image
size=$((260*(1<<20))) # desired size in bytes, 260MB in this case
alignment=1048576  # align to next MB (https://www.thomas-krenn.com/en/wiki/Partition_Alignment)
size=$(( (size + alignment - 1)/alignment * alignment ))  # ceil(size, 1MB)

# mkfs.fat requires size as an (undefined) block-count; seem to be units of 1k
mkfs.fat -C -F32 -n "volname" "${diskimg}".fat $((size >> 10))

# insert the filesystem to a new file at offset 1MB
dd if="${diskimg}".fat of="${diskimg}" conv=sparse obs=512 seek=$((alignment/512))
# extend the file by 1MB
truncate -s "+${alignment}" "${diskimg}"

# apply partitioning
parted --align optimal "${diskimg}" mklabel gpt mkpart ESP "${offset}B" '100%' set 1 boot on

スパースファイルをサポートするファイルシステムで使用する場合、上記の方法はスパースであるという副作用があります。結果の「262MB」ファイルは、ディスク上の200kB未満のスペースを占有します。

du -h --apparent diskimg; du -h diskimg
262M    diskimg
196K    diskimg

FATファイルシステムの場合ツールユーティリティはファイルのオフセット操作をサポートしています(ext2/4/etc.もこれを実行できますか?)。これにより簡単になります。パーティションイメージを作成して直接作業できます。

diskimg=diskimg
size=$((260*(1<<20))) # desired size in bytes, 260MB in this case
# align to next MB (https://www.thomas-krenn.com/en/wiki/Partition_Alignment)
alignment=1048576

size=$(( (size + alignment - 1)/alignment * alignment ))

# image size is gpt + filesystem size + gpt backup
truncate -s $((size + 2*alignment)) "${diskimg}"

parted --machine --script --align optimal "${diskimg}" mklabel gpt mkpart ESP "${alignment}B" '100%' set 1 boot on

mformat -i "${diskimg}"@@"${alignment}" -t $((size>>20)) -h 64 -s 32 -v "volname"

以下は、結果のイメージファイルの図です。

パーティションイメージファイル

答え3

イメージファイル全体ではなくディスクイメージファイルでパーティションをフォーマットしようとしています。この場合、losetupイメージファイルをループバックデバイスとして使用するようにLinuxに指示する必要があります。

注:losetuproot権限が必要なので、rootとして実行するか、sudoを使用して実行する必要があります。有効/作成するデバイス/dev/loop*にアクセスして使用するには、root権限が必要です。

たとえば(root)

# losetup /dev/loop0 ./sdcard.img

# fdisk -l /dev/loop0
Disk /dev/loop0: 1 MiB, 1048576 bytes, 2048 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x54c246ab

Device       Boot Start   End Sectors   Size Id Type
/dev/loop0p1          1  1023    1023 511.5K  c W95 FAT32 (LBA)
/dev/loop0p2       1024  2047    1024   512K 83 Linux

# file -s /dev/loop0p1
/dev/loop0p1: data

# mkfs.vfat /dev/loop0p1 
mkfs.fat 3.0.28 (2015-05-16)
Loop device does not match a floppy size, using default hd params

# file -s /dev/loop0p1
/dev/loop0p1: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, root entries 512, sectors 1023 (volumes <=32 MB) , Media descriptor 0xf8, sectors/FAT 1, sectors/track 32, heads 64, serial number 0xfa9e3726, unlabeled, FAT (12 bit)

最後に、ループバックデバイスから画像を分離します。

# losetup -d /dev/loop0

man losetup詳細は参照してください。

答え4

@user310346の回答は、Box86で使用するFAT16ファイルシステムの作成に適用するのが特に難しく脆弱であることが判明したため、しばらく調査したところ、3つの有用なことがわかりました。

最初、user310346の回答の定型句のほとんどは、任意の項目を指定できるようにすることです。分割サイズをバイト単位で計算し、適切な丸めでドライブサイズを計算します。指定したい場合イメージ/ドライバサイズ(私は必要Box86のCHSプリセットを一致させようとしているので、Paredは自動的に残りをエクスポートできます。

第二、これ別れのマニュアル2002年以降、リストmkfsmkpartfsコマンドは理論的にこれを実行できる必要があるため、変更ログを確認してどのように変更されたかを確認することをお勧めします。おそらくもう少しあいまいなものに変わるかもしれませんが、まだルートアクセスは必要ありません。

第三、ありがとうボックスマニュアル、mtoolsを使用したい場合は、動作するファイルシステムを取得する方が簡単です。みんな働く

#!/bin/sh
cd "$(dirname "$(readlink -f "$0")")" || exit

SRC_DIR="combined_disk"
IMG_NAME="combined_disk.img"

# Size for the hard drive image
# (Here's one that's in 86Box's CHS presets)
CYLINDERS=1036
HEADS=16
SECTORS=63

# Work around partition=1 not being possible on the command-line AFAIK
mtools_tmp="$(mktemp -d --tmpdir make_disk.XXXXXXXXXX)"
mtools_conf="${mtools_tmp}/mtoolsrc"
echo "drive c: file=\"${IMG_NAME}\" partition=1" >"$mtools_conf"
export MTOOLSRC="${mtools_conf}"
cleanup() {
    rm -rf "${mtools_tmp}"
}
trap cleanup EXIT

rm -f "${IMG_NAME}.img"
truncate -s "$((CYLINDERS * HEADS * SECTORS * 512))" "$IMG_NAME"

mpartition -I -t "$CYLINDERS" -h "$HEADS" -s "$SECTORS" c: 2>&1
mpartition -c -T 6 -t "$CYLINDERS" -h "$HEADS" -s "$SECTORS" c:
mformat c:
mcopy -s "$SRC_DIR"/* c:

関連情報