[从0到1搭嵌入式工程]编译打包和升级的实现

工程编译:

我们以nand分区,分为bootloader、kernel、rootfs、homefs为例。
rootfs是linux系统必须的文件目录系统和工具的集合,挂载在跟目录/下,homefs可以认为是我们自己的应用程序、自己的依赖库,放在homefs中,放在/home目录中。

那么编译打包的过程,就是把固件运行所需的全部文件,打成一个包, 在升级时,由升级程序把这个包拆开,把相应的文件保存在对应的分区上。

要完成整个包的编译,要先编出bootloader、kernel和rootfs的整个目录。
生成之后,放在out目录中,开始编我们自己的应用程序。
1:先编译我们自己代码的公共库, 生成.a,放在对应的目录;
2:编译各个模块的应用程序, 并把生成的可执行文件,cp到out/home/app 下供后面打包用;
3:依赖的.a库,已经在编译时编进可执行文件了,依赖的.so库,还需要cp到out/home/lib中;
4:固件需要的工具和文件,比如sd格式化工具, 升级工具,加密工具,提示音文件等等 cp到相应的目录下。
等所有运行需要的文件都放到out目录以后,此时,bootloader和kernel是可执行文件,rootfs和homefs还只是目录和文件,需要我们制作成文件系统。
这里采用jffs2文件系统, 使用mkfs.jffs2工具,把rootfs和home目录下的所有文件,分别制作成 rootfs.jffs2和home.jffs2。
然后把四个独立的文件,使用dd工具再次打包,dd if=boot.bin of=bootimg bs=xx count=xx , dd kernel.img -> sysimg, dd rootfs.jffs2 -> sysimg seek=xxx, 指定offset,把kernel和rootfs打包到一起成sysimg。 同样,把home.jffs2 打包成homeimg。这是打了三个不同部分的img包。
再把boot.bin kernel.img rootfs.jffs2 home.jffs2 使用dd和偏移量, 打包到allimg中。这个包是完整包。
这样就有了四个img, 根据需要升级的部分,决定使用哪个img进行升级。

在home目录下,使用7za工具,对home目录进行 加密 压缩, 压缩成homeimg_m.7z
密码从哪里来?
从0--z中随机生成32位长度的密码。

对homeimg_m.7z 执行md5sum, 
把这几个文件cat到一个文件中
cat md5 password ver homeimg_m.7z > home1
dd if home1 of keyrsa bs=980 count=1 把home1文件的前面777字节放在keyrsa中,当做加密的key。
dd if home1 of home2 bs=980 skip=1 把home1中剩下的放在home2

使用keyrsa 生成公钥, enc_keyrsa, 
cat ver enc_keyrsa home2 > home_m

至此,固件打包完成,主要固件有bootimg/sysimg/home_m/allimg。

升级:

从SD卡升级allimg,
从SD卡升级,是在boot阶段进行的, uboot在监测到SD卡之后, 读取文件名,将文件读取到ram中, 计算文件的crc校验,和从设备flash上读取的对应的crc进行比对, 如果是一致的,就不进行升级。
如果不一致,说明需要升级,这个时候,根据包的类型,是allimg的话,擦除allimg整个区域,如果是bootimg,擦除boot区域,其他一样, 然后把文件整块的数据,写入对应的flash区域,然后把新的crc作为新的环境变量,写入特定的flash区域。重启设备,就是在新的固件下运行了。

网络升级:网络升级的固件一般是经过加密压缩的home_m。
trigger固件进行升级, 固件从服务器端,获取最新的固件的下载url,和固件本身的md5用于校验下载完整性,发送请求,把home_m下载到内存中/tmp/downloadloadimg/home_m, 下载的过程,可以根据ls -l出来的文件大小,与总文件大小的比值,确定下载的百分比。下载成功以后,执行md5sum,和服务器发下来的md5比较,一致为ok。这时,把/tmp/downloadloadimg/home_m mv 到/home/home_m, access 到这个文件,说明下载成功100%。 reboo重启设备。
这个时候,在线升级已经完成了一半。

在kernel启动之后,运行的init.sh脚本中,我们判断/home/home_m , 就开始去进行解压升级。
dd if /home/home_m of /tmp/newver bs=22 count=1, 也就是把固件的前22位取出来,根据打包的顺序, 前面是固件版本号, 和当前的版本号比较,不同就升级。
用工具对home_m 进行解包。
创建 /tmp/update 目录,把home_m放到内存中去,把rsa解码工具 和 7ZA工具也cp过来,开始解。
dd if home_m of ver bs=22 count=1 版本号
dd if home_m of home1 bs=22 skip=1 count=9999999  除了版本号之外的部分
删掉home_m 因为内存可能不够了
dd if home1 of enc_key bs=1024 count=1   取出加密部分
dd if home1 of home2 bs=1024 skip=1 count=9999999  剩余部分
rm home1

使用rsa_pub_dec enc_key dec_enc_key 解密出来,如果dec_enc_key 文件的大小是128, 正确继续,否则退出。
 cat dec_enc_key home2 > home3
 rm home2
  
 dd if home3 of home4 bs=66 skip=1 count=9999999  前66位
 dd if home3 of md5 bs=33 count=1     取 md5
 dd if home3 of pwd bs=33 skip=1 count=1  取 密码
 dd if home4 of verin bs=22 count=1     取版本
 
 dd if home4 of home_m.7z bs=22 skip=1 count=999999999
 
 判断刚才得到的几个版本号是否有问题
 用得到的解压密码,用7za工具解压home_m.7z,
 
在/home/目录下,分目录对比version,如果version不一致, 就把/home/xxx目录下的文件都删掉,然后把/tmp/update/home/目录下对应的目录copy过去。
 
 用md5 对比/tmp目录和/home目录中的md5, 全部都对上 OK。
 把版本文件cp过去, over, 最终升级成功。要比SD卡升要复杂好多。
 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自己动手从0到1写嵌入式操作系统是一个需要全面的学习和深入的项目。首先,我们需要了解嵌入式系统的基本原理和工作原理,包括硬件和软件的结构与交互。然后,我们需要学习嵌入式系统开发的相关知识,如汇编语言、C语言等编程语言,以及相关的开发工具和平台。 接下来,我们可以开始编写嵌入式操作系统的核心部分,包括启动、进程管理、任务调度、内存管理、设备驱动等功能。在编写过程中,我们需要仔细设计系统的结构和接口,确保各个模块之间的协调和数据的正确传递。 在编写操作系统的过程中,我们还需要进行系统的调试和测试,以确保系统的稳定性和正确性。通过调试和测试,我们可以找出系统中的问题并进行修正,提高系统的性能和可靠性。 最后,我们可以将编写的嵌入式操作系统生成为PDF文档,以便于其他人学习和使用。在PDF文档中,我们可以详细描述操作系统的设计思路、实现方法和使用说明,让其他人能够更加容易地理解和使用这个操作系统。 总之,自己动手从0到1写嵌入式操作系统是一项具有挑战性的任务,需要全面的学习和深入的研究。通过学习相关知识、编写核心模块、进行调试和测试,最终可以得到一个完整的嵌入式操作系统,并将其生成为PDF文档,分享给他人。这样的项目将帮助我们深入了解嵌入式系统的原理和开发过程,并提高我们的编程和系统设计能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值