APP下载

一种无操作系统下SOC软件增量升级方法

2016-09-14武柯安李庭胜吴传伟

电子设计工程 2016年2期
关键词:数据包静态代码

武柯安,李庭胜,吴传伟

(中国电子科技集团公司第三十研究所 四川 成都 610041)

一种无操作系统下SOC软件增量升级方法

武柯安,李庭胜,吴传伟

(中国电子科技集团公司第三十研究所 四川 成都610041)

无操作系统下,SOC的软件升级一般采用整体替换的方式,无法独立升级特定的软件模块。通过深入分析SOC目标代码结构以及目标代码间的链接机制,提出了一种软件增量升级的方法。首先,开发者独立编译待升级模块并按照一定的格式修改其目标文件,生成升级数据包。之后,SOC接收该数据包,根据协议规范,加载并修改相关指令,完成最终的升级工作。经实验验证分析,方案可有效地实现无操作系统下SOC软件模块的增量升级。

嵌入式系统;增量升级;动态链接;地址无关编码

无操作系统下的嵌入式处理器一般通过整体替换原代码以实现软件升级维护[1]。由于没有操作系统的支撑,SOC上的软件模块无法通过更换动态链接库的方式独立升级。因此,即使对原始版本的软件只进行了很小的改动,开发端也必须重新编译整个工程。为此,文中通过深入分析SOC目标代码结构以及目标代码间的链接机制,提出了一种针对软件模块进行增量升级的新技术。与传统的整体升级技术相比,这种增量升级技术具有以下几方面的优点:

1)设备升级过程对用户完全透明,用户只需接收设备维护人员远程分发的升级数据包即可,显著降低了设备升级维护难度;

2)在一定程度上实现了上层功能软件与底层硬件无关,提高了代码的可重用性;

3)可有效减小升级数据包的大小,从而降低了对信道资源的开销,提高了较低信道带宽下的升级效率和一次成功率;

文中实验中采用的处理器为某国产SOC,其CPU为32 位RSIC内核CK520,编译器兼容gcc 4.5.1版本。对于开发环境兼容GNU工具链的大部分处理器而言,本文提出的技术手段均适用。

1 可执行代码的链接机制

程序编译通常包括预处理、编译、汇编和链接4个步骤。编译器根据语法规则以及处理器的指令集,将每个源代码文件编译成对应的目标文件。链接器对这些目标文件中的符号进行重定位,将几个独立的目标文件链接为最终的可执行文件。链接分为静态链接和动态链接两种。静态链接由编译工具在编译过程中完成。动态链接则由操作系统在程序运行过程中完成[2]。

文中提出的一种基于软件模块动态加载模型的SOC增量升级技术综合使用了静态链接和动态链接技术,从而有效避免了仅升级部分软件时对整机软件的整体替换。

1.1静态链接

目标文件一般按照可执行链接格式 (Executable and Linking Format,ELF)进行格式化存储[4]。ELF文件起始处为大小固定的ELF Header,该字段给出了节头表(Section Header Table)相对文件起始处的偏移地址。而节头表中则以结构体数组的形式存储了ELF文件中所有段的信息,包括段名称、段类型、段的偏移地址等。在所有段中,一个比较重要的段是“.symtab段”。该段保存了模块中所有符号的信息,包括符号名、符号类型、符号相对段起始位置的偏移等。对于可被静态链接的目标文件而言,还有一类以.rela为前缀的重定位段,如“.rela.text段”、“.rela.data段”等。这些段存储了目标文件中所有符号的重定位信息,包括符号名、符号类型、符号重定位入口(即该目标文件在此位置引用了需重定位的符号)。ELF文件结构如下图所示。

图1 ELF文件的存储结构Fig.1 The structure of ELF files

汇编完成后,各目标文件中所有被引用的外部全局符号的地址均被置为虚地址。静态链接时,链接器将所有目标文件的相似段进行合并,同时分配加载存储地址(Load Memory Address,LMA)和虚拟存储地址 (Virtual Memory Address,VMA)即代码在SRAM中的加载地址[3]。此时,所有全局符号在程序运行时的地址均已确定。之后,链接器根据各目标文件的“.rela.text”、“.rela.data”等重定位段获取重定位入口,再根据“.symtab段”调整重定位入口处的相关指令即可完成各符号的重定位,从而实现各目标文件的静态链接。

1.2动态链接

动态链接的模块可能被加载到任意位置。编译时链接器无法确定模块中各符号的VMA。因此,动态链接一般延迟到模块被加载时才执行。

动态链接模块一般采用地址无关编码(Positionindependent Code,PIC)技术。PIC的代码中,对目标符号的访问包括以下两种情形:

1)访问模块内定义的符号

以CK520的汇编指令集为例,程序先通过如下指令获取“.got段”地址:

其中 bsr指令将下一条指令(即指令 next:lrw r14,offset1)的VMA传给r15。offset1为当前指令相对“.got段”的偏移量,其值在模块编译时已确定。然后程序再通过如下指令,将目标符号的绝对地址存入r7:

