imgファイル内のパーティションをフォーマットする方法は?


12

img次のコマンドでファイルを作成しました。

dd if=/dev/zero bs=2M count=200 > binary.img

ゼロのファイルですが、それを使用してfdiskパーティションテーブルを作成できます。

# fdisk binary.img

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x51707f21.

Command (m for help): p
Disk binary.img: 400 MiB, 419430400 bytes, 819200 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: 0x51707f21

そして、たとえば、1つのパーティション:

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-819199, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-819199, default 819199): 

Created a new partition 1 of type 'Linux' and of size 399 MiB.

Command (m for help): w
The partition table has been altered.
Syncing disks.

パーティションテーブルを確認すると、次の結果が得られます。

Command (m for help): p
Disk binary.img: 400 MiB, 419430400 bytes, 819200 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: 0x7f3a8a6a

Device      Boot Start    End Sectors  Size Id Type
binary.img1       2048 819199  817152  399M 83 Linux

したがって、パーティションが存在します。このパーティションをgpartedでフォーマットしようとすると、次のエラーが発生します。

ここに画像の説明を入力してください

なぜが検索されるのかわかりませんbinary.img1。コマンドライブからパーティションをフォーマットする方法もわかりません。

ext4ファイルシステムを使用してフォーマットする方法を知っている人はいますか?


2
1つのオプションは、この回答からlosetupトリックを実行してから、ループバックデバイスに対してmkfs.ext4を実行することです。
Miikka

私はこのリンクunix.stackexchange.com/a/87189/52763を見つけました。そして、これは実際に私が欲しかったものです。問題は、デバイスをgpartedでチェックすると、が表示されることですCouldn't find valid filesystem superblock.。これが写真です:i.imgur.com/dl7XAC4.png。これは一種のバグですか?
ミハイルモルフィコフ2015年

回答:


13

ループバック機能を介してディスクイメージとその個々のパーティションにアクセスできます。一部のディスクユーティリティがディスクイメージ上で(合理的に)正常に動作することをすでに発見しました。しかし、mkfsそれらの1つではありません(ただし、奇妙なことmountに)。

ここからの出力fdisk -lu binary.img

Disk binary.img: 400 MiB, 419430400 bytes, 819200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
...

Device           Boot Start    End Sectors  Size Id Type
binary.img1            2048 819199  817152  399M 83 Linux

作成したパーティションにアクセスするには、いくつかの選択肢があります

  1. 明示的なルート

    losetup --offset $((512*2048)) --sizelimit $((512*817152)) --show --find binary.img
    /dev/loop0
    

    出力/dev/loop0は、割り当てられたループデバイスの名前です。--offsetパラメータは、単にパーティションは(オフセットださStart)(セクタサイズを掛けました512)。一方--sizelimit、はパーティションのサイズであり、次の方法で計算できます:End-Start + 1、つまり819199-2048 + 1 = 817152であり、その数にもセクターサイズを掛ける必要があります。

    次に/dev/loop0、パーティションへの参照として使用できます。

    mkfs -t ext4 -L img1 /dev/loop0
    mkdir -p /mnt/img1
    mount /dev/loop0 /mnt/img1
    ...
    umount /mnt/img1
    losetup -d /dev/loop0
    
  2. 暗黙のルート

    losetup --partscan --show --find binary.img
    /dev/loop0
    

    出力/dev/loop0は、割り当てられたプライマリループデバイスの名前です。さらに、この--partscanオプションは、パーティションテーブルのデバイスをスキャンし、補助ループデバイスを自動的に割り当てるようにカーネルに指示します。1つのパーティションを/dev/loop0p1使用する場合は、も取得します。これは、パーティションへの参照として使用できます。

    mkfs -t ext4 -L img1 /dev/loop0p1
    mkdir -p /mnt/img1
    mount /dev/loop0p1 /mnt/img1
    ...
    umount /mnt/img1
    losetup -d /dev/loop0
    

@Mikhailは、fdisk出力の一部として既に指定されているパーティションサイズを計算したことを知りたいと思っています。
roaima

2
いくつかの数学の何が問題になっていますか?それに、これは...念のために、あなたは簡単にそのように右のセクタ番号を得ることができることを知って良いことだ
ミハイルMorfikov

簡単な観察:「mkfsフロントエンドは、ファイルシステム固有のmkfs。<type> utilsのために廃止予定です」。mkfsのマンページから引用。
gmagno

@gmagno正解です。確かに。しかし、あまり深く掘り下げずに判断できない限り、その通知は最初にutil-linux 2.25-rc1でリリースされただけであり、2015年6月のかなり後でないとDebian安定版に到達しませんでした。お気軽に現在の情報で回答を更新します。
roaima

