6. 根文件系统备份与重新烧录

对系统镜像镜像完整备份的好处是处理方便,步骤简单, 但是完整备份的系统镜像体积较大且无法使用量产工具进行烧录,使用本章节介绍的备份根文件系统再打包成完整镜像的方法则可以使用量产工具进行烧录。

如果我们仅对根文件系统做出了修改,则可以单独备份根文件系统分区,同理,如果我们对boot分区或其他分区做出了修改, 也可以单独备份相应的分区。以下重点讲解rootfs分区的备份,其他分区的备份及烧录方式也类似。

6.1. 备份前的准备工作

为了顺利的进行根文件系统的备份,我们先要做一些准备工作。

  • 将烧录到eMMC或SD卡的RK格式镜像源文件解包,得到各个分区的镜像。

  • 用于后期镜像处理的Linux PC或虚拟机

  • 如果备份的是eMMC,则需要一张已经烧录了板卡通用备份镜像的SD卡。

6.2. 根文件系统备份

SD卡系统和eMMC系统各分区如下:

存储

boot分区

根文件系统分区

eMMC

/dev/mmcblk0p2

/dev/mmcblk0p3

SD卡

/dev/mmcblk1p2

/dev/mmcblk1p3

以下均以备份eMMC的根文件系统为例,如需备份SD卡的根文件系统分区请自行修改分区编号。

6.2.1. 添加修改判断

为了验证rootfs分区是否被正确备份,我们将桌面背景图片换为下图所示的图片,或者自行在根文件系统添加判断文件等。

../../_images/backup_rootfs01.png

6.2.2. 添加重新初始化配置

为了系统能重新初始化,需要删除/etc/fstab中的boot分区的挂载配置,执行以下命令:

1
2
#eMMC的boot分区为/dev/mmcblk0p2
sudo sed -i '/^\/dev\/mmcblk0p2/d' /etc/fstab

为了能重新随机网口mac地址和扩容,需要添加以下配置:

  • 通用镜像 执行以下操作:

打开系统初始化脚本/etc/init.d/boot_init.sh,该脚本是初始化脚本,默认配置为了开机自启动。

1
vim /etc/init.d/boot_init.sh

假定通用镜像的根文件系统分区为/dev/mmcblk0p3,可执行命令 df -h 进行确认,在系统初始化脚本boot_init.sh末尾添加以下内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#-------扩容------
#判断/boot/boot_dilatation_init文件是否存在,不存在则进行扩容
if [ ! -e "/boot/boot_dilatation_init" ] ;
   then

   #转换MBR -> GPT分区表
   sgdisk -e /dev/mmcblk0

   #修改/dev/mmcblk0p3根文件系统分区空间配置
   printf 'yes\n-1\nyes' | parted /dev/mmcblk0 resizepart 3 ---pretend-input-tty

   #根据配置重新分配空间
   resize2fs /dev/mmcblk0p3

   #创建判断文件,第二次启动存在该文件不再执行此扩容
   touch /boot/boot_dilatation_init
fi

# 遍历eth0到eth3网口
for i in {0..3}; do
   iface="eth$i"

   # 检查接口是否存在
   if ifconfig "$iface" &> /dev/null; then

      # 判断是否是原生GMAC网口
      if cat /sys/class/net/"$iface"/device/of_node/compatible | grep  "gmac" &> /dev/null; then
            # 原生GMAC网口使用rk工具——vendor_storage
            # 判断/boot/boot_mac_ethX,不存在则进行随机mac
            if [ ! -e "/boot/boot_mac_$iface" ] ; then
               # 生成随机MAC地址
               new_mac=$(printf '%01x2%02x%02x%02x%02x%02x' $((RANDOM%16)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))

               # 创建判断文件,第二次启动存在该文件则不再执行随机mac
               touch /boot/boot_mac_$iface

               # 保存随机生成的mac到判断文件中
               echo "$new_mac" > /boot/boot_mac_$iface

               # 获取生成的mac并修改
               vendor_lan_mac=$vendor_lan_mac$(cat /boot/boot_mac_$iface)
               # 使用vendor_storage工具固化修改原生GMAC网口MAC
               vendor_storage -w VENDOR_LAN_MAC_ID -t hex -i "${vendor_lan_mac}"

               # 确保第一次启动时生效,因为vendor_storage固化后需重启才能生效
               ip link set dev "$iface" down
               ifconfig "${iface}" hw ether "${new_mac}"
               ip link set dev "$iface" up
            fi
      else
            # 非原生网口每次启动都使用ifconfig修改mac
            # 判断/boot/boot_mac_ethX,不存在则进行随机mac
            if [ ! -e "/boot/boot_mac_$iface" ] ; then
               # 生成随机MAC地址
               new_mac=$(printf '%01x2:%02x:%02x:%02x:%02x:%02x' $((RANDOM%16)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))

               # 创建判断文件,第二次启动存在该文件则不再执行随机mac
               touch /boot/boot_mac_$iface

               # 保存随机生成的mac到判断文件中
               echo "$new_mac" > /boot/boot_mac_$iface
            fi

            ip link set dev "$iface" down

            # 获取生成的mac并修改
            mac_address=$(cat /boot/boot_mac_$iface)
            ifconfig $iface hw ether $mac_address

            ip link set dev "$iface" up
      fi
   fi
done

6.2.3. 压缩eMMC根系统分区

插入烧录了板卡通用镜像的SD卡,从SD卡启动系统。

打开gparted磁盘管理工具,可在命令行终端执行 sudo gparted 命令打开。

