“调整” .img 的大小以适应较小的 SD 卡。如何缩小可启动 SD 卡映像

“调整” .img 的大小以适应较小的 SD 卡。如何缩小可启动 SD 卡映像

语境

我有一张 16 GB 的 SD 卡,上面装有基于 Linux 的 Raspberry Pi 操作系统。大部分空间都是空的。

我想与其他人共享 SD .img,但如果我使用命令

dd if=/dev/sdXX of=/home/user123/SD.img

它将创建一个 16 GB 的图像。太大了。

问题

我怎样才能将 16GB SD 卡图像调整为更小的 4GB?

我已尝试使用 GParted:它可以毫无问题地创建一个 4GB 的分区,但是整个.imgSD 卡仍然为 16 GB,其中有 12 GB 未分配空间。

GParted 表

我已阅读问题和答案在 Ubuntu 中克隆多个分区,但我仍然无法将 16GB SD 卡重新调整为 4GB 卡。

更多信息

~$ lsblk 
...

sdc      8:32   1  14,9G  0 disk 
├─sdc1   8:33   1   100M  0 part 
└─sdc2   8:34   1     4G  0 part 
~$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 14,9 GiB, 15931539456 bytes, 31116288 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: 0xf8a631ce

Device     Boot  Start     End Sectors  Size Id Type
/dev/sdc1  *      2048  206847  204800  100M  c W95 FAT32 (LBA)
/dev/sdc2       206848 8595455 8388608    4G 83 Linux

任何建议都值得感激!

请注意:正如梅勒比乌斯所观察到的一条评论,正确的用词是收缩

不能调整 SD 卡的大小,因为它是具有给定容量的硬件,无法更改。您显然想缩小 SD 卡图像

答案1

本文给出了解决我的问题的解决方案 (*)。它与另一个非常相似,但它更好地解释了如何计算以及数字和分区的含义。

关键信息是命令的使用truncate。遵循完整的解决方案以免丢失答案。

初步步骤包括在您的 PC 上克隆 SD 卡:

  1. 用于lsblk查看哪些设备可用以及它们的分区是否已挂载

  2. 卸载您要在电脑上复制的设备的所有分区。例如:

     umount /dev/sdc1
     umount /dev/sdc2
    
  3. 创建整个 SD 卡的副本,并卸载所有分区

     dd if=/dev/sdc of=/path/to/file/myimage.img
    

在 Linux 上缩小图像

问题背景

具有myimage.img比硬件支持更大的尺寸(如果尺寸较小则应该没有问题;但是,使用相同的策略,您可以更好地将图像放入硬件支持中)。

秘诀是使用标准 Linux 工具和仪器:GPartedfdisktruncate

要求

  • Linux 电脑
  • .img想要缩小的(myimage.img在此示例中)

创建环回设备

GParted 是一款通常用于管理分区表和文件系统的应用程序。为了收缩图像,GParted 将在答案的第一部分中使用。

GParted 操作的是设备,而不是图像等简单文件。这就是为什么我们首先需要为图像创建一个设备。我们使用 Linux 的环回功能来做到这一点。

让我们启用环回:

sudo modprobe loop

让我们请求一个新的(免费)环回设备:

sudo losetup -f

该命令返回空闲环回设备的路径:

/dev/loop0

让我们创建一个图像的设备:

sudo losetup /dev/loop0 myimage.img

该设备/dev/loop0代表myimage.img。我们想要访问映像上的分区,因此我们需要让内核也加载这些分区:

sudo partprobe /dev/loop0

这应该会给我们设备/dev/loop0p1,它代表中的第一个分区myimage.img。我们不需要直接使用此设备,但 GParted 需要它。

使用 GParted 调整分区大小

让我们使用 GParted 加载新设备:

sudo gparted /dev/loop0

当 GParted 应用程序打开时,它应该出现类似以下内容的窗口:

截屏

现在请注意以下几点:

  • 有一个分区。
  • 分区分配整个磁盘/设备/图像。
  • 分区已部分填充。

我们希望调整此分区的大小以适合其内容,但不能超过这个大小。

选择分区并点击调整大小/移动。将弹出类似以下的窗口:

对话框截图

尽可能将右侧栏拖到左侧。

