Làm cách nào để định dạng phân vùng bên trong tệp img?


12

Tôi đã tạo một imgtập tin thông qua lệnh sau:

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

Đây chỉ là một tệp có số 0, nhưng tôi có thể sử dụng nó trong fdiskvà tạo bảng phân vùng:

# 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

và, giả sử, một phân vùng:

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.

Khi tôi kiểm tra bảng phân vùng, tôi nhận được kết quả sau:

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

Vì vậy, phân vùng tồn tại. Khi tôi cố gắng định dạng phân vùng này qua gparted, tôi gặp lỗi sau:

nhập mô tả hình ảnh ở đây

Tôi không biết lý do tại sao nó tìm kiếm binary.img1và tôi không biết làm thế nào để định dạng phân vùng từ lệnh trực tiếp.

Có ai biết làm thế nào để định dạng nó bằng cách sử dụng hệ thống tập tin ext4?


2
Một tùy chọn là thực hiện thủ thuật losetup từ câu trả lời này và sau đó chạy mkfs.ext4 với thiết bị loopback.
Miikka

Tôi đã tìm thấy liên kết này unix.stackexchange.com/a/87189/52763 . Và đây thực sự là những gì tôi muốn. Vấn đề là, khi tôi kiểm tra thiết bị trong gparted, tôi nhận được Couldn't find valid filesystem superblock.. Đây là pic: i.imgur.com/dl7XAC4.png . Đây có phải là một loại lỗi không?
Mikhail Morfikov

Câu trả lời:


13

Bạn có thể truy cập hình ảnh đĩa và các phân vùng riêng lẻ thông qua tính năng loopback. Bạn đã phát hiện ra rằng một số tiện ích đĩa sẽ hoạt động (một cách hợp lý) một cách vui vẻ trên ảnh đĩa. Tuy nhiên, mkfskhông phải là một trong số họ (nhưng kỳ lạ mountlà).

Đây là đầu ra từ 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

Để truy cập vào phân vùng bạn đã tạo, bạn có một vài lựa chọn

  1. Lộ trình rõ ràng

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

    Đầu ra /dev/loop0là tên của thiết bị lặp đã được phân bổ. Các --offsettham số được chỉ phân vùng bù đắp ( Start) nhân với kích thước khu vực ( 512). Trong khi đó --sizelimitlà kích thước của phân vùng và bạn có thể tính toán nó theo cách sau: End-Start + 1, là 819199-2048 + 1 = 817152, và con số đó cũng phải được nhân với kích thước của khu vực.

    Sau đó, bạn có thể sử dụng /dev/loop0làm tài liệu tham khảo cho phân vùng:

    mkfs -t ext4 -L img1 /dev/loop0
    mkdir -p /mnt/img1
    mount /dev/loop0 /mnt/img1
    ...
    umount /mnt/img1
    losetup -d /dev/loop0
    
  2. Tuyến đường ngầm

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

    Đầu ra /dev/loop0là tên của thiết bị vòng lặp chính đã được phân bổ. Ngoài ra, --partscantùy chọn yêu cầu kernel quét thiết bị cho bảng phân vùng và tự động gán các thiết bị vòng lặp phụ. Trong trường hợp của bạn với một phân vùng bạn cũng nhận được /dev/loop0p1, sau đó bạn có thể sử dụng làm tham chiếu đến phân vùng:

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

@Mikhail tò mò muốn xem bạn đã tính kích thước phân vùng khi nó đã được cung cấp như một phần của fdiskđầu ra.
roaima

2
Có gì sai với một số môn toán? Bên cạnh đó, thật tốt khi biết rằng bạn có thể dễ dàng lấy đúng số ngành theo cách đó, chỉ trong trường hợp ...
Mikhail Morfikov

Chỉ cần quan sát nhanh: "mkfs frontend không được ủng hộ cho mkfs cụ thể của hệ thống tập tin. <Type> utils", trích dẫn từ mkfs man-page.
gmagno

@gmagno bây giờ đúng rồi. Nhưng theo như tôi có thể xác định mà không cần đào quá lâu hoặc quá khó, thông báo đó chỉ được phát hành lần đầu tiên với chương trình linux-linux 2.25-rc1 và điều đó đã không ổn định với Debian cho đến một thời gian sau tháng 6 năm 2015. Hãy thoải mái để cập nhật câu trả lời với thông tin hiện tại mặc dù.
roaima

11

Có một cách khác để làm điều này nói chung, sử dụng kpartx( không liên quan đến kde)

sudo kpartx -a binary.img

và bây giờ bạn nên có tất cả các thiết bị phân vùng được định nghĩa dưới /dev/mapperdạng loop0p1 , loop0p2 , ...

