缩小总磁盘映像:UEFI GPT Flashdrive - 末尾有可用空间

缩小总磁盘映像:UEFI GPT Flashdrive - 末尾有可用空间

我有一个来自可启动闪存驱动器的磁盘映像。它是用于 EFI 启动的 GPT,因此有一个小的 Vfat32 分区和另外三个 Linux 分区,后面还有大约 3G 的可用空间。

我需要将磁盘映像复制到稍小的闪存驱动器,因此我需要将空间从 15G 缩小到 14G 左右。我将在 Linux 上使用 dd 进行复制。

gparted 非常适合修改和调整分区大小,但它无法缩小最后的可用空间。理论上应该可以截断文件,但当我尝试时,它会炸毁(“磁盘表”?猜测),因此没有分区,文件被毁了。我很确定如果我使用旋转磁盘和/或 MBR 磁盘,下面的技术会起作用,但我没有测试过。

尝试过:

dd bs=1M count=14000 iflag=fullblock if=/dev/sda  of=myfile.raw

没有缩水

rsync --sparse filename filename 

这并没有破坏磁盘表,但缩小了交换空间并保留了未分配区域。

qemu-img convert -f raw -O qcow2 -S 4k filename filename (计划转换回原始)

炸毁桌子

truncate size=140000M <filename>

还炸毁了桌子

cp --sparse=always filename filename

没有用

答案1

所创建的原始文件的开头应该有一个主 GUID 分区表,结尾应该有一个辅助(备份)GUID 分区表dd。截断文件会破坏辅助 GUID 分区表。有一种方法可以修复它。

让我们从未截断且末尾有可用空间的文件开始。运行gdisk -l myfile.raw。注意逻辑扇区大小(可能512B,或可能4096B)。找到最大末端区域(可能是最后一个分区的分区,但分区条目可能按顺序排列,也可能不按顺序排列,因此请仔细查找最大的分区)。扇区从 开始编号0,因此您需要(扇区大小)*(最大末端扇区+1)字节来存储所有分区。

此外,您最后还需要至少 33 个完整的可用空间扇区来存储新的辅助 GPT。请参阅这张图片来自维基百科

总共你需要(扇区大小)*(最大末端扇区+ 34) 字节的文件。将文件截断为以下大小或更大的大小:

truncate -s <new_size> myfile.raw

下次调用

gdisk myfile.raw

您将获得(除其他外):

警告!磁盘大小小于主标头指示的大小!
注意:备份 GPT 标头无效,但主标头有效;从主标头重新生成备份标头。

键入w,点击Enter写入正确的分区表。您将看到警告,因为次要 GPT 即将移动。文件末尾有足够的可用空间,因此无需担心。询问时确认。

使用q,退出Enter。再次运行gdisk– 应该不会有任何警告。GPT 已修复


如果您需要使用gparted您的图像,我有一些提示。

该命令sudo gparted myfile.raw要求文件myfile.raw1myfile.raw2存在并与 内的分区相对应myfile.raw。如果是特殊文件,/dev/sdbudev需要处理/dev/sdb1/dev/sdb2… 常规文件则不是这种情况。gparted如果没有myfile.rawN文件,许多功能将失败。

要创建此类文件,请使用kpartx(或partx+losetup串联):

sudo kpartx -av myfile.raw

观察其输出(loopXpY创建了哪些设备)并创建指向所有分区的符号链接。第一个可能是:

ln -s /dev/mapper/loop0p1 myfile.raw1

现在gparted应该运行并操作这些分区。但是有一个陷阱:当分区发生变化(例如,移动/调整大小)时,由 创建的映射kpartx不会更新。通常gparted会调用partprobe或其他东西来更新/dev/sd*;这在我们的例子中不起作用。您应该销毁映射并重新创建它们。在移动/调整分区大小时,运行一个gparted任务,关闭程序,修复映射,运行gparted第二个任务,依此类推。

要销毁映射,请调用sudo kpartx -dv myfile.raw。删除最后的孤立符号链接。

相关内容