请注意,有时 GParted 需要额外的几 MB 空间来放置一些与文件系统相关的数据。您可以按几次新大小框上的向上箭头来执行此操作。例如,我按了 10 次(=10MiB)以使 FAT32 正常工作。对于 NTFS,您可能根本不需要这样做。

最后按“调整大小/移动”。您将返回到 GParted 窗口。这次它看起来类似于以下内容:

右侧未分配的空间

请注意,磁盘中有一部分未分配。分区不会使用磁盘的这一部分,因此我们可以稍后从映像中删除这一部分。GParted 是一个磁盘工具,因此它不会缩小映像,只会缩小分区,我们必须自己缩小映像。

按下ApplyGParted。它现在将移动文件并最终缩小分区,因此可能需要一两分钟,但大多数情况下它会很快完成。然后关闭 GParted。

现在我们不再需要环回设备,因此卸载它:

sudo losetup -d /dev/loop0

削减图像

现在我们已经在映像的开头有了所有重要的数据,是时候删除未分配的部分了。我们首先需要知道分区在哪里结束以及未分配部分在哪里开始。我们使用以下命令执行此操作fdisk

fdisk -l myimage.img

在这里我们将看到类似以下内容的输出:

Disk myimage.img: 6144 MB, 6144000000 bytes, 12000000 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
Disk identifier: 0x000ea37d

      Device Boot      Start         End      Blocks   Id  System
myimage.img1            2048     9181183     4589568    b  W95 FAT32

