教你树莓派4B的系统备份方法教程大全(全卡+压缩备份)

在 Windows 上用 VMware 安装 Linux 虚拟机有个「快照」的功能,就是把你当前的系统做个备份,一旦后来误操作把系统搞挂了之后可以恢复到备份的那个时间节点。Linux 系统开放的权限比较高,以 root 权限操作的话很有可能就会误删一些系统文件导致系统崩溃。我就曾把树莓派的系统搞挂过好几次,每次只能重新刷入镜像,开机后还得重复一大堆操作,所以备份树莓派的系统就很重要了。还可以把已经部署好的树莓派系统,批量复制到更多的树莓派上。

系统备份分为
「全卡备份」和
「压缩备份」两种。「全卡备份」就是将 SD 卡整体备份,操作简单,SD 卡是多大空间的备份的镜像就有多大,系统还原时需要更大的 SD 卡才行。「压缩备份」只备份 SD 卡中有内容的分区,备份出来的镜像大小基本和原来的镜像文件差不多,方法有点复杂,备份的镜像体积大大减小。原始的树莓派官方镜像第一次启动后会自动扩展整个 SD 卡空间,恢复备份镜像后首次开机需要 sudo raspi-config 扩展 SD 卡使用空间。
一、全卡备份
1. Win32DiskImager
全卡备份是最简单的一种,首先在硬盘上创建一 img 后缀的空文件,打开 Win32DiskImager,选择刚刚创建的空img 文件和 SD 卡盘符,点击 read 既可。

等待几分钟后就得到了备份的 img 文件,用 Win32DiskImager 来制作镜像时因为无法读取到 Linux 分区,所以是全卡备份,该方法的缺点是备份文件会和 SD 卡的容量一致,而且在还原的时候必须使用比镜像更大容量的 SD 卡。

可以看到 Raspbian 原系统只有 3.5G,备份文件是 7.4G(8G 的 SD 卡)。
2. 树莓派上直接复制系统
准备一张空白 SD 卡,格式化 SD 卡插入读卡器,然后插入树莓派上,使用 umount 卸载该挂载,使用命令dd bs=4M if=/dev/mmcblk0 of=/dev/sda 就可以把树莓派系统内容全部拷贝到 SD 卡上,mmcblk0 就是树莓派上系统 TF卡,sda 就是插入的 SD 卡(使用 lsblk 查看),等待完成后既可以关机插入新卡重启。

除了将原系统拷贝到 SD 卡外,也可以拷贝到 U盘之类的移动存储设备,树莓派3B+ 支持直接从 USB 启动系统,树莓派4B 暂时还不支持。
通过sudo blkid获取已烧录好系统的 U盘或者移动硬盘的 PARTUUID。

将系统 TF卡中/boot/cmdline.txt 中 rootpartuuid 修改为上述 uuid 重启,即可从 USB 设备启动系统。


该方法本质上是将原系统镜像写入另外一张 SD 卡,适合将你的系统复制给小伙伴用,不适合用作备份。


树莓派的桌面系统自带 SD Card copier,无需输入命令,也可完成复制过程。
3. dd 命令
在树莓派上 mount 一个共享目录(空间大于系统的 TF 卡),然后直接用 dd 就可以备份树莓派 dd if=/dev/mmcblk0 of=raspberrypi.img bs=1M 共享目录在电脑上的话建议用网线连接,无线网会很慢。
或者在 Ubuntu 虚拟机中操作(会自动挂载 SD卡,未自动挂载SD卡则需要先手动挂载)。下图中的 /dev/sdb1 /dev/sdb2 就是树莓派的 SD 卡,其中 256M 的分区 sdb1 是 boot 分区,7.1G 的分区 sdb2 是树莓派的系统文件分区。

使用 dd 命令可以直接备份 SD 卡。这里树莓派的 SD 卡的路径是 /dev/sdb1 和 /dev/sdb2 ,所以备份整个 SD 卡的路径就是 /dev/sdb。
输入备份命令:sudo dd if=/dev/sdb | gzip>/home/hanson/Documents/rpi-back2.gz,其中备份文件要保存的位置、文件名和 SD 卡的路径要根据实际选择。备份的时候终端没有进度条,像卡死一样,等着就行。可以另开一个终端,运行如下命令,可以观察到目标文件大小的变化。
watch -d -n 5 ls -lh /home/hanson/Documents/rpi-back2.gz

