จะฟอร์แมตพาร์ติชั่นภายในไฟล์ 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

และสมมุติว่าหนึ่งพาร์ติชัน:

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
ทางเลือกหนึ่งคือทำเคล็ดลับ losetup จากคำตอบนี้แล้วเรียกใช้ mkfs.ext4 กับอุปกรณ์ลูปแบ็ค
Miikka

ฉันได้พบลิงค์นี้unix.stackexchange.com/a/87189/52763 และนี่คือสิ่งที่ฉันต้องการ ปัญหาคือเมื่อตรวจสอบอุปกรณ์ใน GParted Couldn't find valid filesystem superblock.ฉันได้รับ นี่คือรูป: i.imgur.com/dl7XAC4.pngนี่เป็นข้อผิดพลาดบางอย่างหรือไม่?
Mikhail Morfikov

คำตอบ:


13

คุณสามารถเข้าถึงดิสก์อิมเมจและแต่ละพาร์ติชันผ่านคุณสมบัติลูปแบ็ค คุณได้ค้นพบแล้วว่ายูทิลิตี้ของดิสก์บางตัวจะทำงาน (อย่างสมเหตุสมผล) อย่างมีความสุขบนภาพดิสก์ อย่างไรก็ตาม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
    

@ Mikail อยากรู้อยากเห็นเพื่อดูว่าคุณคำนวณขนาดพาร์ติชันเมื่อมันได้รับเป็นส่วนหนึ่งของการfdiskส่งออกแล้ว
roaima

2
มีอะไรผิดปกติกับคณิตศาสตร์บ้าง? นอกจากนี้ยังเป็นเรื่องดีที่จะรู้ว่าคุณสามารถรับหมายเลขเซกเตอร์ที่ถูกต้องได้อย่างง่ายดายในกรณี ...
Mikhail Morfikov

เพียงสังเกตอย่างรวดเร็ว: "ส่วนหน้า mkfs ถูกคัดค้าน mkfs เฉพาะระบบแฟ้ม <type> utils" ซึ่งอ้างอิงจาก mkfs man-pages
gmagno

@ gmagno ที่ถูกต้องตอนนี้อย่างแน่นอน แต่เท่าที่ฉันสามารถตรวจสอบได้โดยไม่ต้องขุดนานเกินไปหรือยากเกินไปการประกาศนั้นได้รับการปล่อยตัวครั้งแรกกับ util-linux 2.25-rc1 เท่านั้นและนั่นก็ไม่ได้เข้าสู่ Debian เสถียรจนกว่าจะผ่านไปสักพักหลังจากมิถุนายน 2015 เพื่ออัพเดทคำตอบด้วยข้อมูลปัจจุบันแม้ว่า
roaima

11

มีวิธีอื่นในการทำเช่นนี้โดยทั่วไปใช้kpartx( ไม่เกี่ยวข้องกับ KDE)

sudo kpartx -a binary.img

และตอนนี้คุณควรมีอุปกรณ์พาร์ทิชันทั้งหมดที่กำหนดไว้ภายใต้/dev/mapperเป็นloop0p1 , loop0p2 , ...

แล้ว

sudo mkfs.ext4 /dev/mapper/loop0p1

Optionnaly เมื่อคุณทำเสร็จแล้วคุณสามารถเรียกใช้

sudo kpartx -d binary.img

การกำจัด loop0p deivce


2
ไม่แน่ใจว่าทำไมจึงไม่มีคะแนนมากกว่านี้ IMO มันเป็นคำตอบที่ดีที่สุด ... !
Jeremy Davis

ทำงานร่วมกับพาร์ติชัน GPT เช่นหากคุณต้องการแก้ไขพาร์ติชัน EFI จากดิสก์ทั้งวัน
Russ

3

ฉันไม่รู้ว่าทำไมมันถึงมองหา binary.img1

(…และต่อมาเนื่องจากbinary.img2ถูกฝังในคำอธิบาย)

