[unix] img 파일 내에서 파티션을 포맷하는 방법은 무엇입니까?

img다음 명령을 통해 파일을 만들었습니다 .

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

0이있는 파일 일뿐이지만 파일을 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

그리고 하나의 파티션으로 가정 해 봅시다.

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 파일 시스템을 사용하여 형식을 지정하는 방법을 알고 있습니까?



답변

루프백 기능을 통해 디스크 이미지와 개별 파티션에 액세스 할 수 있습니다. 일부 디스크 유틸리티가 디스크 이미지에서 (합리적으로) 행복하게 작동한다는 것을 이미 발견했습니다. 그러나 mkfs그중 하나가 아닙니다 (그러나 이상하게 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옵션은 커널에게 장치에서 파티션 테이블을 검색하고 보조 루프 장치를 자동으로 할당하도록 지시합니다. 하나의 파티션 /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
    

답변

일반적으로, 사용이 작업을 수행하는 또 다른 방법이 있습니다 kpartx( 하지 KDE 관련)

sudo kpartx -a binary.img

이제 모든 파티션 장치 /dev/mapperloop0p1 , loop0p2 , … 로 정의되어 있어야합니다 .

그리고

sudo mkfs.ext4 /dev/mapper/loop0p1

선택적으로, 당신이 완료되면, 당신은 또한 실행할 수 있습니다

sudo kpartx -d binary.img

loop0p를 제거하려면? deivce


답변

왜 찾는 지 모르겠습니다 binary.img1

(… 그리고 나중에 binary.img2해설 에 묻히기 위해 .)

도구가 파일 이름이 특정 패턴을 따를 것으로 예상하기 때문입니다. 이 패턴은 시스템의 실제 디스크 및 디스크 볼륨에 장치 파일에서 사용되는 패턴입니다.

  • 전체 디스크를 포함하는 장치 파일의 이름이 지정됩니다 sda(또는 다른 것). 이것이 fdisk활용할 것으로 기대됩니다.
  • 그 분할에 의해 기술 된 디스크의 개별 조각의 장치 파일 명명되어 sda1, sda2, sda3, 등. 이것은 개별 디스크 볼륨 에 대한 작업 gparted을 할 때 사용 하는 도구와 같은 것 입니다.mkfs

물론 일반 파일은 디스크 장치 파일과 같은 방식으로 겹치지 않습니다. 당신이 본 것을 루프백 파일 시스템을 포함하는 토론은 하나의 전체 디스크 이미지 파일을 복용하고 만들 루프백 사용에 대한 모두 1, 2, 3그 안에 각각의 조각을 반영, 등 파일을 원하는 파티션 레이아웃이 작성되고 나면 파티션 테이블에.


답변

이 주제는 직접적인 관련이 없지만 동일하고 관련된 많은 정보를 언급합니다.

데비안 위키 | 라즈베리 파이 및 qemu 사용자 정적

apt이 게시물에 언급 된 일부 명령을 설치 하는 데 사용할 수없는 경우을 사용해보십시오 apt-cache search [package_name]. 명령이 다른 이름의 패키지에서 온 경우 결과가 나타나지 않을 수 있습니다.

예를 들어, losetup이전에는를 losetup사용하여 설치할 수 apt install losetup있었지만 이제는 util-linux우분투 저장소의 일부입니다 . 다른 패키지의 컨테이너 역할을하는 패키지를 찾는 방법은 Linux 배포판의 온라인 저장소 검색을 사용해야합니다. 또는 다른 소스에서 설치해야하는 경우 웹 검색 엔진을 사용하십시오.

체크 아웃 할 가치가있는 일부 패키지 …

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

모든 Linux 배포판에는 자체 온라인 맨 페이지도 있습니다. 때로는 튜토리얼보다 맨 페이지를 사용하는 것이 더 쉽습니다. 매뉴얼 페이지는 또한 모든 명령 옵션과 매개 변수를 알려줍니다. 튜토리얼은 일반적으로 사용 된 튜토리얼에만 중점을 둡니다.


답변

최소 실행 가능 sfdisk+ mke2fs예 미포함sudo

이 예에서는 sudoor 없이 setsuid, 호스트 디렉토리의 파일로 채워진 두 개의 ext2 파티션이 포함 된 이미지 파일을 작성합니다.

그런 다음 sudo losetup파티션을 마운트하여 Linux 커널이 실제로 읽을 수 있는지 테스트하기 위해 /programming/1419489/how-to-mount-one-partition-from-an-image를 사용합니다. 다중 파티션을 포함하는 파일 / 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"

우분투 18.04에서 테스트되었습니다. GitHub의 상류 .

기존 원시 파일 시스템 파일을 이미지로 랩핑하는 도우미

위에서 추출하면 다음이 유용 할 수 있습니다.

# 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의 상류 .


답변