这个命令可以在备份的同时打包文件,压缩完成后的 .gz 文件只有 1.9G,解压后是 7.5G,本质上也是全卡复制。
还原的时候在 Windows 下解压文件需要加上.img 后缀。Linux 下的还原方法 sudo gzip -dc /home/hanson/Documents/rpi-back2.gz | sudo dd of=/dev/sda
二、压缩备份
1. 原理
树莓派的官方系统是基于 Debian 的,主要是两个分区:启动分区(boot)、根分区(root),烧录系统的时候就是将这两个分区写入 SD 卡。首次开机后需使用raspi-config来扩展 root 分区的大小,boot 分区不变,来达到使用所有 SD 卡内容量的目的(最新的系统已经不需要扩展操作)。
对于树莓派系统的备份,主要就是对 boot 和 root 分区的备份。而 root 分区里面只有一部分空间存储有内容,剩下的部分是空的,如果直接备份的话那就是整个 SD 卡空间备份,也就是上面所说的全卡备份。而压缩备份则是备份 boot 分区和 root 分区中有内容的空间。


2. PiShrink 裁剪
PiShrink 是 Github 上开源的树莓派压缩工具,通过裁剪上面用 Win32DiskImager 或者 dd 命令全卡备份的镜像,去掉没有内容的分区,从而减小备份镜像的大小。

先将全卡备份的镜像文件复制到 Linux 中,打开终端执行wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh 下载 sh 脚本文件,默认存到/home/user目录下,将其拷贝到镜像所在文件夹下。执行chmod +x pishrink.sh 增加执行权限,然后执行sudo bash pishrink.sh rpi-back.img 即可。


原来 7.5GB 的备份文件就被缩减到 3.4GB。
如果你的 linux 系统是语言是中文,可能会报错,需要制定英文运行sudo pishrink.sh raspberrypi.img
sh 脚本文件裁剪的方法比较简单,比如果你想要在 Linux 单纯使用命令行方式裁剪全卡备份文件,可以参考使用linux裁剪树莓派完整sd卡镜像
3. gparted
根据上述压缩备份原理,先在 Linux 环境中将 root 分区拆分内容空间和空白空间,然后在 Windows 上用Win32DiskImager 软件仅读取内容空间进行备份。以下以 Windows 10 64位 + 虚拟机 Ubuntu 19.10 为例,对树莓派4B 的 Raspbian 系统进行压缩备份。
(1).打开虚拟机,在终端输入sudo apt install gparted 安装 gparted
(2).将需要备份的 SD 卡插入读卡器然后插入电脑,等待 Linux 读取成功。
(3).输入sudo gparted启动 gparted,在右上角选择 SD 卡,可以看到 ext4 分区当中置使用了 3.78G,剩余10.88G 都是空白的。

(4).在 ext4 分区上右击点击 umount 卸载,然后继续右键点击更改大小。


(5).在弹出的窗口中重新分配大小,在新大小一栏填入比最小值(3689)大上三四百就行,我这里大 300M,在点击空余空间会自动计算,然后点击右下角 Resize,之后可以看到原来的分区只剩下 4.07G,剩下的 10.58G 空间未分配。

(6).然后点击绿色的对号键确认,在弹出的对话框中点应用。


(7).等待执行完成,可以看到分区由14.66G 缩小到 4.07G,然后弹出 SD 卡,到这里 Linux 上的操作完成。


(8).将 SD 卡重新插到 Windows 上,新建一个空白 img 文件,打开 Win32DiskImager 软件,选中该文件,然后勾选‘’仅读取已分配分区‘’(注意要最新版,旧版本没有这个功能)。


(9).等待读取完成,压缩的镜像备份就制作完成了,源镜像文件 3.9GB,备份的镜像文件 4.5GB,如果压缩一下的话就只有 1.8GB 了,适合存储。


4. 树莓派 / Linux 命令行
这种方法完全利用 Linux 命令操作,使用 dump 和 restore 来制作树莓派的 img 镜像,具体过程来自CSDN的Blog,我按照文中步骤实际操作了一番。