其中offset2为目标符号相对“.got段”的偏移量,编译时offset2的值也已确定。这样,不论该模块被加载到何位置,目标符号的地址总能被计算出来并存入r7。显然,模块内定义的符号的寻址代码与模块的加载地址无关。

2)访问模块外定义的符号

如图2所示,访问模块外定义的符号时采用了间接寻址的方式。

图2 模块间符号的寻址方式Fig.2 Addressing method for symbols between modules

以模块2访问模块1中定义的符号func1为例,相应的汇编指令如下:

首先通过“PC指针+offset1”获取“.got段”的地址。“.got段”中存放了所有外部符号的指针。模块被加载时,动态链接器自动更新“.got段”,以确保每个指针所指向的地址都正确。通过 offset2即可获取目标符号的指针。同样的,编译时offset1和offset2的值已确定。

可动态链接的目标文件也采用ELF格式对各个段进行格式化存储[5]。两个比较重要的段是“.reloc段”和“.dynsym段”。其中“.dynsym段”保存了需重定位符号的信息,包括符号名、符号类型、符号重定位入口等。“.reloc段”保存了符号重定位入口。动态链接时,只需根据“.reloc段”和“.dynsym段”中的信息,修改“.got段”中各符号指针的值即可。

1.3软件模块的动态加载模型

假设SOC整机软件进行了良好的模块化设计。模块高内聚、低耦合,每个模块有若干全局函数作为入口,模块内其余函数均为静态函数。整机软件通过调用这些模块实现某些功能[6]。这种情况下,待升级软件可被细化为若干独立的软件模块。这些软件模块可以是某应用程序的专用子模块,如数据包处理协议,也可以是某些应用程序共用的子模块,如硬件驱动程序。此时,对SOC的软件进行增量升级就可以抽象为加载并链接与待升级应用程序相关的软件模块。

图3给出了链接时可能遇到的5种情况。结合前文对两种链接机制的分析,下面对这些情况分别进行讨论。

图3 新模块替换原模块示意图Fig.3 Sketch of new module replacing the original one

1)升级模块替换原工程中的函数

通过对原工程ELF文件的分析,获得原工程中函数Global_Fun1()的LMA,改写此处值为0x00007001(无条件转移指令机器码),并在其后写入升级模块中函数Global_Fun1()的VMA,这样就将升级模块的入口函数静态链接到了原模块中。

2)升级模块访问原工程中的全局函数

函数Global_Fun2()需在升级模块中以类似c++中虚函数的方式定义为外部全局函数。链接时只需修改升级模块“. got段”中Global_Fun2()的指针为原工程中Global_Fun2()的VMA即可。这样就将原模块中的全局函数动态链接到了该升级模块中。

3)升级模块访问原工程文件中的全局变量Global_Var1

升级模块需定义该全局变量并初始化。为保证升级模块和原工程文件模块中同名全局变量的一致性,动态链接器需修改升级模块“.got段”中的Global_Var1的指针,使其指向原工程文件中的Global_Var1。

4)升级模块访问模块内的静态函数

升级模块采用PIC编译技术,对模块内定义的静态函数的寻址代码与模块加载地址无关,因此无需对该函数重定位。

5)升级模块访问模块内的静态变量

同(4),PIC的代码对模块内定义的静态变量的寻址代码与模块的加载地址无关,无需重定位。

以某SOC为例,系统启动时,Bootloader将Flash中从0x000000开始的代码段一次性加载到从0x06000000开始的SRAM中,然后跳转到SRAM中指定地址开始执行。因此可以将Flash的高位地址空间,如从0x7F0000开始到0x800000 的64KB作为升级代码的存储空间,将相应大小的SRAM的高位地址空间,如从0x6040000开始到0x6050000的64KB作为升级代码的加载空间。因此,需修改原Bootloader,使系统启动时加载 Flash中的原始代码和升级代码到相应的SRAM中。

当调用原工程中被升级的软件模块时,静态链接指令将该模块的入口地址直接转移到升级代码加载区中新模块的入口处。同时由于新模块内部采用了PIC等动态链接技术,因此新模块中的寻址指令和加载地址无关,模块可正常工作。这样就实现了软件模块的部分升级。

2 软件模块动态加载的设计方案

如前文所述,为实现软件模块的增量升级,SOC既要将升级模块的入口函数静态链接到原模块中,又要将原模块中的全局符号动态链接到升级模块中。因此SOC需要解析原工程文件和升级工程文件,并根据SRAM的使用状态为升级代码分配加载空间。为了减少SOC端的工作量,实现设备升级过程对用户完全透明,可考虑将这些工作放在开发端进行。这就要求开发端生成的升级数据包中包含完整的链接信息,以便SOC端的升级程序可以根据这些链接信息自动实现待加载机器码的链接、存储和加载。

2.1升级数据包格式定义

升级数据包的文件格式设计如图4所示。

图4 升级数据包格式Fig.4 The format of upgrade data packet

其中“静态链接信息”给出了加载该升级包后需静态链接的符号数及各符号的地址。“升级模块存储区域调整信息”给出了Flash中需要搬移的代码起始地址和长度。“新模块存储地址信息”给出了待加载机器码的存储地址及长度。

2.2开发端生成升级数据包流程

