试想一个情景,当你开发完一个linux系统后,想要将其TF卡制作成img镜像来移植到其他TF卡上来实现大规模部署时,你选择将写有系统的TF卡插入读卡器,插入你的win10系统的电脑上,打开Win32DiskImager读取TF卡上的数据制作成img镜像后,你将另一张空的TF卡插入读卡器,使用Win32DiskImager将刚刚的img镜像写入这张TF卡时,极大概率会出现如下图所示的十分尴尬的错误。

 

linux做img镜像 linux写入img镜像_python

        让我们来分析一下这个错误产生的原因,这个img镜像需要124735488的空间,所选的TF卡可用的空间未122142720,换言之,也就是TF卡的容量小于镜像需要的容量。

        为什么会出现这种问题?其实很好理解,使用64G的卡做出来的镜像就是64G的,即便在Linux系统上通过dd制作成10几个G的tar文件,解压后还是64G的img镜像。目前市面上的TF卡质量参差不齐,目前实验室有四家不同品牌的TF卡,分别为实际内存容量为57.3GB的闪迪旗舰店的闪迪Ultra、59.2GB的海康威视旗舰店的闪迪Ultra、57.9GB的创乐博旗舰店的闪迪Ultra、58.2GB的金士顿旗舰店的SDCG3和59.3GB的三星存储旗舰店的EVO Plus,由于原先开发的Linux系统使用的是59.2GB的海康威视旗舰店的闪迪Ultra,故制作出来的img镜像实际大小为59.2GB,经测试,只有59.2GB的海康威视旗舰店的闪迪Ultra和59.3GB的三星存储旗舰店的EVO Plus可以正常进行写入。

        为此,本人在三天的不眠之夜中,分别尝试了Linux制作tar文件法、Linux备份镜像法、DiskGenius克隆分区法、DiskGenius压缩rootfs区法、DiskGenius更改原TF卡分区空间制作img镜像法、SDFormat覆盖式格式化法,均以失败告终。

        而今天,终于通过Linux分区法成功实现制作低容量img镜像的方法,下面是具体操作步骤。

        首先,我们将装有原系统的TF卡放入读卡器中,插入另一台装有linux系统的电脑(或树莓派皆可),本文以树莓派4B为例。

        首先,等待自动挂载完成,若未自动挂载,请根据其他文章的方法手动挂载。

        

linux做img镜像 linux写入img镜像_arm_02

         进入终端,输入sudo su以开启所有权限。

         随后输入df -h,查看挂载情况及可用空间。

linux做img镜像 linux写入img镜像_linux_03

        如图所示,/dev/sda2容量为54G,已使用15G,挂载地为/media/ubuntu/rootfs

        我们输入umount  /media/ubuntu/rootfs ,让其变为非挂载状态,同时df -h确认一下

        

linux做img镜像 linux写入img镜像_python_04

        此时,/dev/sda2已经处于非挂载状态,开始进行我们的关键操作

        输入e2fsck -f /dev/sda2  用于检查sda2这个分区的状态

        执行完后输入resize2fs /dev/sda2 20G  (这里20G是因为sda2使用了15G,只要填写大于15G且小于该分区总容量的54G皆可)

linux做img镜像 linux写入img镜像_linux_05

        执行完后我们是用parted进行分区修改

        我们输入parted /dev/sda

        随后输入unit s print free 以检查目前TF卡各卷大小

 

linux做img镜像 linux写入img镜像_linux_06

         由于我原先对2区域进行过一次分区,所以2区域有5个G大小的剩余空间。

         我们需要记住2区域开始的532480s和End的121536511s这两串数字。

         随后我们删除2这个分区,并新建一个分区,尤其需要保证开始扇区数不变,但是结束扇区数变小。

         如果你要空出30GB,那就把之前的End扇区数减掉30 * 1000 * 1024 * 2以上。我这里计算后得出的是63295487。

         输入rm,输入2,此时删除了2这个分区。

         随后输入mkpart primary 532480s 63295487s

        恭喜!我们的新分区已经建立好了!!!!(啪啪啪鼓掌)

        不出意外的话,此时会提示rootfs重新挂载了。

         输入unit s print free 查看分区情况。

                

linux做img镜像 linux写入img镜像_linux_07

         这时我们已经分离出了30G的空闲空间。

         然后我们输入quit,退出parted

         输入resize2fs /dev/sda2

         此时,我们成功将主系统所在的ext4卷进行了压缩。(鼓掌)

linux做img镜像 linux写入img镜像_linux_08

        现在,我们将TF卡和读卡器拔出,插在我们的win10电脑上,打开Win32DiskImager,新建一个空的img镜像,勾选"仅读取已分配分区"(很重要!!!!!!!!!!!)

linux做img镜像 linux写入img镜像_树莓派_09

         按下读取,我们便开始制作我们的小容量镜像了。

         制作完成,我们的镜像大小未30.1GB,远小于原先镜像的59.4GB。

linux做img镜像 linux写入img镜像_arm_10

         随后,我们便可以将这个镜像顺利地烧录到我们的新TF卡里了。

        

linux做img镜像 linux写入img镜像_linux做img镜像_11

        但此时新TF卡的容量只有30GB,我们需要手动进行一次扩容,扩容的操作与文章上述的建立分区的方法并无二致,仅仅是更改mkpart primary 532480s 63295487s为

mkpart primary 532480s (你想要的数字)s

         我以将其恢复到54GB为例,输入mkpart primary 532480s 114495487s

         重复其他步骤,此时我们的TF卡恢复为54G容量(使用64GB内存卡,容量不能超过本身最大容量)

linux做img镜像 linux写入img镜像_arm_12

 

linux做img镜像 linux写入img镜像_linux做img镜像_13

 

linux做img镜像 linux写入img镜像_python_14

        至此,本文章的任务圆满结束!!!!!!可以关电脑,飞奔出实验室,回去躺床上打原神啦!!!!!