树莓派4B+ 备份镜像&批量烧录
原文:https://www.cooooder.com/archives/20200114
写这篇文章之前,自己找了一些开源脚本,但是可能是因为实际参数与脚本设置不一致,导致一直没能跑通,故自己一步一步调整命令,整理出以下步骤,如果你也遇到和我一样的问题,希望你按照下面步骤一步一步来,一些复杂的命令也给出相应的解释和标注,相信你也可以成功实现SD卡备份镜像。
0. 准备工作
环境
- 树莓派4B+
- 树莓派SD卡(已装Raspbian buster系统)
- SD读卡器
- Ubuntu PC 环境
- VMware 虚拟机(安装Ubuntu桌面操作系统)
准备
- 省略VMware安装、Ubuntu安装过程
- SD卡插入读卡器,插入电脑USB接口
- 挂载SD卡,一般虚拟机会自动识别并挂载
- 没有自动挂载SD卡的话可以手动挂载,选择 虚拟机> 可移动设备 > 连接
- 挂载成功可以看到两个文件夹
资源
- VMware Workstation 15 Pro中文版 提取码:t1ip
- ubuntu-20.04.1-desktop-amd64.iso 提取码:mj7k
万事俱备,开始备份
1. 安装必需的工具
parted是一个用于硬盘分区或调整分区大小的工具
sudo apt-get install -y dosfstools dump parted kpartx
2. 建立工作目录
mkdir ~/backupimg
cd ~/backupimg
3. uid和gid根据系统的当前用户名来确定
uid=edward
gid=edward
4. 确定创建的镜像IMG大小
这里预估镜像大小 (1.2G + 53M),安全考虑起见,创建1.5G(1600M)空白镜像IMG文件
# 查看SD卡已用空间大小,从而确定待备份的镜像IMG大小
df -h
# Filesystem Size Used Avail Use% Mounted on
# /dev/sdb1 253M 53M 200M 21% /media/edward/boot
# /dev/sdb2 15G 1.2G 13G 9% /media/edward/rootfs
5. 创建空白镜像IMG
# 大小1600M
sudo dd if=/dev/zero of=raspberrypi.img bs=1M count=1600
6. 检查镜像大小
确认镜像文件大小,必须要是512byte的整数倍,否则应该是第5步操作有误。
ls -l raspberrypi.img
# -rw-r--r-- 1 root root 1677721600 Jan 13 19:29 raspberrypi.img
# 1677721600 = 1024 * 1024 * 1600
7. 查看分区表
镜像文件需要分区为bootfs和rootfs(bootfs为FAT32类型,rootfs为ext4类型)
# 执行sudo fdisk -l ,查看分区表,确定bootfs扇区的起始,获取三个后面需要用到的参数值:8192,532479,532480
sudo fdisk -l
# Device Start End Sectors Size Type
# /dev/sdb1 8192 532479 524288 256M W95 FAT32(LBA)
# /dev/sdb2 532480 31116287 30583808 14.6G Linux
8. 镜像文件分区
# 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
9. 检查分区是否成功
sudo parted raspberrypi.img
# 在(parted)后面输入print free
# Number Start End Size Type File system Flags
# 16.4kB 4194kB 4178kB Free Space
# 1 4194kB 273MB 268MB primary lba
# 2 273MB 1677MB 1404MB primary
# 1677MB 1678MB 1049kB Free Space
# 输入quit退出
10. 镜像IMG文件关联loop device
镜像文件挂载到系统,需要利用loop device将文件挂载到系统上
sudo losetup -f --show raspberrypi.img
# 注意这里的输出 /dev/loop6
# 这里包括后面的loop6根据上一步命令获取,实际使用要根据实际获取的值进行替换
sudo kpartx -va /dev/loop6
# 查询挂载位置
ls /dev/mapper/loop6p*
# /dev/mapper/loop6p1 /dev/mapper/loop6p2
# loop6p1对应的是img文件分区上的 /boot,loop6p2对应的是 /root
11. 镜像IMG格式化
sudo mkfs.vfat -n boot /dev/mapper/loop6p1
sudo mkfs.ext4 -L rootfs /dev/mapper/loop6p2
12. loop device挂载到系统
mkdir tgt_boot tgt_Root
sudo mount -t vfat -o uid=${uid},gid=${gid},umask=0000 /dev/mapper/loop6p1 ./tgt_boot/
sudo mount -t ext4 /dev/mapper/loop6p2 ./tgt_Root/
13. 备份:备份boot
sudo cp -rfp /media/${uid}/boot/* ./tgt_boot/
14. 备份:备份root
# 设置权限,并把文件夹清空
sudo chmod 777 tgt_Root
sudo chown ${uid}.${uid} tgt_Root
sudo rm -rf ./tgt_Root/*
cd tgt_Root/
sudo dump -0uaf - /media/${uid}/rootfs/ | sudo restore -rf -
# 注意!注意!
cd ../
扫描二维码关注公众号,回复:
12703088 查看本文章
15. 查看PARTUUID
# Raspbian启动要对应分区的PARTUUID
# 镜像文件对应的loop device的两个分区的PARTUUID
sudo blkid
# /dev/mapper/loop6p1: SEC_TYPE="msdos" LABEL_FATBOOT="boot" LABEL="boot" UUID="ED9A-5B01" TYPE="vfat" PARTUUID="816d8bf0-01"
# /dev/mapper/loop6p2: LABEL="rootfs" UUID="88f021e9-d2bc-4a0b-b8f2-778d8adbc76a" TYPE="ext4" PARTUUID="816d8bf0-02"
# boot对应816d8bf0-01,root对应816d8bf0-02
# 被替换的PARTUUID
opartuuidb=`sudo blkid -o export /dev/sdb1 | grep PARTUUID`
opartuuidr=`sudo blkid -o export /dev/sdb2 | grep PARTUUID`
# 用于替换的PARTUUID
npartuuidb=`sudo blkid -o export /dev/mapper/loop6p1 | grep PARTUUID`
npartuuidr=`sudo blkid -o export /dev/mapper/loop6p2 | grep PARTUUID`
16. 修改 ./tgt_boot/cmdline.txt
# 用 $npartuuidr 替换 $opartuuidr => PARTUUID=816d8bf0-02 替换 PARTUUID=738a4d67-02
sudo sed -i "s/${opartuuidr}/${npartuuidr}/g" ~/backupimg/tgt_boot/cmdline.txt
17. 修改 ./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
18. 卸载分区
sudo umount tgt_boot tgt_Root
sudo kpartx -d /dev/loop6
sudo losetup -d /dev/loop6
rmdir tgt_boot tgt_Root
19. 烧录镜像
使用树莓派自带的镜像烧录工具烧录Raspberry Pi Imager,将 raspberrypi.img 烧录进SD卡。
20. 扩展root分区
将SD卡插入树莓派启动,执行 df -h 查看磁盘空间会发现总大小只有1.5G,需要执行sudo raspi-config命令进行配置,Advanced Options => Expand Filesystem,将根分区扩展到整张SD卡。
sudo raspi-config
21. Reboot重启树莓派生效
reboot
参考: