为较小的 SD 卡“重新调整大小” .img。如何缩小可启动的 SD 卡映像

Leo*_*313 18 partitioning resize dd sd-card disk-image

语境

我有一个 16 GB SD 卡,带有用于 Raspberry Pi 的基于 Linux 的操作系统。大部分空间都是空的。

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

dd if=/dev/sdXX of=/home/user123/SD.img
Run Code Online (Sandbox Code Playgroud)

它将创建一个 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 
Run Code Online (Sandbox Code Playgroud)
~$ 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
Run Code Online (Sandbox Code Playgroud)

任何建议表示赞赏!

请注意:正如 Melebius 在评论中所观察到的,正确使用的词是shrink

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

Leo*_*313 22

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

关键信息是命令的使用truncate。为了不丢失答案,请遵循完整的解决方案。

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

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

  2. 卸载要复制到 PC 上的设备的所有分区。例如:

    umount /dev/sdc1
    umount /dev/sdc2
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建整个 SD 卡的副本,并卸载所有分区

    dd if=/dev/sdc of=/path/to/file/myimage.img
    
    Run Code Online (Sandbox Code Playgroud)

在 Linux 上缩小图像

问题的背景

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

秘诀是使用标准的 Linux 工具和工具:GPartedfdisktruncate.

要求

  • 一台 Linux 电脑
  • .img要收缩(myimage.img在这个例子中)

创建环回设备

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

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

让我们启用启用环回:

sudo modprobe loop
Run Code Online (Sandbox Code Playgroud)

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

sudo losetup -f
Run Code Online (Sandbox Code Playgroud)

该命令返回自由环回设备的路径:

/dev/loop0
Run Code Online (Sandbox Code Playgroud)

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

sudo losetup /dev/loop0 myimage.img
Run Code Online (Sandbox Code Playgroud)

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

sudo partprobe /dev/loop0
Run Code Online (Sandbox Code Playgroud)

这应该给我们设备/dev/loop0p1,它代表myimage.img. 我们并不直接需要这个设备,但是 GParted 需要它。

使用 GParted 调整分区大小

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

sudo gparted /dev/loop0
Run Code Online (Sandbox Code Playgroud)

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

截屏

现在注意几点:

  • 有一个分区。
  • 该分区分配整个磁盘/设备/映像。
  • 分区被部分填充。

我们想调整这个分区的大小,使其适合它的内容,但不能更多。

选择分区并单击调整大小/移动。会弹出类似如下的窗口:

对话框截图

尽可能向左拖动右侧栏。

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

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

右侧未分配空间

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

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

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

sudo losetup -d /dev/loop0
Run Code Online (Sandbox Code Playgroud)

剃须图像

现在我们在图像的开头拥有了所有重要的数据,是时候去除未分配的部分了。我们首先需要知道我们的分区在哪里结束以及未分配部分从哪里开始。我们使用fdisk

fdisk -l myimage.img
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

请注意输出中的两件事:

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

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

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

truncate --size=$[(9181183+1)*512] myimage.img
Run Code Online (Sandbox Code Playgroud)

  • Ask Ubuntu 站点的质量标准意味着仅链接的答案不够好。答案应包含基本说明,以便人们可以在不参考原始来源的情况下使用它们。然而,这并不意味着人们不应该尊重版权法。我建议用你自己的话来描述必须要做的事情。 (2认同)
  • 换句话说,我将重写测试以提出相同的解决方案。但是我插入了链接和作者的名字,以避免每一个“误解”。我不是作者 (2认同)
  • ...一点一点更新:) (2认同)

mp3*_*p3k 5

所选答案完全适用于dos disklabel 类型。对于GPT类型,需要考虑添加33个扇区,因为GPT也在磁盘的末尾存储一张表。

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

截断 --size=$[( End_of_last_partition + 1 + 33 )*512] myimage.img

这应该会在fdisk -l. 要解决此问题,请运行以下命令:

gdisk myimage.img
Run Code Online (Sandbox Code Playgroud)

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

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