系统镜像备份并重新烧录¶
在开发到生产过程中,对系统镜像的备份及再烧录过程是必不可少的,接下来介绍几种不同的备份方法和将备份镜像烧录的方法。
备份SD卡系统镜像并重新烧录¶
使用以下备份方法得到的备份镜像为RAW格式镜像,对应Win32DiskImager、Etcher等,还可以自己使用dd命令来进行烧录。
注解
RAW格式原意是指未经加工的格式,野火相关文档中RAW格式是指镜像中已经包含了完整分区信息及分区文件,整个镜像是一个整体不可拆分。
压缩SD卡中的系统¶
由于SD卡启动后会进行初始化扩容,充分利用SD卡空间,如果完全备份SD卡,系统大小会很大,烧录时间会很长,因此,可以提前压缩SD卡中没有使用的空间,然后再进行备份,解决以上问题。
1、将SD卡插到板卡中,删除初始化判断文件,以及分区自动挂载配置,让镜像备份到其他SD卡启动时可以重新初始化。
1 2 3 4 5 | #初始化判断文件以boot_开头,将其删除
sudo rm /boot/boot_*
#删除/etc/fstab文件中的boot分区自动挂载
sudo sed -i '/^\/dev\/mmcblk0p1 \/boot auto defaults 0 2/d' /etc/fstab
|
删除后直接断电,那么再次启动时就会进行扩容、将随机生成的mac固定。
2、拔下SD卡,将SD卡挂载到虚拟机,打开gparted工具,在终端执行以下命令
1 2 3 4 5 | #安装gparted工具
sudo apt install gparted
#打开gparted工具
sudo gparted
|
3、在打开的界面先选择sd卡对应的设备,然后选择根文件系统分区卸载,再调整大小。
4、然后拉动边框缩小根文件系统分区大小,然后确认。
5、然后点击绿色勾确认分区当前配置,弹出的界面选择应用,等待完成。
6、完成以上操作后可以看到,sd卡的根文件系统分区被压缩。
使用dd命令压缩备份SD卡系统¶
1、在压缩完sd卡的根文件系统分区后可备份SD中系统,从下图中可以看到SD卡中共2个已分配的分区,要备份的内容是最后一个已分配的分区及之前的内容。
现在再计算一下需要备份的大小 (16+1060)MiB≈1076MiB, 由于显示的大小通过四舍五入的方式保留2位小数,所以我们可以加一点余量,备份1200MiB的大小。
注解
在Linux下 1MiB=1024KiB=1048576Byte,1MB=1000KB=1000000Byte。
2、使用 mkdir
命令创建一个新的目录,用于存放从带镜像的SD卡中拷贝的镜像。
然后使用 dd
命令将带镜像的SD中的镜像拷贝到新创建的目录中。
1 2 3 4 5 6 7 8 9 10 | #创建新目录
mkdir backup
#将带镜像的SD卡中的镜像拷贝到创建的目录中,其中count和bs就是前面算出的大小
sudo dd if=/dev/sdb of=./backup/backup.img count=1200 bs=1024k conv=sync
#拷贝需要时间,请耐心等待,打印消息如下
记录了1200+0 的读入
记录了1200+0 的写出
1258291200字节(1.3 GB,1.2 GiB)已复制,133.188 s,9.4 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指定的字节数,此处设置的是1200, 表示1200个bs,也就是1200M。
conv= sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。
烧录镜像到SD卡¶
RAW格式的backup.img镜像,可以使用使用balenaEtcher或者Win32DiskImager等软件来烧录到SD卡,也可以使用dd命令去写入到空的SD卡中。
1、使用balenaEtcher烧录方法前面系统镜像烧录章节已经介绍过了,以下介绍使用dd命令去写入到空的SD卡。
2、将空白SD卡插入PC,确认插入SD卡的设备号,这里演示的设备号是/dev/sdb,烧录时以SD卡实际对应的设备号灵活修改。
1 2 3 4 5 6 7 8 9 10 | #如果SD自动挂载了,需要先卸载
sudo umount /dev/sdb1
#将backup.img写入SD卡
sudo dd if=./backup/backup.img of=/dev/sdb bs=1024k conv=sync
#写入完成后,打印消息如下
记录了1200+0 的读入
记录了1200+0 的写出
1258291200字节(1.3 GB,1.2 GiB)已复制,268.577 s,4.7 MB/s
|
不指定count,会将整个backup.img文件写入目标位置。
等待写入完成后,即可使用烧录好的SD卡来启动板卡了。
备份eMMC系统镜像并重新烧录¶
由于eMMC镜像系统使用的是cmdline partition方式管理分区,没有分区表,并且SD卡启动时也识别不了eMMC分区,所以备份eMMC的方法目前只能是打包eMMC的文件系统, 然后通过SDK工具打包成能烧录的文件系统格式,最后替换到镜像烧录包进行烧录。
打包板卡根文件系统¶
1、为了用打包出来的文件系统烧录到其他板卡时能够正常初始化,需要删除初始化判断文件和data分区自动挂载。
1 2 3 4 5 | #初始化判断文件以boot_开头,将其删除
sudo rm /boot/boot_*
#删除/etc/fstab文件中的data分区自动挂载
sudo sed -i '/\/dev\/mmcblk0p7\s\+\/mnt\/data\s\+auto\s\+defaults\s\+0\s\+2/d' /etc/fstab
|
2、用户需要准备一个u盘或者是sd卡, 注意u盘/sd卡的容量一定要比当前系统占用的磁盘空间要大, 否则备份过程将会失败。用户可通过在控制台终端输入以下命令,查看当前系统大小:
1 2 3 4 5 6 7 8 9 10 11 12 | #查看挂载情况和分区大小
df -h
#输出信息如下
Filesystem Size Used Avail Use% Mounted on
/dev/root 2.9G 936M 1.9G 34% /
tmpfs 154M 0 154M 0% /dev/shm
tmpfs 62M 1000K 61M 2% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
/dev/mmcblk0p7 4.1G 28K 3.9G 1% /mnt/data
tmpfs 31M 0 31M 0% /run/user/0
tmpfs 31M 0 31M 0% /run/user/1000
|
其中 / 表示当前根文件系统,占用大小为936M,用户需要确保u盘/sd卡容量大于936M, 又因为总大小是2.9G,单文件不超过4G,所以使用 fat32格式 的U盘或者SD卡备份即可。
3、插入u盘,拔动切换开关向USB A口方向,切换为host,USB-OTG切换开关可以理解成物理接口的切换开关。 切换到USB A接口方向时,主控的USB信号通往USB A接口;切换到Type-C接口方向时,主控的USB信号通往Type-C接口。
4、将拨码开关拨到USB A口方向后,仍需要软件配置usb口为host模式,因为系统默认设置usb为device模式,需要执行以下命令进行切换host。
1 2 | #临时切换host模式
echo host > /proc/cviusb/otg_role
|
5、确保当前系统识别到相应设备文件,设备文件为:/dev/sdx(x为具体英文字母), 如果系统只有一个u盘设备, 那么该设备文件通常为:/dev/sda,用户可通过输入以下命令确认:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #查看设备
lsblk
#信息输出如下
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 7.5G 0 disk
`-sda1 8:1 1 7.5G 0 part
mmcblk0 179:0 0 7.3G 0 disk
|-mmcblk0p1 179:1 0 8M 0 part
|-mmcblk0p2 179:2 0 512K 0 part
|-mmcblk0p3 179:3 0 128K 0 part
|-mmcblk0p4 179:4 0 3G 0 part /
|-mmcblk0p5 179:5 0 40M 0 part
|-mmcblk0p6 179:6 0 14.9M 0 part
`-mmcblk0p7 179:7 0 4.2G 0 part /mnt/data
mmcblk0boot0 179:8 0 4M 1 disk
mmcblk0boot1 179:16 0 4M 1 disk
|
通过设备容量可以看出U盘的设备为sda,而sda下有一个分区sda1,也可以通过U盘插入前后的设备变化确定U盘的设备。
提示
若是直接使用板载的SD卡槽,相应的设备文件则为:/dev/mmcblk1p1。
6、创建backup_rootfs.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 | #!/bin/sh -e
_exit_trap() {
umount ${tmp_rootfs_dir}
rmdir ${tmp_rootfs_dir}
}
_err_trap() {
umount ${tmp_rootfs_dir}
rmdir ${tmp_rootfs_dir}
}
tmp_rootfs_dir=/mnt/data/rootfs_backup
if [ $# -gt 0 ]; then
DEV="$1"
else
echo "please input a storage device!"
exit 0
fi
if [ ! -d ${tmp_rootfs_dir} ] ; then
mkdir ${tmp_rootfs_dir}
fi
trap _exit_trap EXIT
#trap _err_trap ERR
mount $DEV $tmp_rootfs_dir
tar -cvf ${tmp_rootfs_dir}/rootfs.tar \
--exclude=/dev \
--exclude=/proc \
--exclude=/sys \
--exclude=/tmp \
--exclude=/run \
--exclude=/mnt/data \
--exclude=/media \
--exclude=/lost+found \
/*
echo "roofs backup finished!!"
|
备份脚本讲解:
#!/bin/sh -e:-e参数代表命令一旦执行出错,脚本马上停止执行。
_exit_trap:设置脚本执行错误和退出时应当执行的函数,这里主要是卸载和删除临时挂载目录。
tmp_rootfs_dir:U盘/SD临时挂载目录。
trap _exit_trap EXIT:捕捉脚本执行错误和退出的信号,如果捕捉成功,则执行相应处理函数。
mount $DEV $tmp_rootfs_dir:挂载U盘/SD到时挂载目录
tar -cvf ${tmp_rootfs_dir}/rootfs.tar:打包文件系统
–exclude:排除不需要打包的目录
注意
data分区是不打包的,因为烧录系统启动后进行初始化,会将data分区格式化,然后挂载到/mnt/data/
7、用户执行该脚本时,需要输入u盘的设备文件作为参数,如以下命令所示:
1 2 3 4 5 | #添加执行权限
sudo chmod 777 backup_rootfs.sh
#执行打包,需要指定实际u盘/sd操作符
sudo ./backup_rootfs.sh /dev/sda1
|
8、执行该文件后,系统将自动开始备份,在此过程中将不断打印提示消息,结束时打印消息如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /var/lib/dpkg/triggers/File
/var/lib/dpkg/triggers/update-ca-certificates
/var/lib/dpkg/triggers/Unincorp
/var/lib/dpkg/lock
/var/lib/dpkg/updates/
/var/lib/dpkg/cmethopt
/var/lib/dpkg/lock-frontend
/var/lib/ntp/
/var/lib/ntp/ntp.drift
/var/lib/logrotate/
/var/lib/logrotate/status
/var/tmp/
/var/local/
/var/mail/
/var/lock
roofs backup finished!!
|
9、系统备份成功后,拔下u盘,插入到windows电脑上,可查看到rootfs.tar。
生成烧录文件¶
1、需要借助SDK来生成能够烧录的根文件系统文件,将rootfs.tar拷贝到SDK源码的Ubuntu目录下,然后解压,具体路径以情况以电脑上的镜像路径目录为准。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #进入sdk的ubuntu目录
cd sophon-image-build/ubuntu
#如果编译过sdk的需要删除构建产生临时文件目录
sudo rm -rf binary/
sudo rm -rf rootfs/
#创建临时目录
mkdir binary
mkdir rootfs
#解压文件系统到临时目录
tar xvfp rootfs.tar -C binary/
#借助mk-image.sh脚本打包成ext4文件
sudo ./mk-image.sh
|
打包完成后会生成的ubuntu-rootfs.ext4文件。
2、借助SDK改变根文件系统格式,生成能够烧录的根文件系统,在sdk源码顶层目录执行以下命令,初始化编译环境和加载对应的emmc配置文件,具体路径需要根据加载的配置确定:
如果 没有编译过 sdk的执行以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #进入sdk顶层目录
cd sophon-image-build/
#初始化编译环境,输入当前用户的密码
source build/cvisetup.sh
#加载对应的板级配置文件
defconfig sg2000_lubancat_riscv_ubuntu_emmc
#创建目录
mkdir -p install/soc_sg2000_lubancat_riscv_ubuntu_emmc/rawimages
#将build/Makefile的rootfs:ebf-ubuntu-rootfs-prepare注释掉,不打包编译的sdk的.ko和.so进文件系统
sed -i 's/^rootfs:ebf-ubuntu-rootfs-prepare/#rootfs:ebf-ubuntu-rootfs-prepare/' build/Makefile
#打包文件系统
pack_rootfs
#打包完成后恢复build/Makefile配置
sed -i 's/^#rootfs:ebf-ubuntu-rootfs-prepare/rootfs:ebf-ubuntu-rootfs-prepare/' build/Makefile
|
生成的sophon-image-build/install/soc_sg2000_lubancat_riscv_ubuntu_emmc/rootfs.emmc 就是我们需要的文件系统。
如果 编译过 sdk的执行以下命令:
1 2 3 4 5 6 7 8 9 10 11 | #进入sdk顶层目录
cd sophon-image-build/
#初始化编译环境,输入当前用户的密码
source build/cvisetup.sh
#加载对应的板级配置文件
defconfig sg2000_lubancat_riscv_ubuntu_emmc
#打包文件系统
pack_rootfs
|
生成的sophon-image-build/install/soc_sg2000_lubancat_riscv_ubuntu_emmc/rootfs.emmc 就是我们需要的文件系统。
3、对生成的rootfs.emmc进行md5校验
1 2 3 4 5 | #进行md5校验
md5sum install/soc_sg2000_lubancat_riscv_ubuntu_emmc/rootfs.emmc
#信息输出如下
2a66297044f46517582beeadc72e1118 install/soc_sg2000_lubancat_riscv_ubuntu_emmc/rootfs.emmc
|
4、将生成的rootfs.emmc替换到eMMC镜像包
5、修改eMMC镜像包的META目录中的metadata.txt,将生成的md5校验值修改到文件中。
最终使用该emmc镜像包刷到emmc中即可。