và sau đó

sudo mkfs.ext4 /dev/mapper/loop0p1

Tùy chọn, khi bạn hoàn thành, bạn cũng có thể chạy

sudo kpartx -d binary.img

để thoát khỏi loop0p? deivce


2
Không chắc chắn tại sao điều này không có nhiều phiếu hơn. IMO đó là câu trả lời tốt nhất ...!
Jeremy Davis

Hoạt động với các phân vùng GPT, ví dụ, nếu bạn muốn sửa đổi phân vùng EFI khỏi toàn bộ dd đĩa.
Nga

3

Tôi không biết tại sao nó lại tìm binary.img1

(Hoài và sau này cho binary.img2chôn trong bình luận.)

Đó là bởi vì các công cụ đang mong đợi tên tệp theo một mẫu cụ thể. Mẫu đó là mẫu được sử dụng bởi các tệp thiết bị cho các đĩa và khối lượng đĩa thực trên hệ thống của bạn, cụ thể là:

  • Một tập tin thiết bị bao gồm toàn bộ đĩa được đặt tên sda(hoặc một cái gì đó khác). Đây là những gì fdiskmong đợi để sử dụng.
  • Tập tin thiết bị cho lát cá nhân của đĩa, được mô tả bởi sự phân tán của nó, được đặt tên sda1, sda2, sda3, và vân vân. Đây là những gì các công cụ như gpartedmong đợi sẽ sử dụng khi họ nói mkfsđể làm mọi thứ trên khối lượng đĩa riêng lẻ .

Tất nhiên, các tệp thông thường không trùng lặp theo cách mà các tệp thiết bị đĩa làm. Các cuộc thảo luận liên quan đến hệ thống tập tin loopback mà bạn đã thấy là tất cả về tham gia một tập tin hình ảnh toàn bộ đĩa đơn và sử dụng loopback để tạo 1, 2, 3, và vân vân file mà phản ánh những lát cá nhân bên trong nó, một khi bố trí phân vùng mong muốn đã được viết đến bảng phân vùng.


Điều đó có ý nghĩa!
Mikhail Morfikov

0

Mặc dù chủ đề này không liên quan trực tiếp, nhưng nó đề cập đến rất nhiều thông tin tương tự và liên quan.

Debian wiki | Raspberry Pi và qemu-user-static

Nếu bạn không thể sử dụng aptđể cài đặt một số lệnh được đề cập trong bài viết này, hãy thử sử dụng apt-cache search [package_name]. Điều này có thể không bật lên bất kỳ kết quả nào nếu lệnh xuất phát từ một gói có tên khác.

Ví dụ, losetuptrước đây có thể được cài đặt như đang losetupsử dụng apt install losetup, nhưng giờ đây nó là một phần của util-linuxkho lưu trữ của Ubuntu. Cách bạn tìm ra gói nào đóng vai trò là bộ chứa cho gói khác, bạn phải sử dụng tìm kiếm cho kho lưu trữ trực tuyến để phân phối Linux cho bạn. Hoặc, nếu bạn phải cài đặt nó từ một nguồn khác, hãy sử dụng công cụ tìm kiếm Web.

Một số gói đáng để kiểm tra ...

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

Mỗi bản phân phối Linux cũng có các trang trực tuyến riêng. Đôi khi nó dễ sử dụng các trang hơn là một hướng dẫn. Các trang hướng dẫn cũng sẽ cho bạn biết tất cả các tùy chọn lệnh và tham số. Một hướng dẫn thường sẽ chỉ tập trung vào những người được sử dụng.


0

Tối thiểu Runnable sfdisk+ mke2fsví dụ mà khôngsudo

Trong ví dụ này, chúng tôi sẽ tạo, không có sudohoặc setsuid, một tệp hình ảnh có chứa hai phân vùng ext2, mỗi phân vùng chứa các tệp từ một thư mục máy chủ.

Sau đó, chúng tôi sẽ sử dụng sudo losetupchỉ để gắn kết các phân vùng để kiểm tra xem nhân Linux có thực sự có thể đọc chúng như được giải thích tại: /programming/1419361/how-to-mount-one-partition-from-an-image -file-that-chứa-nhiều phân vùng / 39675265 # 39675265

Để biết thêm chi tiết, xem:

Ví dụ:

#!/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"

Đã thử nghiệm trên Ubuntu 18.04. GitHub ngược dòng .

Trợ giúp để bọc một tệp hệ thống tệp thô hiện có thành một hình ảnh

Trích xuất từ ​​trên, sau đây có thể hữu ích:

# 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 ngược dòng .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.