นั่นเป็นเพราะเครื่องมือคาดหวังว่าชื่อไฟล์จะเป็นไปตามรูปแบบเฉพาะ รูปแบบนั้นเป็นรูปแบบที่ใช้โดยไฟล์อุปกรณ์สำหรับดิสก์จริงและดิสก์ไดรฟ์ในระบบของคุณ ได้แก่ :

  • มีการตั้งชื่อไฟล์อุปกรณ์ที่ครอบคลุมดิสก์ทั้งหมดsda(หรืออย่างอื่น) นี่คือสิ่งที่fdiskคาดว่าจะใช้
  • แฟ้มอุปกรณ์สำหรับแต่ละชิ้นของแผ่นดิสก์อธิบายโดยแบ่งพาร์ทิชันของมันจะถูกตั้งชื่อsda1, sda2, sda3และอื่น ๆ นี่คือสิ่งที่เครื่องมือเช่นgpartedคาดหวังที่จะทำให้การใช้งานเมื่อพวกเขาบอกmkfsจะทำสิ่งที่อยู่ในไดรฟ์ดิสก์ของแต่ละบุคคล

แน่นอนว่าไฟล์ทั่วไปจะไม่ทับซ้อนกันในลักษณะที่ไฟล์ดิสก์ทำ การอภิปรายที่เกี่ยวข้องกับระบบแฟ้มย้อนกลับที่คุณได้เห็นทั้งหมดเกี่ยวกับการไฟล์ภาพทั้งแผ่นเดียวและการใช้ย้อนกลับในการสร้าง1, 2, 3และอื่น ๆ ไฟล์ที่สะท้อนถึงแต่ละชิ้นอยู่ภายในเมื่อรูปแบบพาร์ทิชันที่ต้องการได้รับการเขียน ไปยังตารางพาร์ทิชัน


นั่นทำให้รู้สึก!
Mikhail Morfikov

0

แม้ว่าหัวข้อนี้จะไม่เกี่ยวข้องโดยตรง แต่ก็กล่าวถึงข้อมูลเดียวกันและที่เกี่ยวข้องมากมาย

Debian wiki | ราสเบอร์รี่ Pi และ qemu ผู้ใช้แบบคงที่

ถ้าคุณไม่สามารถใช้ในการติดตั้งบางส่วนของคำสั่งที่ระบุไว้ในโพสต์นี้ให้ลองใช้apt apt-cache search [package_name]สิ่งนี้อาจไม่ปรากฏผลลัพธ์ใด ๆ หากคำสั่งมาจากแพ็คเกจที่มีชื่อแตกต่างกัน

ยกตัวอย่างเช่นlosetupอาจเคยติดตั้งเป็นการlosetupใช้apt install losetupแต่ตอนนี้มันเป็นส่วนหนึ่งของที่util-linuxเก็บของอูบุนตู วิธีที่คุณค้นหาว่าแพ็คเกจใดที่ทำหน้าที่เป็นคอนเทนเนอร์สำหรับแพ็คเกจอื่นคุณต้องใช้การค้นหาที่เก็บออนไลน์สำหรับการแจกจ่าย Linux ของคุณ หรือถ้าคุณต้องติดตั้งจากแหล่งอื่นให้ใช้ Web search engine

แพคเกจบางอย่างควรค่าแก่การตรวจสอบ ...

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

การแจกจ่าย Linux ทุกครั้งนั้นมี manpages ออนไลน์ด้วยเช่นกัน บางครั้งการใช้ manpages ง่ายกว่าการสอน หน้าคู่มือจะบอกให้คุณทราบถึงตัวเลือกคำสั่งและพารามิเตอร์ทั้งหมด โดยทั่วไปแล้วการสอนจะเน้นเฉพาะสิ่งที่ใช้


0

ตัวอย่างsfdisk+ ที่รันได้น้อยที่สุดmke2fsโดยไม่มีsudo

ในตัวอย่างนี้เราจะสร้างโดยไม่ต้องsudoหรือ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"

ทดสอบบน Ubuntu 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 ต้นน้ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.