如何创建具有大分区的小磁盘映像

All*_*Kll 7 filesystems embedded ext4 ext3

我正在为嵌入式系统构建磁盘映像(放置在 4GB SD 卡上)。我希望系统有两个分区。一个“根”(200Mb) 和一个“数据”分区(800Mb)。

我用 dd 创建了一个空的 1GB 文件。然后我使用 parted 来设置分区。我将它们每个都安装在一个循环设备中,然后将它们格式化;ext2 代表“根” ext4 代表“数据”。将我的根文件系统添加到“Root”分区并将“Data”留空。

这就是问题所在。我现在被困在一个 1GB 的图像上,上面只有 200MB 的数据。理论上,我不应该能够将图像截断为 .. 201MB 并且仍然可以安装文件系统吗?不幸的是,我没有发现这种情况。

我记得过去曾使用过 Freescale 的构建环境,该环境用于创建 30Mb 图像,该环境将具有使用整个 4GB sdcard 的分区。不幸的是,此时,我无法找到他们是如何做到的。

我已经阅读了 ext 文件系统的磁盘格式,如果第一个超级块之后没有任何数据(备份超级块和未使用的块表除外),我想我可以在那里截断。

不幸的是,当我这样做时,安装系统吓坏了。然后我可以运行 FSCK,恢复超级块和块表,然后可以挂载它就没有问题了。我只是不认为那应该是必要的。

也许不同的文件系统可以工作?有任何想法吗?

谢谢,

编辑

更改分区以读取文件系统。分区仍然存在并且没有改变,但是截断图像后文件系统被破坏了。

编辑

我发现这种情况是,当我将文件截断到刚好大于第一组“数据”分区超级块和索引节点/块表的大小时,(在数据块范围内的某处)文件系统无需执行即可卸载一个 fsck 来恢复其余的超级块和块/inode 表

der*_*ert 6

最简单的方法是将您的后备文件创建为稀疏文件;也就是说,使用truncate -s 1G disk.img而不是dd if=/dev/zero bs=1048576 count=1024 of=disk.img(或其他)使其成为 1GB 。很好,truncate也快得多。

如果您ls -l对该文件执行操作,它会显示为 1GB — 但这只是它的表观大小。du disk.img将给出实际尺寸。

(注意——你需要在支持稀疏文件的文件系统上保存你的映像。所有常见的 Unix 都可以。Ext2/3/4 都可以。FAT32 不行。HFS+ 也不行。)

注意:从逻辑上讲,稀疏文件仍然是完整大小。只是从未写过的部分没有物理存储在磁盘上。大多数情况下,未实际存储的部分对程序是隐藏的。不过,一些实用程序支持它。(例如,dd conv=sparsecp --sparse=auto/always等等)。一个实际的 USB 记忆棒不可能是稀疏的。如果您使用dd conv=sparse它来编写它,它可能会快得多,但是您将保留之前存在的任何数据,而不是预期的充满 NUL (0x00) 的块。应该可以正常工作(作为其可用空间),但会将旧数据留在 USB 记忆棒上——可能是一个安全问题。


mik*_*erv 5

首先,将稀疏图像写入磁盘不会导致任何结果,只会覆盖该图像文件的整个大小(孔和所有内容)覆盖磁盘。这是因为稀疏文件的处理是文件系统的一种特性,而原始设备(例如写入映像的设备)没有这样的东西。稀疏文件可以安全可靠地存储在由支持稀疏文件的文件系统(例如 ext4 设备)控制的介质上,但一旦您将其写出,它就会包含您想要的所有内容。所以你应该做的是:

  1. 只需将其存储在能够识别稀疏文件的文件系统上,直到您准备好写入它为止。

  2. 让它深两层...

    • 也就是说,将主映像写入文件,使用可以理解稀疏文件的 fs 创建另一个映像,然后将映像复制到映像,然后...

    • 当需要编写图像时,首先编写您的父图像,然后编写您的主图像。

