在树莓派上做开发,难免会弄出各种版本的系统,加上有时候还需要拿给客户自己烧录或者demo,总是要clone一下TF卡,做系统做到烦躁。于是想想有没有什么办法能做跟官方release一样的烧录img出来,基本要求就是全系统克隆,但做出的img跟卡的容量无关,只跟系统占用的存储大小有关。
简单全卡备份
其实如果只是简单备份,可以直接将TF卡插入Linux电脑,用dd命令来备份和恢复(设备号不固定这里只是例子,还是用fdisk -l先查看一下比较保险):
# Backup the system to img file in Linux
dd if=/dev/mmcblk0 of=raspberrypi-bak.img bs=1M
# A little difference if Mac
dd if=/dev/rdisk2 of=raspberrypi-bak.img bs=1M
#
# Restore system from img
dd if=raspberrypi-bak.img bs=1M of=/dev/mmcblk0
# Or in Mac
dd if=raspberrypi-bak.img bs=1M of=/dev/rdisk2
不过这样做,16G的卡哪怕你只用了1G,整个备份文件也有16G,占用空间耗时间是小事,想想拿这么大文件给客户不方便,也显得太不专业了。
在网上搜了一下,已经有朋友先行做过类似的事情:树莓派 Raspberry Pi SD卡系统备份与还原,看了一下按照他的步骤实践了一遍,但出现了一些问题,折腾了很久最终才解决。
RaspberryPi的文件系统
首先介绍一下RaspberryPi的文件系统。树莓派的官方系统是基于Debian的,主要是两个分区:启动分区boot和根分区。boot分区为fat32格式,挂载在/boot,存放一些系统启动需要的基本文件,包括内核、驱动、firmware、启动脚本等;根分区文件系统是ext4格式,挂载于/,存放一些安装的软件和库文件、系统配置、用户数据等等;另外当系统启动时会自动生成和挂载一些必要的其他文件夹,包括temfs、sysfs、proc、debugfs、configfs等(使用mount可以看到他们),这些都是虚拟文件系统,由操作系统自动管理,备份时不需要关注。日常使用时,修改的文件包括安装的软件都是在根分区中,而如果自行编译内核,需要更新的文件都在/boot中。
所以备份一个系统,实际上是要备份这两个分区,官方发布的烧录镜像,也是包含了这样的两个分区,并保证通过dd的操作,能将其完整写入目标TF卡。首次烧录完毕后,不论你的TF卡容量为多少,启动后的boot和/分区大小都是固定的,然后可以使用raspi-config
来扩展根分区的大小,boot分区不变,来达到使用所有卡内容量的目的。
相对应的备份步骤,大致为:创建img,把img当作一个磁盘分区和格式化,mount各个分区,将文件备份至对应的分区中,umount分区结束备份。
目标备份文件的创建和分区
既然是备份到文件,那么首先需要创建一个备份文件,并且把这个文件看作一个虚拟设备,对其进行分区。