(1).查看系统所占容量
先用 df -h 命令查看当前系统所占容量,以确定将来要生成备份镜像的大小,若树莓派所占空间小于 SD 卡空间的 50%,就可以在树莓派内部直接生成镜像。否则要将备份的镜像生成到挂载的外置 SD 卡里面。

可以看到树莓派有 boot 和 root 两个分区,所占大小为 3.5G+253M=3.8G,因为格式转换,所以会损耗 5%~10%,总大小大约 3.8*1.1=4.2G。如果 SD 卡剩余空间大于这么多就可以接着往下进行了。
(2)安装所需的软件
sudo apt-get install dosfstools dump parted kpartx
dosfstools:fat32分区格式化工具 dump:dump & restore 备份工具 parted & kpartx:虚拟磁盘工具
(3).根据第一步计算的系统所占用空间,用 dd 命令创建一个大约 4.5G的空白镜像 raspberrypi.img,这个过程大约几分钟完成。 sudo dd if=/dev/zero of=raspberrypi.img bs=1M count=4500
注意这里 bs=1M(1M=1024x1024Bytes)。

(4).分割虚拟磁盘
通过sudo fdisk -l /dev/mmcblk0得知:第一个分区为 boot 分区,采用 FAT32 格式,由 sector 8192 开始到sector 532480;第二个分区采用 EXT4,由 sector 540672 开始到空白 img 结尾。

sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 532480s
sudo parted raspberrypi.img --script -- mkpart primary ext4 540672s -1
分区的起始扇区数都是 8192 的倍数,上述命令中 8192 基本是固定的,532480 和 540672 根据你自己的实际查询情况修改,-l 表示到文件末尾。
检查分区是否成功sudo parted raspberrypi.img,在 parted 程序中,输入 print free 命令可以显示分区内容,输入 quit 退出。

(5).挂载虚拟磁盘并格式化
设置 img 文件对应的 Loop device:sudo losetup -f --show raspberrypi.img下一行命令输出了 /dev/loop0。(如果不是 loop0 的话以后的各个步骤里的 loop0 都要改成和这里一样的)。

接着sudo kpartx -va /dev/loop0


此时 loop device 就设置好了,loop0p1 对应的是 img 文件分区上的 /boot,loop0p2 对应的是 /(根)。
然后格式化 img 文件中的两个分区。
sudo mkfs.vfat -n boot /dev/mapper/loop0p1
sudo mkfs.ext4 /dev/mapper/loop0p2