以下是第 2 步的操作方法:

  • 创建一个 1GB 稀疏文件...

    dd bs=1kx1k seek=1k of=img </dev/null
    
    Run Code Online (Sandbox Code Playgroud)
  • 将两个ext4分区写入其分区表:1 200MB、2 800MB...

    printf '%b\n\n\n\n' n '+200M\nn\n' 'w\n\c' | fdisk img
    
    Run Code Online (Sandbox Code Playgroud)
  • 在分配的循环设备上创建两个ext4文件系统-P,并将第二个文件系统的副本放在第一个文件系统上......

    sudo sh -c '
        for p in "$(losetup --show -Pf img)p"*        ### the for loop will iterate
        do    mkfs.ext4 "$p"                          ### over fdisks two partitions
              mkdir -p ./mnt/"${p##*/}"               ### and mkfs, then mount each
              mount "$p" ./mnt/"${p##*/}"             ### on dirs created for them
        done; sync; cd ./mnt/*/                       ### next we cp a sparse image
        cp --sparse=always "$p" ./part2               ### of part2 onto part1
        dd bs=1kx1k count=175 </dev/zero >./zero_fill ### fill out part1 w/ zeroes
        sync; cd ..; ls -Rhls .                       ### sync, and list contents
        umount */; losetup -d "${p%p*}"               ### last umount, destroy
        rm -rf loop*p[12]/ '                          ### loop devs and mount dirs
    
    Run Code Online (Sandbox Code Playgroud)
    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 204800 1k blocks and 51200 inodes
    Filesystem UUID: 2f8ae02f-4422-4456-9a8b-8056a40fab32
    Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 210688 4k blocks and 52752 inodes
    Filesystem UUID: fa14171c-f591-4067-a39a-e5d0dac1b806
    Superblock backups stored on blocks:
        32768, 98304, 163840
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    175+0 records in
    175+0 records out
    183500800 bytes (184 MB) copied, 0.365576 s, 502 MB/s
    ./:
    total 1.0K
    1.0K drwxr-xr-x 3 root root 1.0K Jul 16 20:49 loop0p1
       0 drwxr-xr-x 2 root root   40 Jul 16 20:42 loop0p2
    
    ./loop0p1:
    total 176M
     12K drwx------ 2 root root  12K Jul 16 20:49 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 20:49 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 20:49 zero_fill
    
    ./loop0p1/lost+found:
    total 0
    
    ./loop0p2:
    total 0
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在有很多输出 - 大部分来自mkfs.ext4- 但请特别注意ls底部的位。将显示磁盘上文件的ls -s实际-s大小- 并且它始终显示在第一列中。

  • 现在我们基本上可以将图像缩小到只有第一个分区......

    fdisk -l img
    
    Run Code Online (Sandbox Code Playgroud)
    Disk img: 1 GiB, 1073741824 bytes, 2097152 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: 0xc455ed35
    
    Device Boot  Start     End Sectors  Size Id Type
    img1          2048  411647  409600  200M 83 Linux
    img2        411648 2097151 1685504  823M 83 Linux
    
    Run Code Online (Sandbox Code Playgroud)
  • 告诉fdisk我们第一个分区中有 411647 +1 512 字节扇区img...

    dd seek=411648 of=img </dev/null
    
    Run Code Online (Sandbox Code Playgroud)
  • 这会将img文件截断为仅其第一个分区。看?

    ls -hls img
    
    Run Code Online (Sandbox Code Playgroud)
    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 21:37 img
    
    Run Code Online (Sandbox Code Playgroud)
  • ...但我们仍然可以挂载该分区...

    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 21:37 img
    
    Run Code Online (Sandbox Code Playgroud)
  • ...这是其内容...

    sudo mount "$(sudo losetup -Pf --show img)p"*1 ./mnt
    
    Run Code Online (Sandbox Code Playgroud)
    ls -hls ./mnt
    
    Run Code Online (Sandbox Code Playgroud)
  • 我们可以将第二个分区的存储图像附加到第一个分区......

    total 176M
     12K drwx------ 2 root root  12K Jul 16 21:34 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 21:34 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 21:34 zero_fill
    
    Run Code Online (Sandbox Code Playgroud)
    sudo sh -c '
        dd seek=411648 if=./mnt/part2 of=img
        umount ./mnt; losetup -D
        mount "$(losetup -Pf --show img)p"*2 ./mnt
        ls ./mnt; umount ./mnt; losetup -D'
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在我们的img文件已经增长了:它不再稀疏......

    1685504+0 records in
    1685504+0 records out
    862978048 bytes (863 MB) copied, 1.96805 s, 438 MB/s
    lost+found
    
    Run Code Online (Sandbox Code Playgroud)
    ls -hls img
    
    Run Code Online (Sandbox Code Playgroud)
  • ...但是第二次删除它和第一次一样简单,当然...

    1004M -rw-r--r-- 1 mikeserv mikeserv 1.0G Jul 16 21:58 img
    
    Run Code Online (Sandbox Code Playgroud)
    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 22:01 img
    
    Run Code Online (Sandbox Code Playgroud)