请注意输出中的两件事:

  • 分区结束于块 9181183(如下所示End
  • 块大小为 512 字节(显示为 扇区1 * 512

我们将在示例的其余部分使用这些数字。块大小 (512) 通常相同,但结束块 (9181183) 会有所不同。这些数字表示分区以字节 9181183 结束512 字节。该字节之后是未分配部分。只有前 9181183512 字节对于我们的图像很有用。

接下来,我们将映像文件缩小到刚好可以包含分区的大小。为此,我们将使用命令truncate(感谢 uggla!)。使用 truncate 命令需要提供文件的大小(以字节为单位)。最后一个块是 9181183,块号从 0 开始。这意味着我们需要 (9181183+1)*512 字节。这很重要,否则分区将不适合映像。所以现在我们使用 truncate 并进行计算:

truncate --size=$[(9181183+1)*512] myimage.img

(*)FrozenCow 的原始帖子似乎已被移动这里

答案2

所选答案完全适用于系统disklabel 类型。对于谷氨酰胺磷酸酶类型,需要考虑添加 33 个扇区,因为 GPT 也在磁盘末尾存储了一个表。

因此对于 GPT 用户来说,“截断”命令需要如下所示:

截断 --size=$[(最后一个分区结束+1+33)*512]我的图片.img

这应该会在 中产生 GPT 错误fdisk -l。要修复此问题,请运行以下命令:

gdisk myimage.img

运行命令来验证磁盘: v。您应该会看到磁盘上发现一些错误。

“在 gdisk 中,你可以输入X进入专家菜单,然后输入将备份分区表数据移动到磁盘的新末尾,然后输入将更改写入磁盘。”[来源]如何在不破坏 GPT 分区表(结束指针)的情况下截断磁盘映像文件中未使用的空间- 谢谢!

答案3

我浏览了这里的许多方法,并理解了它们,但我并不想按顺序执行这些步骤,只是为了缩小 Raspberry Pi IMG 文件。因此,我偶然发现了一个 Bash 脚本,它来自一个名为PiShrink

执行起来非常简单,并且可以在我的 MacOS M1 Mac Mini 上启动。

背景故事

在我的特殊情况下,我有 2 张 32GB SD 卡,不知什么原因,1 张比另一张小一点(约 95MB),balena蚀刻机拒绝将 IMG 从 2 张 SD 卡中较大的一张写入较小的一张。

我知道我只使用了 32GB 中的约 10GB,因此我可以将 IMG 文件缩小到适合的大小。

脚步

首先,我有以下文件。文件.zip包含文件.img,但我在下面显示的是解压后的文件。

$ ls -lh | grep -E 'img|zip'
-rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
--w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img

然后我下载了 PiShrink shell 脚本并使其可执行:

$ wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
$ chmod +x pishrink.sh

然后我像这样运行它:

$ sudo pishrink disk.img pi.img
Copying disk.img to pi.img...
e2fsck 1.44.0 (7-Mar-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
STORAGE: 69402/7684096 files (0.2% non-contiguous), 9562823/30732288 blocks
resize2fs 1.44.0 (7-Mar-2018)
resize2fs 1.44.0 (7-Mar-2018)
Resizing the filesystem on /dev/disk4s2 to 9273700 (1k) blocks.
Begin pass 2 (max = 245358)
Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 3752)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 3420)
Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/disk4s2 is now 9273700 (1k) blocks long.

"disk4" ejected.
fdisk: could not open MBR file /usr/standalone/i386/boot0: No such file or directory
Enter 'help' for information
fdisk: 1>          Starting       Ending
 #: id  cyl  hd sec -  cyl  hd sec [     start -       size]
------------------------------------------------------------------------
 2: 83 1023   3  32 - 1023 254   2 [   1056768 -   61464576] Linux files*
Partition id ('0' to disable)  [0 - FF]: [83] (? for help) Do you wish to edit in CHS mode? [n] Partition offset [0 - 62521344]: [1056768] Partition size [1 - 61464576]: [61464576] fdisk:*1> Writing MBR at offset 0.
fdisk: 1> Shrunk pi.img from 30G to 9.3G

生成的 IMG 文件现在约为 9GB。

$ ls -lh | grep -E 'img|zip'
-rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
--w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img
--w---x---  1 root staff 9.4G Jan 29 17:04 pi.img

然后我将其重新打包为 ZIP 文件,以便在磁盘上处理时保持最有效的大小。

$ sudo zip pi.zip pi.img

我们现在有以下一组文件:

$ ls -lh | grep -E 'img|zip'
-rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
--w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img
--w---x---  1 root staff 9.4G Jan 29 17:04 pi.img
-rw-r--r--  1 root staff 8.3G Jan 29 17:08 pi.zip

然后我可以使用balena蚀刻机或者ApplePi-Baker将 ZIP 文件刻录到“较小”的 SD 卡。

ss01

查看我的 Mac 上的 SD 卡时,我看到它显示约 10GB。

$ diskutil list /dev/disk4
/dev/disk4 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.9 GB    disk4
   1:             Windows_FAT_32 LIBREELEC               536.9 MB   disk4s1
   2:                      Linux                         10.0 GB    disk4s2
                    (free space)                         21.3 GB    -

笔记:我可以使用 etc. 从 Linux 系统执行相同的命令lsblk

术后

使用上述方法后,我确实注意到 SD 卡内的文件系统在 32GB 上不够用。主要表现如下:

$ df -h | grep -E "File|mmc"
Filesystem                Size      Used Available Use% Mounted on
/dev/mmcblk0p1          511.7M    141.7M    370.0M  28% /flash
/dev/mmcblk0p2            8.6G      8.2G    377.4M  96% /storage

重新启动后,通过从内部扩展 SD 文件系统应该可以轻松解决这个问题。

首先我使用以下命令parted来扩展分区:

$ parted /dev/mmcblk0 resizepart 2 100%
Warning: Partition /dev/mmcblk0p2 is being used. Are you sure you want to
continue?
Yes/No? yes
yes
Information: You may need to update /etc/fstab.

然后我重新启动了系统:

$ reboot

之后我使用以下命令在线扩展了文件系统resize2fs

$ resize2fs /dev/mmcblk0p2
resize2fs 1.45.6 (20-Mar-2020)
Filesystem at /dev/mmcblk0p2 is mounted on /storage; on-line resizing required
old_desc_blocks = 71, new_desc_blocks = 234
The filesystem on /dev/mmcblk0p2 is now 30638592 (1k) blocks long.

现在显示 SD 卡上的所有可用空间:

$ df -h | grep -E "File|mmc"
Filesystem                Size      Used Available Use% Mounted on
/dev/mmcblk0p1          511.7M    141.7M    370.0M  28% /flash
/dev/mmcblk0p2           28.3G      8.2G     20.1G  29% /storage

答案4

resize2fs也可以用来调整大小。

sudo resize2fs -fp SD.img 4G

它还可以调整文件本身的大小!

相关内容