11

これを一般的に行う別の方法があります。使用しますkpartx(kde関連ではありません)。

sudo kpartx -a binary.img

そして今、あなたはすべてのパーティションデバイス/dev/mapperloop0p1loop0p2、... として定義する必要があります

その後

sudo mkfs.ext4 /dev/mapper/loop0p1

オプションで、完了したら、実行することもできます

sudo kpartx -d binary.img

loop0pを取り除くには?デバイス


2
なぜこれがもっと投票しないのかわからない。IMO最高の答えです...!
Jeremy Davis

たとえば、ディスク全体のddからEFIパーティションを変更する場合など、GPTパーティションで機能します。
Russ

3

なぜ探しているのかわかりません binary.img1

(…そして後でbinary.img2解説に埋められた。)

これは、ツールがファイル名が特定のパターンに従うことを期待しているためです。そのパターンは、システム上の実際のディスクおよびディスクボリュームのデバイスファイルで使用されるパターンです。

  • ディスク全体を含むデバイスファイルに名前が付けられますsda(またはその他の名前)。これはfdisk利用することを期待するものです。
  • そのパーティショニングによって記述ディスクの個々のスライスのデバイスファイルは、名前が付けられsda1sda2sda3、など。これは、個々のディスクボリュームで処理を実行gpartedするように指示mkfsするときに使用することを期待するツールなどです。

もちろん、通常のファイルは、ディスクデバイスファイルのように重複することはありません。あなたが見てきたことをループバックファイルシステムに関わる議論は、単一の全体のディスクイメージファイルを取得し、作成するために、ループバック使用についてのすべてです123その中の個々のスライスを反映して、などのファイルを、目的のパーティションレイアウトが書かれていたら、パーティションテーブルに。


それは理にかなっている!
ミハイルモルフィコフ2015年

0

このトピックは直接の関連はありませんが、多くの同じ関連情報について言及しています。

Debian wiki | Raspberry Piとqem​​u-user-static

を使用aptしてこの投稿に記載されているコマンドの一部をインストールできない場合は、を使用してみてくださいapt-cache search [package_name]。コマンドが別の名前のパッケージからのものである場合、これは結果を表示しない場合があります。

たとえば、losetup以前はをlosetup使用してインストールできましapt install losetupたが、現在util-linuxはUbuntuのリポジトリに含まれています。どのパッケージが別のパッケージのコンテナーとして機能するかを見つける方法として、Linuxディストリビューションのオンラインリポジトリの検索を使用する必要があります。または、別のソースからインストールする必要がある場合は、Web検索エンジンを使用します。

チェックアウトする価値のあるいくつかのパッケージ...

util-linux genisoimage dosfstools squashfs-tools fsarchiver xfsprogs reiserfsprogs reiser4progs jfsutils ntfsprogs btrfs-tools

すべてのLinuxディストリビューションには、独自のオンラインマンページもあります。チュートリアルよりもマンページの方が簡単な場合があります。マニュアルページには、すべてのコマンドオプションとパラメーターも記載されています。チュートリアルは通常、使用されるものにのみ焦点を当てます。


0

最小限の実行可能sfdisk+ mke2fsなしの例sudo

この例では、2つのext2パーティションを含むイメージファイルを作成するsudosetsuid、作成せずに作成します。それぞれにホストディレクトリからのファイルが読み込まれます。

次にsudo losetup、パーティションをマウントするためだけに使用して、Linuxカーネルが実際にそれらを読み取れることをテストしますhttps : //stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image -file-that-c​​ontains-multiple-partitions / 39675265#39675265

詳細については、以下を参照してください。

例:

#!/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:
# /programming/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アップストリーム

既存のrawファイルシステムファイルを画像にラップするヘルパー

上記から抽出すると、以下が役立ちます。

# Put a raw filesystem file into a disk image with a partition table.
#
# /unix/209566/how-to-format-a-partition-inside-of-an-img-file/527132#527132
#
# Usage:
#
#     sfdisk-fs-to-img root.ext2
#
# Creates a file:
#
#     sfdisk-fs-to-img root.ext2.img
#
sfdisk-fs-to-img() (
  partition_file_1="$1"
  img_file="${partition_file_1}.img"
  block_size=512
  partition_size_1="$(wc -c "$partition_file_1" | awk '{print $1}')"
  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)/$bs)) skip="$(($cur_offset/$bs))"
  printf "
  type=83, size=$(($partition_size_1/$block_size))
  " | sfdisk "$img_file"
  cur_offset=$(($cur_offset + $part_table_offset))
  dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
  cur_offset=$(($cur_offset + $partition_size_1))
)

GitHubアップストリーム

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.