将空间未完全被利用的内存卡(含引导记录和系统分区)中的数据迁移至更小容量的内存卡中(同时保持系统盘之功能)
最近遇到一个如题的需求。有一个NVIDIA Jetson Nano的64 GB系统microSD卡(TF卡),其包含14个GPT分区,其中13个分区容量极小皆小于1 MB,一个分区容量大,总容量约32 GB。将使用Linux中的dd命令备份上述TF卡得到的镜像文件用于制作新的TF卡系统盘时发现:
1.新TF卡为32 GB是不可以的,因为镜像文件有64 GB,尽管其后半无分区,然而由于GPT备份分区表 (Secondary Header) 存在于原64 GB TF卡的最后一个扇区 (Last Sector) 即镜像文件的末尾,GPT备份分区表会丢失,以致新系统盘制作失败;
2.即使使用64 GB的新TF卡有时会因为新卡的容量略微小于原卡的容量而产生与上述相同的问题;
3.我们不得不使用128 GB的新TF卡根据备份镜像来制作新系统盘。
为了能够使用64 GB的TF卡来制作新系统盘,我的办法大致是在一张32 GB的TF卡上建立与原64 GB TF卡上的相同的分区表并逐分区将原64 GB卡上的内容复制至此32 GB卡上,用以此32 GB卡为源得到的备份镜像来制作新的系统盘。整个过程分为5步,以下详述。
一、用fdisk查看32 GB卡与原64 GB卡的信息
将两张TF卡都连接至Linux PC并于终端执行
sudo fdisk -l
可以列出连接至系统的所有磁盘的信息,根据容量确定两者的设备描述文件。在本例中32 GB TF卡的设备描述文件为/dev/sdb,64 GB TF卡的为/dev/sdc。执行
sudo fdisk -l /dev/sdb
仅查看32 GB TF卡的信息,如下图
可见这是一张空卡。执行
sudo fdisk -l /dev/sdc
仅查看64 GB TF卡的信息,如下图
可见其含有14个GPT分区,其中唯/dev/sdc1为大容量分区。
二、 用gparted缩减原64 GB卡上容量最大的分区
于上一步骤我们知道/dev/sdc1的容量为29.7 GiB,这超过了某些32 GB TF卡的总容量,虽然本例中的32 GB TF卡的容量为29.8 GiB足够大,然而为了针对读者使用欠容量32 GB TF卡或原64 GB卡上的/dev/sdc1分区更大(比如为48 GiB,而其中所有文件占用的空间仍小于29 GiB)时的情况在此我使用gparted缩减/dev/sdc1分区至29 GiB。执行
sudo apt install gparted
sudo umount /dev/sdc1
sudo gparted
安装gparted,取消挂载/dev/sdc1分区(不然只能扩展而不能缩减该分区)和启动gparted。gparted是一个GUI程序,于其中直观操作,结果如下图
gparted主要做啦两步操作:
1、调用resize2fs将文件系统的大小从29.71 GiB调整至29.00 GiB;
2、将分区容量调整至29.00 GiB。其中第一步改变啦文件分配表同时可能对某些文件在分区上的分布做啦调整,即将29.00 GiB至29.71 GiB之间的内容前移。第二步操作分区表将/dev/sdc1的容量设置为29.00 GiB,这一步可以手动地在fdisk或gdisk(下一步中即将介绍)中完成。
上图使用fdisk列出啦缩减分区容量后的64 GB卡的分区情况,相较与图2可见/dev/sdc1的大小确实改变啦。
三、用gdisk在32 GB卡上建立与原64 GB卡上的相同的分区表
安装gdisk
sudo apt-get install gdisk
安装完gdisk后执行
sudo gdisk /dev/sdc
以交互式运行gdisk于/dev/sdc,操作过程如下图示(图中的 Caution! Secondary header was placed beyond the disk’s limits! Moving the header, but other problems may occur! 表明GPT备份分区表的位置被从原卡末尾的64 GB调整为新卡末尾的32 GB。)
在上述流程后执行重启
sudo reboot
以使操作系统识别新的分区表。然后我们再次使用fdisk查看/dev/sdb并与图4比较可见在32 GB卡/dev/sdb上建立有与缩减分区容量后的64 GB卡/dev/sdc上的相同的GPT分区表,如下图
四、用dd逐分区将原64 GB卡上的内容复制至32 GB卡上
执行以下14条命令按分区备份原64 GB卡上的所有分区到文件
sudo dd if=/dev/sdc1 status=progress | gzip -c > 1.img.gz
…
sudo dd if=/dev/sdc14 status=progress | gzip -c > 14.img.gz
操作过程如下图
再执行以下14条命令从备份文件还原数据至32 GB卡上对应的分区
gunzip -c 1.img.gz | sudo dd of=/dev/sdb1 status=progress
…
gunzip -c 1.img.gz | sudo dd of=/dev/sdb1 status=progress
操作过程如下图
然后执行partprobe或reboot。如此我们已经制作完成新的32 GB Jetson Nano系统盘
五、根据32 GB卡得到备份镜像并以之制作新系统盘
接下来我们可以执行
sudo dd if=/dev/sdb status=progress | gzip -c > nano_backup.img.gz
将32 GB系统盘备份至文件nano_backup.img.gz,而后通过执行
gunzip -c nano_backup.img.gz | sudo dd of=/dev/sdd status=progress
从备份文件还原至未来的TF卡以制作更多的系统盘。此时我们可以使用64 GB的TF卡而不必不得已使用128 GB的TF卡。
如果此文章对您有所帮助而您又愿意赞助鼓励作者更好地去创作可以点击此处打赏作者