苗 军 倪奇志
摘 要:在基于TI DSP的嵌入式应用系统中,升级文件提取方法的效率和易用性对于DSP升级来说特别重要,传统的提取方法耗时且容易出错,为此迫切需要一种快速且可靠的方法。由于DSP编译器最终输出的可执行代码是一种COFF格式的文件,具有结构化、分层次的特点,可以剔除其中与最终下载代码无关的大量冗余信息。为此提出一种基于可执行文件本身结构特点的方法,只提取出与下载相关的数据。实践证明这种方法高效、可靠、灵活易用。此提取器摒弃传统方法的缺陷,为DSP在研发生产中的快速自动升级提供了可靠保证。
关键词:COFF;段;DSP;冗余信息
中图分类号:TP311文献标识码:B
文章编号:1004 373X(2009)02 042 03
Realization and Applicotion of COFF File Extraction Equipment
MIAO Jun,NI Qizhi
(ZTE Corp.Ltd.,Shenzhen,518057,China)
Abstract:In the embedded system based on TI DSP,it is very important to improve the efficiency and usability of updating file extraction.More time is needed and mistakes are always made in traditional way.So an efficient and reliable method is needed.TI DSP compiler outputs executable file which is a file of COFF format.The file is structured and hierarchical,with much redundant information that is not useful for downloading.A method based on the structure of executable file that only the useful data can be extracted.It is proved that this method is efficient,flexible and easy to use.This file extraction resolves the disadvantages of the traditional way,and ensures that DSP can be updated quickly and automatically for R&D; and production.
Keywords:COFF;section;DSP;redundant information
在基于DSP的嵌入式系统中,软件更新通常需要借助仿真器将最新的可执行程序下载到目标板上,然后提取出可执行二进制程序并写入非易失存储器中。或者离线进行二进制文件的提取,然后再由DSP自己或主机芯片完成文件的烧结。在此,有必要简单介绍一下TI DSP可执行程序(目标文件)的结构。TI代码产生工具CCS在经过编译、链接之后,产生的目标文件是一种模块化的文件格式——COFF格式。程序中的代码和数据在COFF文件中是以段的形式组织。在此基础上,再来讨论上面两种方法的弊端。前者只要程序有变化,就会造成新生成目标文件各段的大小和运行地址的变化,其系统引导程序也需要作相应的改动。如果需要对大量的DSP系统进行软件更新或经常需要软件更新的情况下,这种方法的效率非常低下,缺乏灵活性。后者的通常做法是先用工具软件hex6x先将编译器生成的目标文件转换成多个TI格式的.hex文件,再逐一分析.hex文件,手工去掉其中的一些标志信息,并根据需要对文件进行必要的分割合并,最后调用TI提供的工具软件hexbin将各个.hex文件转换成二进制文件,生成文件的数目随应用而变化。这种方法因为涉及到手工操作费时费力不说且很容易出错。同样也存在着灵活性差的弊端,遇到有大量增减以及配置文件有修改的时候就会导致生成文件数目的增减,需要修改DSP或主机boot程序以适应这种改变。通过对目
标文件结构的分析,可以直接提取可供下载的二进制文件。
1 目标文件结构分析
DSP的源程序——C代码或汇编代码在编译后生成的COFF文件包含多个段,默认的情况下,COFF文件包含3个段:.text: 通常包含可执行代码;.data: 通常包含已初始化的数据;.bss: 通常为未初始化的数据保留空间。
当然汇编器和链接器允许自己建立和链接自定义的块,这些块与以上的3个段类似。所有的段分为两大类:已初始化段和未初始化段。这两类段的最大区别就在于是否出现在加载文件中。
下面来分析COFF文件的结构,COFF文件从上到下中依次是文件头、可选的文件头、段头信息表、段头信息表对应的段数据、重定位信息、行号入口表、符号表、字符串表,如图1所示。其中第3~6项包含多个数据区,前4项与加载文件密切相关。
由于前4项与加载文件相关,下面对这4项逐一分析一下:
(1) 文件头:顾名思义,就是COFF文件的头,用来保存COFF文件的基本信息,如段数目、时间戳、符号表位置等。从文件的0偏移处开始,用C的结构描述如下:
typedef struct{
unsigned short usMagicNumber;// 魔法数,标识COFF文件的版本也即平台标识
unsigned short usSectionCounter;// 段头数目
unsigned intuiTimeStamp;// 时间戳,COFF文件生成时间
unsigned intuiSymbolPointer; // 符号表入口基地址,采用绝对地址
unsigned intuiSymbol; // 符号表入口数目
unsigned short usOptHdrSize;// 可选文件头长度。如果有此值为28,否则为0
unsigned short usFlags; // 文件标记
unsigned short usTargitID; // 目标文件标记。若为0x0099,目标文件能在C6x平台上运行
} FileHeader;
文件头中的标记包含了诸如大小端模式、COFF是否为可执行文件等信息,具体解释见参考文献[1]。
(2) 可选头:
可选头接在文件头的后面,也就是从COFF文件的0x0014偏移处开始。长度可以为0。不同平台的可选头,长度和结构都不相同,TI DSP采用的可选头长度为28 B,用C的结构描述如下:
typedef struct {
unsigned shortusMagicNumber; // 魔法数,标识文件类型
unsigned shortusVersion; // 版本标识
unsigned int uiTextSize; // 代码段大小,以byte计
unsigned int uiInitDataSize;// 已初始化数据段大小,以byte计
unsigned int uiUninitDataSize; // 未初始化数据段大小,以byte计
unsigned int uiEntry; // 入口点
unsigned int uiTextBase;// 代码段(.text)基址
unsigned int uiDataBase;// 已初始化数据段基址
} OptinalHeader;
(3) 段头:
段头紧跟在可选文件头的后面(如果可选文件头的长度为0,它紧跟在文件头后),一般COFF包含多个段头,数目就是文件头中的usSectionCounter。它的长度为48 B,用C的结构描述如下:
typedef struct {
charcName[8]; // 段名,长度大于8则为指向符号表的指针
unsigned int uiPhyAddr; // 段的物理地址
unsigned int uiVirtAddr; // 段的虚拟地址,目标运行地址
unsigned int uiSecSize; // 段长度,以byte计
unsigned int uiSecPointer;// 段数据指针
unsigned int uiRelPointer;// 段重定位表指针
unsigned int uiLNOffset; // 行号表指针
unsigned intuiRelSize; // 重定位表长度
unsigned intuiLNSize; // 行号表长度
unsigned intuiFlags;// 段标识
unsigned short usReserved; // 保留字段
unsigned short usMmPageNum; // 内存页号
} SectionHeader;
段头可以说是最重要的头,文件分析提取器的核心就是用它来描述它的。一个COFF文件可以不要其它的节,但文件头和段头这两节是必不可少的。有必要详述一下它的成员:
cName用来保存段名,常用的段名有.text,.data,.bss等。对于用户自定义长度超过8 B的段名,则为指向符号表的指针。
uiVirtAddr是段数据载入或连接时的虚拟地址。对于可执行文件,这个地址是相对于它的地址空间而言。当可执行文件被载入内存时,这个地址就是段中数据的第一个字节的位置。大多数情况下与uiPhyAddr相同。
uiSecSize是段中数据的实际长度,在读取段数据时就由它来确定要读多少字节。
uiSecPointer是段数据在COFF文件中的偏移量,以绝对地址标识。
uiRelPointer是该段重定位信息的绝对地址,它指向了重定位表的1个记录。
uiLNOffset是该段行号表的绝对地址,它指向的是行号表中的1个记录。
uiRelSize是重定位信息的记录数,从uiRelPointer指向的记录开始,到第ulNumRel个记录为止,都是该段的重定位信息。
uiLNSize和uiRelSize相似,不过它是行号信息的记录数。
uiFlags是该段的属性标识,与下载相关的标识如表1所示。
其余定义请见参考文献[1]。
(4) 段数据:
保存各个段的数据,在目标文件中这些数据都以原始数据(Raw Data)形式存在,只有需要下载的数据段才存在该区域。
2 COFF文件分析提取器的工作流程
首先读入目标文件,该文件扩展名为out,以二进制形式读入。分析.out文件的文件头以确定有多少个段,然后逐段分析段信息头,根据段属性标识以确定是否需要下载,段头中的绝对地址、段数据长度等信息作为升级文件的一部分。与需下载的段数据合并成最终的下载文件,为了适应自动化升级的需要,下载文件头部还保留了COFF文件的时戳。值得注意的是因为TMS320C6000 DSP为32位处理器,需要对段落头中段数据长度信息进行32位整型对齐,在此采用Ceil对齐不足的字节以0补齐。具体流程如图2所示。
而COFF文件中的重定位信息、行号入口表、符号表、字符串表等数据区,对于下载文件的制作没有直接联系,可以不做分析。当然,如果在PC上制作可视化工具的话,另当别论,限于篇幅在此不做讨论。
3 COFF文件分析提取器的应用
开发的DSP应用系统一般采用HOST-SLAVE模式,即DSP是作为系统的信号处理协处理单元,HOST保存有所有处理器的下载文件。COFF文件分析提取器在做离线使用时,提取出的下载文件由HOST负责保存、上电加载。HOST的引导程序在上电时读取已经构建好的二进制文件,根据段数目、每段大小以及目标数据的下载地址等相关信息即可完成对目标代码的自动下载。COFF文件分析提取器在线使用时,时间戳就作为版本是否更新的依据,HOST一旦侦测到版本服务器有新版本的COFF文件并得到用户升级确认后,就可启动文件提取器。
目前,这种利用COFF文件分析提取器生成DSP下载文件的方式,已经在中兴通讯多个产品线广泛应用,大大提高了产品的可测试性和易维护性。
4 结 语
在此讨论的方法基于对COFF文件结构的分析,读取DSP编译器生成的.out文件,根据文件本身携带的信息,直接提取生成可供下载的二进制文件。最终生成的二进制文件中包含有与.out文件相同的信息,在下载时利用这些信息即可完成对DSP芯片的加载。
参考文献
[1]Texas Instruments.TMS320C6000 Assembly Language Tools User′s Guide[Z].2003.
[2]Texas Instruments.TMS320C6455,Fixed-Point Digital Signal Processor[Z].2006.
[3]Texas Instruments.TMS320DM642 Video/Imaging Fixed-Point Digital Signal Processor Data Manual[Z].2004.
[4]Texas Instruments.TMS320C645x DSP Host Port Interface(HPI) User′s Guide[Z].2007.
[5]Texas Instruments.TMS320C645x Bootloader User′s Guide[Z].2007.
[6]Texas Instruments.Extracting Equivalent Hex Values from a COFF File[Z].1999.
[7]Texas Instruments.Using OFD Utility to Create a DSP Boot Image[Z].2004.
[8]Texas Instruments.TMS320C6000 Host Port to MPC860 Interface[Z].2001.
[9]Texas Instruments.Using the TMS320C672x Bootloader[Z].2005.
[10]Texas Instruments.TMS320C6000 Tools:Vector Table and Boot ROM Creation[Z].2002.
[11]Texas Instruments.Creating a Second-level Bootloader for FLASH Bootloading on TMS320C6000 Platform with Code Composer Studio[Z].2004.
作者简介 苗 军 男,1971年出生,四川绵阳人,高级工程师,现在中兴通讯股份有限公司从事DSP软件系统设计。
倪奇志 男,1974年出生,汉族,安徽桐城人,硕士,现在中兴通讯股份有限公司从事会议电视硬件系统设计。