确认右上角选择的存储是/dev/mmcblk0,然后右键/dev/mmcblk0p3一栏选择对根文件系统分区进行操作,卸载并压缩要备份的rootfs分区。

../../_images/backup_rootfs02.png

根据可调整的最小大小调整根文件系统分区,以下最小大小为3796Mib,可剩余一些空间调整大小为3900Mib,然后选择Resize进行确认。

../../_images/backup_rootfs03.png

应用我们做出的修改,缩小rootfs的体积,等待软件操作完成即可关闭软件。

../../_images/backup_rootfs03_2.png

6.2.4. 打包eMMC根系统分区

使用 dd 命令将eMMC根系统分区打包成一个img文件,这里我们选择将eMMC根系统分区打包到U盘。

刚才在压缩分区时我们得知eMMC的rootfs分区就是/dev/mmcblk0p3分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#挂载U盘
mount /dev/sda1 /mnt/

#将eMMC根系统分区镜像拷贝到U盘中
dd if=/dev/mmcblk0p3 of=/mnt/backup-rootfs.img bs=1024k conv=sync status=progress

#拷贝需要时间,请耐心等待,打印消息如下
4017094656 bytes (4.0 GB, 3.7 GiB) copied, 182 s, 22.1 MB/s
3900+0 records in
3900+0 records out
4089446400 bytes (4.1 GB, 3.8 GiB) copied, 183.547 s, 22.3 MB/s

umount /mnt/

备份完成后我们使用 sudo poweroff 命令关机,移除U盘,这样我们就得到了单独的根文件系统分区镜像backup-rootfs.img。

我们可以选择直接用开发工具进行 分区烧录 ,也可以将备份的backup-rootfs.img与其他分区合并成一个完整的镜像,进行 批量烧录

6.3. 分区烧录

使用开发工具导入对应的分区表,然后依次选择RK格式完整镜像解包后的各个分区镜像, 注意rootfs分区要选择我们刚刚备份得到的backup-rootfs.img镜像文件,然后进行烧录。

解包镜像可参考: 完整镜像的解包和打包 章节。

选择“下载镜像”,然后右键点击下方空白处,选择“导入配置”:

../../_images/backup_rootfs04.png

右下角选择“ALL File”,然后选择解包生成的parameter.txt分区配置文件:

../../_images/backup_rootfs04_2.png

选择解包生成的parameter.txt和MiniLoaderAll文件:

../../_images/backup_rootfs04_3.png

选择解包生成的boot.img和uboot.img文件:

../../_images/backup_rootfs04_4.png

选择解包备份的backup-rootfs.img文件:

../../_images/backup_rootfs04_5.png

板卡连接usb数据线,然后按住mr或者rec按键上电进入烧录模式,最后点击执行开始烧录镜像:

../../_images/backup_rootfs04_6.png

烧录镜像后,默认桌面背景仍然是我们原来备份前修改的图片。

6.4. 打包成完整镜像

分区烧录一次仅支持单个板卡烧录,不能进行批量烧录,因此需要将镜像各组件打包成完整的镜像然后使用量产工具进行批量烧录。

打包镜像可参考: 完整镜像的解包和打包 章节。

以在Linux环境使用Linux_Pack_Firmware_v2.29解包lubancat-rk3566的Debian xfce通用镜像为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#进入工具目录
cd Linux_Pack_Firmware/rockdev/

#解压镜像,根据实际压缩包名称而定
7z x lubancat-rk3566-debian10-xfce-20250303_update.7z

#重命名镜像为update.img,根据实际镜像名称而定
mv lubancat-rk3566-debian10-xfce-20250303_update.img update.img

#解包镜像
./unpack.sh

#解包镜像的到output目录
#查看output目录
ls output
#信息输出如下
boot.img  MiniLoaderAll.bin  package-file  parameter.txt  rootfs.img  uboot.img

将之前备份emmc根文件系统的分区镜像得到到backup-rootfs.img 复制 到Linux_Pack_Firmware/rockdev/output目录下, 删除解包生成的rootfs.img并将backup-rootfs.img重命名为rootfs.img,然后打包命令打包成完整镜像。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#进入工具解包输出目录
cd Linux_Pack_Firmware/rockdev/output

#删除解包的根文件系统
rm rootfs.img

#重命名备份出来的根文件系统
mv backup-rootfs.img rootfs.img


#打包镜像,根据实际芯片名称而定

#rk356x打包执行
../afptool -pack ./ update_tmp.img || pause
../rkImageMaker -RK3568 MiniLoaderAll.bin update_tmp.img update.img -os_type:androidos || pause

#rk3576打包执行
../afptool -pack ./ update_tmp.img || pause
../rkImageMaker -RK3576 MiniLoaderAll.bin update_tmp.img update.img -os_type:androidos || pause

#rk3588/rk3588s打包执行
../afptool -pack ./ update_tmp.img || pause
../rkImageMaker -RK3588 MiniLoaderAll.bin update_tmp.img update.img -os_type:androidos || pause

打包后在output当前目录生成 update_tmp.imgupdate.img 镜像文件,其中 update.img 就是最终打包生成的完整镜像。

6.5. 完整镜像烧录

打包得到到完整镜像和野火发布的镜像格式一致,可使用“RKDevTool”工具通过“升级固件”的方式烧录到eMMC, 或使用USB量产工具FactoryTool进行批量烧录。

RKDevTool工具参考: RKDevTool完整镜像烧录

USB量产工具FactoryTool参考: USB量产工具烧录镜像到eMMC