目录
一、需求背景
因此在做硬件系统研发阶段需要来回烧录系统并搭建各种环境,重复工作花费很多时间,并且研发完成后要量产,需要每个硬件配置同样的系统和环境,我们不可能挨个给板子装系统配环境,因此需要将配置好的系统环境打包成镜像,也就是备份出来,供下一次测试或者其他板子上直接烧录使用。
二、思路和方法
本人经过调研备份导出系统方式很多,可以借助工具来整体sd卡文件打包,不做压缩的情况下是完整打包,比如sd卡是32G,系统加环境占用6G,但是备份出来的是32G,显然这是不可接受的,因此需要压缩,也就是最后备份出来就是6G,我们这里选用dd命令来完成系统备份生成新的镜像,并用dd命令还原系统。
三、linux系统下读取sd卡
读卡器插入要备份的sd卡接入到一个linux系统主机,命令查看文件系统的磁盘使用情况
df -h
我的是64G的sd卡,结果发现没有,那查看一下磁盘情况
sudo fdisk -l
先记下上图中的三个数值:8192、532479、532480,后边给镜像文件分区时会用。
发现有我的sd卡磁盘,只是没有挂载上,创建两个目录挂载一下
mkdir tfCardSdb1 tfCardSdb2
mount /dev/sdc1 ~/tfCardSdb1
mount /dev/sdc2 ~/tfCardSdb2
#然后df -h看一下挂在好了
这里说一下 /dev/sdc1 是启动分区boot ,/dev/sdc2是根分区,boot分区为fat32格式,挂载在/boot,存放一些系统启动需要的基本文件,包括内核、驱动、firmware、启动脚本等;根分区文件系统是ext4格式,挂载于/,存放一些安装的软件和库文件、系统配置、用户数据等等;
备份一个系统,实际上是要备份这两个分区,官方发布的烧录镜像,也是包含了这样的两个分区,并保证通过dd的操作,能将其完整写入目标TF卡。
四、第一种备份方式
安装一些辅助工具
sudo apt-get install -y dosfstools dump parted kpartx
预估要备份出来的镜像大小并创建一个空的镜像文件
由上图蓝色区域可以看出,因为我这里包含了很多环境和工程代码,差不多是6.5G,然后稍微大出一点 6.5*1.3=8.45,那就8500M吧。
mkdir ~/backupimg
cd ~/backupimg
sudo dd if=/dev/zero of=raspberrypi.img bs=1M count=8500
等了差不多几分钟吧就好了,然后看一下镜像文件的大小:
ls -l raspberrypi.img
给镜像文件分区
工具parted可以用来把一个img文件当作一个磁盘来分区,镜像文件需要分区为bootfs和rootfs(bootfs为FAT32类型,rootfs为ext4类型),还记得上边记录下的三个数值吗?拿过来开始给镜像文件分区:
# mklabel msdos:定义分区表格式,msdos不支持2TB以上容量的磁盘,大于2TB的磁盘选gpt分区表格式
# mkpart primary start end:primary指分区类型为主分区
# 这里的值需要手动执行步骤7,来设定
sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 532479s
sudo parted raspberrypi.img --script -- mkpart primary ext4 532480s -1
检查是否成功:
# 在(parted)后面输入print free
#数字 开始: End 大小 类型 文件系统 标志
# 16.4kB 4194kB 4178kB 剩余空间
# 1 4194kB 273MB 268MB primary lba
# 2 273MB 8912MB 8639MB primary
# 8912MB 8913MB 1049kB 剩余空间
# 输入quit退出
sudo parted raspberrypi.img
设置循环设备:
#losetup命令:设置循环设备
#循环设备可以把文件虚拟成块设备(block device),以便模拟整个文件系统,这样用户可以将其看作是硬盘驱动器,光驱或软驱等设备,并挂入当作目录来使用。
sudo losetup -f --show raspberrypi.img
# 注意,我这里的输出 /dev/loop7
# 这里包括后面的loop7根据上一步命令获取,实际使用要根据实际获取的值进行替换
sudo kpartx -va /dev/loop7
#add map loop7p1 (253:0): 0 524288 linear 7:7 8192
#add map loop7p2 (253:1): 0 16873472 linear 7:7 532480
# 查询挂载位置
ls /dev/mapper/loop7p*
# /dev/mapper/loop7p1 /dev/mapper/loop7p2
# loop7p1对应的是img文件分区上的 /boot,loop7p2对应的是 /root
镜像文件IMG格式化:
sudo mkfs.vfat -n boot /dev/mapper/loop7p1
sudo mkfs.ext4 -L rootfs /dev/mapper/loop7p2
loop device挂载系统:
mkdir tgt_boot tgt_Root
sudo mount -t vfat /dev/mapper/loop7p1 ./tgt_boot/
sudo mount -t ext4 /dev/mapper/loop7p2 ./tgt_Root/
备份boot:
sudo cp -rfp /home/raychiu/tfCardSdb1/* /home/raychiu/backupimg/tgt_boot
备份root
# 设置权限,并把文件夹清空
sudo chmod 777 tgt_Root
sudo rm -rf ./tgt_Root/*
cd tgt_Root/
sudo dump -0uaf - /home/raychiu/tfCardSdb2/ | sudo restore -rf -
# 注意!注意!
cd ../
查看PARTUUID:
# Raspbian启动要对应分区的PARTUUID
# 镜像文件对应的loop device的两个分区的PARTUUID
sudo blkid
#/dev/mapper/loop7p1: SEC_TYPE="msdos" LABEL="boot" UUID="9D96-119D" TYPE="vfat" PARTUUID="6cc7c5be-01"
#/dev/mapper/loop7p2: LABEL="rootfs" UUID="4170b706-3a94-443e-a887-e0528f32cbed" TYPE="ext4" PARTUUID="6cc7c5be-02"
# boot对应6cc7c5be-01,root对应6cc7c5be-02
# 被替换的PARTUUID
opartuuidb=`sudo blkid -o export /dev/sdc1 | grep PARTUUID`
opartuuidr=`sudo blkid -o export /dev/sdc2 | grep PARTUUID`
# 用于替换的PARTUUID
npartuuidb=`sudo blkid -o export /dev/mapper/loop7p1 | grep PARTUUID`
npartuuidr=`sudo blkid -o export /dev/mapper/loop7p2 | grep PARTUUID`
修改 ./tgt_boot/cmdline.txt
sudo sed -i "s/${opartuuidr}/${npartuuidr}/g" ~/backupimg/tgt_boot/cmdline.txt
修改 ./tgt_Root/etc/fstab
sudo sed -i "s/${opartuuidb}/${npartuuidb}/g" ~/backupimg/tgt_Root/etc/fstab
sudo sed -i "s/${opartuuidr}/${npartuuidr}/g" ~/backupimg/tgt_Root/etc/fstab
卸载分区
sudo umount tgt_boot tgt_Root
sudo kpartx -d /dev/loop7
sudo losetup -d /dev/loop7
rmdir tgt_boot tgt_Root
这里已经完成镜像备份制作,
烧录镜像并扩充分区
烧录参考:树莓派4B 4G从烧录系统到无屏幕配置ssh和静态IP_RayChiu757374816的博客-CSDN博客
因为烧录完后会发现系统空间并不是sd卡的所有空间,因此需要扩充分区。
sudo raspi-config
sudo reboot
五、第二种系统备份方式:
安装pishrink:
github地址在这里:https://github.com/Drewsif/PiShrink
按照里边的操作是这样安装的:
git clone https://github.com/Drewsif/PiShrink.git
cd PiShrink
chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin
先用lsblk命令查看SD卡的盘符:
lsblk
备份和压缩:
sudo dd if=/dev/sdb of=./rpi.img bs=8M
sudo pishrink.sh -s rpi.img newpi.img
这种方式其实就是全量复制后再压缩一下,我的卡是64G的,第一步就太耗时间了,此方式不太好啊。
参考:树莓派RaspberryPi系统备份Image的制作 | Linux开发和七七八八
树莓派备份镜像&批量烧录_夜空中最亮的星-CSDN博客_树莓派备份系统镜像