嵌入式系统那些事-xilinx multiboot番外篇

0、背景

        前面我们通过文件视角解读了arm体系结构的指令集和汇编,在开启解读elf文件之前,我们先来看一下一个bin文件是如何升级到嵌入式设备上,然后加载运行的。特别是如果在升级的过程中出现断电等异常情况,导致flash中的程序不可执行时,有什么样的手段可以保证系统可以起来。本文先去简单介绍了一个升级流程,然后以xilinx multiboot实现双区备份为例,帮助读者理解保障系统可靠性的方案。

1、文件的升级和运行过程

        下面的的这张图中,我们的嵌入式c语言文件或者汇编文件,经过一系列的编译和链接后,就变成了可以在设备上跑的可执行bin文件。与那种纯软的执行软件不同,二进制bin文件需要通过上位机传到嵌入式设备上,然后再由设备加载运行。这个过程是怎样的,在这个过程中又会遇到哪些异常情况呢。

 1.1 嵌入式设备升级过程

         如下图所示是嵌入式设备的一种常见的升级方式,可执行的bin文件通过tftp/ftp/sftp的方式下载到嵌入式设备的内存中,然后再将其烧录到flash中规划的位置;设备启动后,就会将每个组件的bin文件依次从flash中加载到ddr中运行。这是升级和启动的全流程,看起来很简单,但是在我们的实际工作中,经常会遇到板子变砖或者启动不起来的情况。如果只是裸板还好说,但是如果遇到已经装配好的设备,就要拆机,要是发生在生产阶段,那这将是一个致命的问题,如果流向了客户,问题就会变得更加棘手。通常情况下,我们要保证在各种升级异常的场景如断电,或者软件本身的bug导致系统起不来时,设备不会变砖,还可以救活,这就需要对关键的组件进行双备份。

        双区备份的方案无外乎要么对全部的组件做备份,要么只对关键的组件做备份。第一种方案通常需要较大的flash空间,这对成本上有很大挑战,所以从节约成本的角度看,还是选择第二种方案。只对关键组件做备份,首要的肯定是bios,只要它能起来,起码可以保证我们的设备是可以救活的。其他的关键组件就是跟通信链路有关的备份了,这样就可以保证设备还可以通过备用的链路传输升级文件,让设备活过来。在实现方案的选择上,需要根据具体的场景、成本和资源综合考虑,有时候某些芯片本身就具备这样的能力,只需要你做一些简单的适配即可。下面我们就简单看一下xilinx的multiboot特性。

2、基于xilinx multiboot的双区备份实现案例

        在xilinx的zynqmp版本中有这样一个特性multiboot,支持备份多个boot文件,当其中的一个boot起不来时,可以自动跳转到另外一个boot启动,其基本的原理如下图所示。初始时,都是从0地址开始加载有效的boot,在加载前首先会检查头部是否正常,如果发现头部异常或者是在交接给uboot前的某个阶段发生了错误,就会让multiboot寄存器的值加1,注意每加1,就移动32KB的位置,依次循环,直到找到另外一个备份的boot头部为止,就把这个boot开始的信息搬移到ddr中运行。

        借助于上面的这个特性,我们就可以实现一个最简单的boot双区备份,首先是我们在升级的时候,每次只固定的升级一个boot,如从0开始的boot,在flash 1M的位置处放置一个可以起来的boot,但是不会去动它,就在异常的情况下从这个boot启动。接下来,当我们检测到异常情况时可以直接给multiboot赋值为0x20,即1M的位置,一次就可以跳转到备区部分。

        如何验证上述方案的可行性呢,笔者提供了两条uboot下的命令,如上图所示的uboot bios命令行,其中一个可以读取multiboot寄存器的值,另一个可以改变multiboot的值,我们可以试验在1M的位置放置一个boot,然后直接修改multiboot的值为0x20,然后复位,看是否可以找到想要的boot。感兴趣的读者可以自己实验一下。

3、小结

        本文简单介绍了一个二进制文件的升级过程,已经工程实践中,如果做好可靠性,保证设备的升级和启动正常,如果发生异常时如何保证系统可以救活。并且举了xilinx的multiboot的例子,让读者可以直观的感受这个实现方案和实验方法。

猜你喜欢

转载自blog.csdn.net/linus_ben/article/details/124416888
今日推荐