开发端先解析原工程目标文件,记录原工程中的所有函数和变量名称以及地址等信息。然后再解析单独编译的升级模块目标文件。在完成合法性检验(如是否和目标平台匹配、代码是否地址无关等)后,根据嵌入式终端当前 Flash和SRAM的使用状态,为模块分配加载地址和运行地址。然后再解析目标文件的重定位信息,生成静态链接指令并完成原模块中全局符号的动态链接。最后开发端将相关数据打包,生成最终的升级数据包。其工作流程如下图所示。

2.3嵌入式终端处理流程

考虑模块可能被多次升级,每次的升级包中代码长度可能不同,因此嵌入式终端需进行代码存储空间的维护工作,处理流程如图6所示。

如图 7所示,假设 SOC已加载了 Module1、Module2、Module3共3个模块,模块的实际大小分别为Size1、Size2、Size3,开发端预分配的空间大小分别为 Block1、Block2、Block3。为了尽量避免模块升级时因升级代码变长而占用后续模块的存储空间,因此,每个模块预分配的空间一般略大于其实际大小。在这种情况下,嵌入式终端新接收了一个升级模块Module4,其实际大小为Size4,开发端为其分配空间为Block4。

图5 开发端生成升级数据包流程Fig.5 Flowchart of generating upgrade data packet by upper machine

图6 嵌入式终端处理流程Fig.6 Flowchart of SoC dealing with the upgrade data packet

图7 新模块加载示意图Fig.7 Sketch of loading a new module

结合图6所述处理流程,嵌入式终端针对不同情况采取的操作如下:

当Module4为新模块时,将该模块直接加载到Module3之后并将模块中的入口函数静态链接到原工程文件中即可。

当Module4为Module2的更新,且Size4<Block2时,用Module4覆盖Module2,并完成Module4中入口函数的静态链接即可。

当Module4为Module2的更新,且Size4>Block2时,需将Module3向前移动Block2大小,覆盖原Module2,然后加载Module4。最后完成Module3和Module4中入口函数的静态链接即可。

3 结 论

无操作系统下嵌入式处理器软件增量升级方法分开发端和嵌入式终端两部分,其中升级模块的链接工作主要集中在开发端进行,嵌入式终端只需接收升级数据包,并自动调用软件升级子程序即可完成软件升级。因此,设备升级过程对用户完全透明。同时,当模块间的接口固定后,顶层模块和子模块可单独编译,当整机软件固化后,如需对子模块进行改动,独立加载新的子模块即可,顶层模块无需修改。因此,这种增量升级技术在一定程度上实现了上层功能软件与底层硬件无关,提高了代码的可重用性。此外,由于每次仅对部分模块进行升级更换,无需替换整机代码,因此增量升级技术还能有效地减小升级数据包的大小和信道资源的开销,从而提高了较小信道带宽下的升级效率和一次成功率。

经实验验证分析,本文提出的设计方案可有效地实现无操作系统下SOC软件模块的增量升级。

[1]黄绳雄,张荣芬.嵌入式设备远程在线升级技术的研究[J].电子设计工程,2012,20(9):172-173.

[2]张蓝博,张善从,陈蔚薇.嵌入式系统中的代码动态链接模型[J].计算机工程与设计,2008,29(16):4115-4117.

[3]张和君,张跃.基于GNU工具的嵌入式Bootloader设计与开发[J].计算机工程,2006,32(15):277-279.

[4]陈宇,廖湘科,李慰.静态链接动态库的ELF文件软件设计[J].微计算机信息,2008,24(3):162-164.

[5]John R.LevineLinkers&Loaders[M].San Francisco:Morgan Kaufman,1999.

[6]邓伟,许扬婧.一种基于TI TMS320 DSP的软件动态链接技术[J].电子设计工程,2012,20(11):167-169.

An incremental upgrade method for SOC without OS

WU Ke-an,LI Ting-sheng,WU Chuan-wei
(The No.30 Institute of China Electronic Technology Corporation,Chengdu 610041,China)

Generally,software on SOC without OS is upgraded by overwriting the whole codes.Modules cannot be upgraded independently.Therefore the structure and the linking procedure of object files are analyzed.According to the analyses,an incremental upgrade method for SOC without OS is presented.Firstly,the programmer compiles the new module independently.And then the object files are modified according the certain format which will be the final upgrade data packet.After that SOC receives the packet,loads and modifies the codes according to the protocol defined by the package.Experiments show that this method can upgrade software modules on SOC without OS independently and effectively.

embedded system;incremental update;dynamic link;position-independent code

TN492

A

1674-6236(2016)02-0161-04

2015-03-17稿件编号:201503228

武柯安(1990—),男,山西孝义人,硕士研究生。研究方向:信息安全与保密通信、嵌入式系统。

猜你喜欢

数据包静态代码
二维隐蔽时间信道构建的研究*
最新进展!中老铁路开始静态验收
静态随机存储器在轨自检算法
民用飞机飞行模拟机数据包试飞任务优化结合方法研究
SmartSniff
创世代码
创世代码
创世代码
创世代码
油罐车静态侧倾稳定角的多体仿真计算