挂载目标 img 文件 loop device 到新建的目录下。
mkdir tgt_boot tgt_Root sudo mount -t vfat -o uid=pi,gid=pi,umask=0000 /dev/mapper/loop0p1 ./tgt_boot/ sudo mount -t ext4 /dev/mapper/loop0p2 ./tgt_Root/
这里是在树莓派系统里面做备份操作的,如果是用其他 Linux 系统,请注意 uid 和 gid 的设置。
(6).开始备份
【备份/boot】
首先备份 /boot,直接拷贝即可sudo cp -rfp /boot/* ./tgt_boot/(如果是用其他 Linux 系统,/boot/* 换成你挂载的 SD 卡,比如 dev/sdb1)

运行完出来一堆提示:failed to preserve ownership for...,进图形界面查看了下:


文件都复制成功了,只是文件的权限没有复制过来,影响不大。

【备份“/”】
备份根文件系统用 dump/restore 方法,首先对目标挂载点设置合适的权限,并清空。(如果是用其他 Linux 系统,将 pi.pi 替换成对应的用户名和用户组)
sudo chmod 777 tgt_Root sudo chown pi.pi tgt_Root sudo rm -rf ./tgt_Root/* cd tgt_Root/
然后开始备份
sudo dump -0uaf - / | sudo restore -rf - (如果是用其他 Linux 系统,/ 换成你挂载的 SD 卡,比如 dev/sdb2)

整个 dump/restore 过程需要几分钟时间,看到 DUMP IS DONE 就说明备份成功了。
如果上述方法的 sudo dump … 那一步出现 Broken pipe、 Illegal instruction等错误而失败的话,可以使用tar方法,把源 SD卡的根文件系统打包,所以在本机系统空间里需要额外的和源SD卡的根文件系统已用空间大小一样的可用空间,详细过程见原作者。
(7).修改相应的 PARTUUID
此时备份已经完成,还需要修改下 Raspbian 启动对应分区的 PARTUUID,也就是修改目标 img 文件里的下面两个文件:./tgt_boot/cmdline.txt 和./tgt_Root/etc/fstab
首先查看 img 文件对应的 loop device 的两个分区的 PARTUUID: sudo blkid

这里可以看到 /boot 对应的是 594e62d6-01 , / 对应的是 594e62d6-02
修改 cmdline.txt 文件 sudo vi ./tgt_boot/cmdline.txt

修改 fstab 文件 sudo vim ./tgt_Root/etc/fstab


(8).收尾工作
卸载各个挂载的分区: sudo umount tgt_boot tgt_Root
删除loop device:sudo kpartx -d /dev/loop0 和 sudo losetup -d /dev/loop0
删除挂载点目录:rmdir tgt_boot tgt_Root
最后只剩下 img 文件

将其通过 WinSCP 拷贝到 Windows 电脑上保存。或者直接在树莓派中 dd if=/home/xxx/xxx.img of=/dev/sdb bs=4M ; sync 烧写 img 文件到其他 SD 卡中(镜像目录使用 if= 来指定,外接U盘设备的地址使用 of= 来指定,不一定是 sdb,最后的 bs=4M 指定一次写入字节数,sync 同步数据),同样的在树莓派中运行后,要先用 raspi-config 先把分区空间 expand 一下。
这种方法虽然步骤比较多,但是照着一步步走下来可以对整个备份的全部技术细节有详细的了解。
5. sh 脚本一键备份
上述纯 Linux 命令行进行压缩备份的步骤繁琐,可以把全部步骤写成一个 .sh 脚本文件,这样的话只需要执行该脚本文件就能自动执行完压缩备份命令了。
使用上述脚本只需要在树莓派中新建一个.sh文件sudo vi backup.sh,sudo chmod 777 backup.sh 更改权限,然后 sudo ./backup.sh 就可以在当前脚本目录中生成树莓派的备份镜像文件了,然后还需要手动修改下PARTUUID。之后既可以在 Windows 中用 Win32DiskImager 将镜像恢复到SD卡,也可以在 Linux 用 dd 命令还原到 SD 卡,当用此 SD 卡启动树莓派的时候执行 raspi-config ->Expand Filesystem 即可扩展未使用的空间。
sh 脚本首先需要能够读懂才能使用,里面有的参数需要修改以适合你自己的环境。sh 脚本如果报错了不容易查找问题原因,建议还是先把 Linux 命令的全部流程走通了再来用这个脚本,这样的可以知道哪一步出错了从而修改。
6. 推荐脚本
这里还有一个脚本是我最推荐使用的,程序内容太长,我就不贴上来了,具体脚本内容我也没有完全读懂,反正简单易用,也是我目前使用的备份方法,可以去这里下载,使用方法如下:
step1:下载脚本文件 rpi-backup.sh 到 Linux 系统中
step2:把需要备份的 SD 卡插入 Linux 系统中,用 df -h 命令查询下 SD 卡对应的设备名。

step3:进入脚本文件 rpi-backup.sh 所在目录,只需要下面两行命令即可完成 SD 卡备份,最终 img 文件会生成在~/backupimg/文件夹下。
sudo chmod +x rpi-backup.sh (需要赋可执行权限)
./rpi-backup.sh /dev/sdb1 /dev/sdb2(脚本执行有两个参数,第一个参数是树莓派SD卡/boot分区的设备名:/dev/sdb1,第二个参数是/分区的设备名:/dev/sdb2,视情况修改)

三、总结
全卡备份肯定是不可取的,如果你是新手小白的话,建议先在 Windows 上用 Win32DiskImager 或者树莓派上的 SD Card copier 全卡备份,然后用 PiShrink 进行裁剪,代码量最低,简单不容易出错,就是比较耗时。
如果你熟悉一点 Linux 的基本操作的话可以在 Linux 虚拟机中用 gparted 图形界面来进行备份。

About the Author

今生在线

发表评论

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据