5. 系统镜像备份并重新烧录¶
在开发到生产过程中,对系统镜像的备份及再烧录过程是必不可少的,接下来介绍几种不同的备份方法和将备份镜像烧录的方法。
使用以下备份方法得到的备份镜像为RAW格式镜像,无法使用USB量产工具进行烧录,但可以使用其他支持RAW格式烧录的软件, 如Win32DiskImager、Etcher等,还可以自己使用dd命令来进行烧录。
注解
RAW格式原意是指未经加工的格式,野火相关文档中RAW格式是指镜像中已经包含了完整分区信息及分区文件,整个镜像是一个整体不可拆分。 与RK格式(打包时将分区标志打包进完整镜像,烧录时根据分区表将对应的分区烧录到相应的地址)做区分。
注意
如果是希望备份sd卡系统烧录到emmc的用户,请提前修改/etc/fstab文件,否则无法挂载boot分区,修改如下,如果不是则不需要修改。
1 2 3 4 | #mmcblk1p2为sd卡的boot分区,mmcblk0p2为emmc的boot分区,启动系统会自动挂载该分区到/boot目录
#/dev/mmcblk1p2 /boot auto defaults 0 2
/dev/mmcblk0p2 /boot auto defaults 0 2
|
5.1. 使用Win32DiskImager全卡备份SD卡系统镜像并重新烧录¶
使用Win32DiskImager进行全卡备份是最简单的一种备份SD卡的方法,但是由于对整个SD卡进行备份, 会导致备份文件和SD卡的容量一致,而且在还原的时候必须使用比镜像更大容量的SD卡。
Win32磁盘映像工具下载链接: https://win32diskimager.org/
在windows下新建一个空文件,后缀为img,例如backup.img, 将需要备份镜像的SD卡插到windows上并打开Win32磁盘映像工具,然后点击文件夹图标, 找到刚刚创建的backup.img文件并确认,并确认SD卡盘符,取消“仅读取已分配区”的勾选, 最后点击读取按钮,如果弹出是否覆盖backup.img的对话框,点击是即可,等待镜像备份完毕。
此时镜像已经备份完毕,备份好的镜像就是RAW格式的backup.img。
除了使用Win32磁盘映像工具烧写backup.img镜像到SD卡,也可以使用Etcher等支持烧录RAW格式镜像的软件来烧录。 打开Win32磁盘映像工具,选择backup.img镜像,选择新的空白SD卡盘符, 最后点击写入按钮即可,注意被烧录的SD卡大小必须大于等于镜像的大小。
5.2. 使用dd命令压缩备份SD卡系统镜像并重新烧录¶
使用dd命令进行SD卡压缩备份虽然需要借助运行Linux系统的主机或虚拟机,但是备份出的镜像体积较小,便于再次发布和烧录。
将已经搭建好环境的SD卡从板卡取出并插到读卡器上,然后将读卡器接入PC机(Ubuntu中),
打开Gparted磁盘管理工具,将磁盘切换到SD卡,就能看到一下信息(烧录debian系统的SD卡为例)
没有Gparted的可以使用以下命令安装。
1 | sudo apt install gparted
|
从图中可以看到SD卡中共8个已分配的分区,要备份的内容是最后一个分区及之前的内容。
最后一个分区大小为23.43GiB,但是已用空间只有450KiB,我们将最后一个分区的大小进行压缩,就可以减小备份镜像的大小。
选中要调整大小的分区,点击鼠标右键,选中 更改大小/移动
从图中看到,此分区的最小大小为481M,我们将它压缩到500M,然后点击 调整大小/移动
配置完成后点击绿色对钩,开始执行的更改
如果希望备份的镜像可以在烧录启动时自动扩展最后一个分区,可以在终端执行以下命令。
挂载rootfs分区,根据上图可知,也就是/dev/sdb6,然后删除其中的一个文件
1 2 3 4 5 6 7 8 | #挂载rootfs分区
sudo mount /dev/sdb6 /mnt
#删除此文件,使用备份镜像启动会自动扩展分区
sudo rm /mnt/var/lib/misc/firstrun
# 删除完成后,卸载已挂载的分区
sudo umount /mnt
|
现在再计算一下需要备份的大小 (8+4+4+64+64+32+6.00x1024+128+500)MiB≈6948MiB, 由于显示的大小通过四舍五入的方式保留2位小数,所以我们可以加一点余量,备份7000MiB的大小。
注解
在Linux下 1MiB=1024KiB=1048576Byte,1MB=1000KB=1000000Byte。
使用 mkdir
命令创建一个新的目录,用于存放从带镜像的SD卡中拷贝的镜像。
然后使用 dd
命令将带镜像的SD中的镜像拷贝到新创建的目录中。
1 2 3 4 5 6 7 8 9 10 | #创建新目录
mkdir backup
#将带镜像的SD卡中的镜像拷贝到创建的目录中
sudo dd if=/dev/sdb of=./backup/backup.img count=7000 bs=1024k conv=sync
#拷贝需要时间,请耐心等待,打印消息如下
记录了7000+0 的读入
记录了7000+0 的写出
7340032000 bytes (7.3 GB, 6.8 GiB) copied, 492.74 s, 14.9 MB/s
|
提示
若备份的镜像烧录后仍无法正常运行,请将bs=1024k改为bs=1M并去掉conv参数,即
sudo dd if=/dev/sdb of=./backup/backup.img count=7000 bs=1M
等待dd命令运行完成后,就得到了RAW格式的backup.img镜像
dd命令参数的含义:
if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=/dev/sdb >
of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=./backup/backup.img, 这里的.img是镜像的格式,转成.img格式的文件后方便后续使用etcher烧录镜像 >
bs = bytes:同时设置读入/输出的块大小为bytes个字节,此处填的是1024k,表示1M大小。
count = blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数,此处设置的是7000, 表示7000个bs,也就是7000M。
conv= sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。
RAW格式的backup.img镜像,可以使用使用Win32DiskImager或Etcher等软件来烧录到SD卡,也可以使用dd命令去写入到空的SD卡中。
将空白SD卡插入PC,确认插入SD卡的设备号,这里演示的设备号是/dev/sdc,烧录时以SD卡实际对应的设备号灵活修改。
1 2 3 4 5 6 7 | #将backup.img写入SD卡
sudo dd if=./backup/backup.img of=/dev/sdc bs=1024k conv=sync
#写入完成后,打印消息如下
记录了7000+0 的读入
记录了7000+0 的写出
7340032000 bytes (7.3 GB, 6.8 GiB) copied, 427.027 s, 17.2 MB/s
|
不指定count,会将整个backup.img文件写入目标位置。
等待写入完成后,即可使用烧录好的SD卡来启动板卡了。
5.3. 使用fire-config压缩备份eMMC中的系统镜像¶
5.3.1. 说明¶
fire-config v1.2.4版本添加支持了SD卡备份eMMC和重新烧录eMMC的功能,将操作步骤通过脚本一键完成,方便开发和生产。 fire-config执行的步骤和后一小节——“使用dd命令压缩备份eMMC中的系统镜像”的内容一样,只不过通过脚本自动执行。
对于备份:
自动压缩eMMC没有使用的空间,减小备份镜像的大小。
添加随机网口Mac和扩充脚本。
使用dd进行备份,与SDK构建的格式不一样。
对于烧录:
将备份镜像重新烧录到eMMC,镜像需位于/home/cat/或者/mnt/,名字为backup.img。
只能烧录dd打包的镜像,不能烧录SDK构建的通用镜像。
确认版本:
执行fire-config命令打开界面,可以从界面中找到当前版本,如下图,需要v1.2.4及以上的版本。
如果低于v1.2.4版本可以通过网络或者deb包进行更新:
网络更新:
1 2 3 4 5 | #更新软件数据库
sudo apt update
#下载最新版fire-config
sudo apt install fire-config
|
离线deb更新:
fire-config-v1.2.4
fire_config_1.2.4_arm64.deb
下载离线deb包,然后传到板卡,使用命令 sudo dpkg -i fire_config*.deb 进行安装。
5.3.2. SD备份eMMC¶
命令行执行fire-config打开界面,选择“P5 系统备份与重新烧录选项”,如下图:
进入系统备份与重新烧录界面后,选择“U2 SD备份eMMC”,如下图:
选择后,会自动判断是否是SD卡启动系统,然后是SD卡启动,则自动执行备份命令。
信息输出如下:
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 | 添加随机mac和扩容分区内容到eMMC boot_init.sh初始化脚本完成
可以进行分区调整,备份的文件系统的已用大小:6486MB,调整分区大小为:6686MB
检查文件系统是否挂载...
文件系统未挂载,可进行压缩空间和备份...
e2fsck 1.46.2 (28-Feb-2021)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mmcblk0p3: ***** FILE SYSTEM WAS MODIFIED *****
132371 inodes used (1.77%, out of 7477792)
94 non-contiguous files (0.1%)
164 non-contiguous directories (0.1%)
# of inodes with ind/dind/tind blocks: 0/0/0
Extent depth histogram: 121444/59
1568317 blocks used (5.14%, out of 30502904)
0 bad blocks
1 large file
109957 regular files
9930 directories
55 character device files
25 block device files
0 fifos
7 links
12395 symbolic links (10780 fast symbolic links)
0 sockets
------------
132369 files
开始调整文件系统分区大小为 6686MB
resize2fs 1.46.2 (28-Feb-2021)
resize2fs: Invalid new size: 6686MB
End? [125GB]? 6686MB
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? yes
Information: You may need to update /etc/fstab.
e2fsck 1.46.2 (28-Feb-2021)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mmcblk0p3: 132371/7477792 files (0.2% non-contiguous), 1568317/30502904 blocks
文件系统分区调整完成。
正在执行sync同步....
开启打包镜像,请耐心等待...
7142899712字节(7.1 GB,6.7 GiB)已复制,122 s,58.5 MB/s
记录了6886+0 的读入
记录了6886+0 的写出
7220494336字节(7.2 GB,6.7 GiB)已复制,123.516 s,58.5 MB/s
正在执行sync同步....
|
挂载eMMC根文件系统到/media/emmc/,向/media/emmc/etc/init.d/boot_init.sh初始化脚本添加扩容和随机网口Mac代码。
判断eMMC根文件系统是否需要压缩空间,压缩空间可以减小备份镜像的体积,重新烧录eMMC后会自动扩容。
e2fsck工具自动检测和修复文件系统,resize2fs工具压缩文件系统,parted工具调整根文件系统分区大小。
通过dd命令打包镜像,期间会判断当前设备空间是否充足,如果充足则打包镜像到/home/cat/backup.img,如果不充足,则需要插入 NTFS格式 的U盘,自动挂载/mnt,并将镜像打包到/mnt/backup.img。
打包完成后会提示,备份已完成并提示备份镜像生成的路径,如下图:
生成的backup.img镜像为dd格式,可以通过fire-config工具重新烧录到eMMC,或者参照本章后续小节——“使用RKDevTool烧录RAW格式镜像到eMMC”的内容,使用RKDevTool工具通过USB烧录到eMMC。
5.3.3. SD烧录eMMC¶
需要注意:
要烧录的镜像必须是dd打包的,不能是SDK构建出来的通用镜像。
镜像需要放在/home/cat/或/mnt,名字为backup.img。
如果/home/cat/和/mnt同时存在backup.img则需要删除其中一个。
命令行执行fire-config打开界面,选择“P5 系统备份与重新烧录选项”,如下图:
进入系统备份与重新烧录界面后,选择“U3 SD烧录eMMC”,如下图:
自动检测backup.img,如果/home/cat/或/mnt存在,则可以进行烧录,如下图:
信息输出如下:
1 2 3 4 5 6 7 | 开始烧录eMMC....
7052722176字节(7.1 GB,6.6 GiB)已复制,17 s,415 MB/s[ 3458.479757] mmcblk0: p1 p2 p3
记录了6886+0 的读入
记录了6886+0 的写出
7220494336字节(7.2 GB,6.7 GiB)已复制,28.8714 s,250 MB/s
正在执行sync同步....
|
通过dd命令将backup.img烧录到eMMC。
烧录完成后会提示烧录已完成,如下图,然后断电拔掉SD卡,从eMMC启动系统即可。
5.4. 使用dd命令压缩备份eMMC中的系统镜像¶
使用dd命令对eMMC中的系统镜像进行备份和使用dd命令对SD卡备份的过程和原理都类似, 都是在Linux环境下,去读取并复制要备份存储设备中的内容。
备份SD卡和备份eMMC的不同点在于,SD卡是可移动存储设备,可以借助PC的Linux环境,而eMMC在板卡上不可拆卸。 如果使用SD卡启动启动系统,就能为eMMC备份提供Linux环境了。
注解
SD卡备份过程中以rkboot分区Debian镜像为例演示,eMMC备份过程中将以extboot分区Ubuntu镜像进行演示, 两系统镜像仅分区格式和数量有部分差异,对备份方法及过程无影响,可对照使用。
我们需要准备一张SD卡,并烧录用于备份的板卡镜像,此处的镜像是板卡对应的通用镜像,Debian或Ubuntu通用镜像都可以, 使用最新版本即可,板卡通用镜像可以从网盘下载。
还需要一个存储设备,用于存放备份后的镜像,最好是U盘,读写速度较快,可以加快备份速度。 没有U盘的话,也可以使用启动板卡的SD卡,单独创建一个用于存放备份镜像的分区。
先用eMMC启动,创建一个标志文件,用以验证修改过的内容是否被正确备份了。
使用poweroff命令关机,插入SD卡,系统是优先SD卡启动的,直接上电启动即可。
后面的步骤就和使用Linux PC备份SD卡的流程一致了,只是有部分细节需要注意。
首先要获取eMMC的设备号,查看/dev目录下mmc设备,带有mmcblkx[boot]x的就是eMMC,这里就是/dev/mmcblk0。
桌面打开或者终端执行以下命令打开Gparted磁盘管理工具,将磁盘切换到eMMC
1 2 | #使用终端命令打开Gparted磁盘管理工具
sudo gparted
|
从图中可以看到SD卡中共3个已分配的分区,将要备份的内容是最后一个分区及之前的空间。
我们发现最后一个分区,也就是rootfs分区的总空间为28.99GiB,但是已用空间只有2.92GiB, 我们将rootfs分区的大小进行压缩,就可以减小备份镜像的大小。
调整最后一个分区,也就是rootfs分区的大小。从图中可以看到,最小的空间是3143MiB,我们调整到3160MiB。
调整完成后点击绿色按钮应用修改
5.4.1. 扩容和网口随机mac¶
由于使用dd完整备份emmc里面的系统,网口mac是随机生成并固定在uboot环境变量的,且不能覆盖,但如果不修改mac会造成新烧录的一块或多块板的网口mac地址相同,造成网络无法通信,但是我们可以使用脚本重新随机或自定义网口mac。
另外,希望备份的镜像可以在烧录启动时自动扩展最后一个分区,可以按以下步骤进行操作。
注解
以下命令须使用管理员权限操作,如未使用root用户操作,需要在命令前加sudo
通用镜像和专用镜像的方法不同,分别对两种镜像进行讲解。
通用镜像 执行以下操作:
插入烧录好系统的SD卡,以SD卡启动系统,进入系统后执行以下操作:
1 2 3 4 5 6 7 8 | #创建目录挂载U盘
mkdir -p /media/emmc
#挂载根文件系统分区
mount /dev/mmcblk0p3 /media/emmc/
#打开系统初始化脚本
vim /media/emmc/etc/init.d/boot_init.sh
|
在系统初始化脚本boot_init.sh末尾添加以下内容,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 | #-------扩容------
#判断/boot/boot_dilatation_init文件是否存在,不存在则进行扩容
if [ ! -e "/boot/boot_dilatation_init" ] ;
then
#修改/dev/mmcblk0p3根文件系统分区空间配置
printf 'yes\n-1\nyes' | parted /dev/mmcblk0 resizepart 3 ---pretend-input-tty
#根据配置重新分配空间
resize2fs /dev/mmcblk0p3
#创建判断文件,第二次启动存在该文件不再执行此扩容
touch /boot/boot_dilatation_init
fi
#------随机网口mac------
#---------------------------------------------
# 遍历eth0到eth3
for i in {0..3}; do
iface="eth$i"
# 检查接口是否存在
if ifconfig "$iface" &> /dev/null; then
ip link set dev "$iface" down
# 判断/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
# 获取生成的mac并修改
mac_address=$(cat /boot/boot_mac_$iface)
ifconfig $iface hw ether $mac_address
ip link set dev "$iface" up
fi
done
|
提示
以上扩容和随机网口Mac都会在/boot/下生成一个判断文件,如果存在则表示已经扩容和随机Mac,下次启动不会重复执行,如果删除对应的文件则会重新执行。
修改完成后卸载挂载的分区
1 2 | # 修改完成后,卸载已挂载的分区
umount /media/emmc/
|
提示
如果需要二次备份,请删除以上的判断文件,否则二次备份后烧录到其他板,文件存在则不会进行扩容和随机mac。
专用镜像 执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #创建目录挂载U盘
mkdir -p /media/emmc
#挂载根文件系统分区,根据实际修改
mount /dev/mmcblk0p3 /media/emmc/
#删除此文件,使用备份镜像启动会自动扩展分区
rm /media/emmc/var/lib/misc/firstrun
#随机mac参考通用镜像,创建自启动脚本并进行随机。
# 删除完成后,卸载已挂载的分区
umount /media/emmc/
|
手动计算一下需要备份的大小 (8+4+128+3.09x1024)MiB≈3305MiB, 由于显示的大小通过四舍五入的方式保留2位小数,所以我们可以加一点余量,备份3350MiB的大小。
使用 mkdir
命令创建一个目录用于挂载U盘,然后使用 使用 mount
命令挂载U盘,最后使用 dd
命令将镜像备份到挂载的U盘中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #创建目录挂载U盘
mkdir -p /media/usb
#挂载U盘
mount /dev/sda1 /media/usb/
#将镜像备份到挂载U盘中
dd if=/dev/mmcblk0 of=/media/usb/backup.img count=3350 bs=1024k conv=sync
#拷贝需要时间,请耐心等待,打印消息如下
3350+0 records in
3350+0 records out
3512729600 bytes (3.5 GB, 3.3 GiB) copied, 198.883 s, 17.7 MB/s
# 备份完成后,卸载U盘
umount /media/usb/
|
等待dd命令运行完成后,就得到了RAW格式的backup.img镜像,为了确保U盘中的镜像写入完整, 不要直接拔出U盘,使用umount命令卸载完成后再拔出U盘
5.5. 使用RKDevTool烧录RAW格式镜像到eMMC¶
为了验证系统镜像确实被写入了eMMC,我们先删除原来的镜像。使用RKDevTool高级功能中的 擦除所有 来清空eMMC。
注解
RKDevTool高级功能中的擦除所有功能虽然无法清除Loader文件,但是可以擦除其他分区。
接下来使用RKDevTool向eMMC中烧录RAW格式的镜像。
要想烧录RAW格式镜像,需要使用RKDevTool_Release_v2.86的版本,使用最新版的烧录工具会失败。
打开RKDevTool_Release_v2.86,默认配置文件就是用来烧录RAW格式的, 如果与下图红框的内容不一致,可以在 地址 下方的空白区域点击鼠标右键导入配置, 选择和RKDevTool_Release_v2.86同一文件夹的RAW.cfg。
也可以按照图片中的地址和名字,手动点击 地址 和 名字 进行修改, 还可以右键点击空白处 添加项
上述工作准备完成后,点击路径后的 … 添加对应的文件,Boot是指Loader文件, 也就是芯片型号对应的MiniLoaderAll.bin,system对应的就是RAW格式的镜像, 可以是备份的RAW格式的镜像,也可以是OpenWrt的RAW格式镜像。
这里以备份镜像为例,选择完镜像后点击执行,开始下载。
下载完成后启动板卡,看一下备份之前eMMC之前创建的文件。
5.6. 使用dd命令烧录RAW格式镜像到eMMC¶
除了使用RKDevTool工具烧录eMMC之外,还可以通过dd命令将RAW格式的backup.img镜像写入eMMC中。
使用dd命令对eMMC烧录RAW格式镜像和使用dd命令备份eMMC的过程类似,备份是将eMMC中的内容以RAW格式写入backup.img镜像, 而烧录过程就是将RAW格式的backup.img镜像写入eMMC中。
为了验证系统镜像确实被写入了eMMC,我们先删除原来的镜像。使用dd命令将eMMC的前16M写空内容,破坏原有的分区表就可以了。
1 2 | # 将eMMC前16M写空内容
dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=16
|
移除SD卡,重新上电,直接进入了Maskrom模式.
我们需要准备一张SD卡,并烧录用于备份的板卡通用备份镜像 RK356X-LUBANCAT-BACKUP_xxx_Update.img,xxx为更新日期
还需要一个存储设备,用于存放要烧录的RAW格式镜像,就使用刚刚用于备份的U盘。
为了验证通过dd命令烧录的镜像就是我们备份的镜像,先烧录Debian镜像覆盖eMMC中的内容。
插入SD卡,从SD卡启动操作系统。由于系统启动时会自动挂载分区,我们先要手都卸载/media/cat/目录下的所有分区,然后重新挂载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #卸载/media/cat/目录下挂载的所有分区
umount /media/cat/*
#挂载U盘到/mnt目录
mount /dev/sda1 /mnt
#将eMMC中的内容备份到/mnt/backup.img中
dd if=/mnt/backup.img of=/dev/mmcblk0 bs=1024k conv=sync
#拷贝需要时间,请耐心等待,打印消息如下
3350+0 records in
3350+0 records out
3512729600 bytes (3.5 GB, 3.3 GiB) copied, 133.043 s, 26.4 MB/s
# 卸载U盘
umount /mnt/
# 将内存中的缓存写入存储设备
sync
# 关机
poweroff
|
移除SD卡,重新上电启动