Linux Shell 合并镜像

在嵌入式linux中系统通常由boot、kernel、rootfs等部分组成,为方便批量烧写一般会把他们生成为一个文件。海思开发工具HiTool就提供了这样的界面功能来制作合并镜像,通过生成的文件分析发现,这个功能的本质就是按分区组合多个二进制文件,且当指定区域段数据不足时使用0x00补全。了解规则后就自己手撸一个合并镜像功能,这样完成编译后就可以直接生成一个完整的烧写镜像了。

这里选择shell脚本来实现,其中主要涉及的指令为cat重定向statdd,它们分别用来进行文件拼接、空白区计算与域填充功能。

切换路径

第一行指定解释器,第二行移动路径到我的镜像输出路径。

#!/bin/bash

cd out

删除旧的文件

这里定义合并后的镜像文件名称,如果这个文件已经存在那么就把它删除。

outfile='img.flash'
if [ -f $outfile ]
then
    rm -rf $outfile
fi

填充 uboot

先设定生成的uboot文件名称,然后获取这个文件的长度,我这里镜像中uboot设定的区域长度是1M大小。拼接文件使用>>符号进行追加。因为合并文件中数据不足区域要补0,计算得到空缺长度addlen后,使用dd指令从zero中获取一块相同长度的数据填上,这样第一部分就完成啦。

file='u-boot-hi3516ev200.bin'
len=`stat -c "%s" $file`
alllen=$((1 * 1024 * 1024))

addlen=`expr $alllen - $len`
echo len=$len alllen=$alllen addlen=$addlen

cat $file >> $outfile
dd if=/dev/zero bs=$addlen count=1 >> $outfile

填充 kernel

这部分语法与上面一致,其中kernel区域指定长度为4M大小。

file='uImage'
len=`stat -c "%s" $file`
alllen=$((4 * 1024 * 1024))

addlen=`expr $alllen - $len`
echo len=$len alllen=$alllen addlen=$addlen

cat $file >> $outfile
dd if=/dev/zero bs=$addlen count=1 >> $outfile

填充 rootfs

file='rootfs_uclibc_64k.jffs2'
len=`stat -c "%s" $file`
alllen=$((11 * 1024 * 1024))

addlen=`expr $alllen - $len`
echo len=$len alllen=$alllen addlen=$addlen

cat $file >> $outfile
dd if=/dev/zero bs=$addlen count=1 >> $outfile

填充完根文件系统后,整个合并的镜像文件就算完成了。接着可以打印一下辅助信息做简说明要判断,HiTool工具提供了按地址烧写的操作,我们可以把需要填写的十六进制文件长度也显示出来。

echo filepath: `pwd`/$outfile
alllen=`stat -c "%s" $outfile`
echo filesize: $alllen `printf "(HEX:%x)" $alllen`

至此,把这些代码都写到一个脚本文件中,在make的时候调用一下就可以直接生成合并的镜像文件发出去啦。测试运行效果

posted @ 2021-02-23 20:32  派大海星  阅读(357)  评论(0编辑  收藏  举报