微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM开发各种烧写文件格式说明(ELF、HEX、BIN)

ARM开发各种烧写文件格式说明(ELF、HEX、BIN)

时间:11-11 来源:互联网 点击:

全局变量,局部变量将在运行时被存放在堆栈中,不会在.data或.bss段中出现。
.bss:未初始化的全局变量,在这里只是一个占位符,在object文件中并没有实际的存储空间。
.symtab:符号表,用于存放程序中被定义的或被引用到的全局变量和函数的信息。
.rel.text:一个保存着一系列在.text中的位置的列表。这些位置将在linker把这个文件与其它object文件合并时被修改,一般来说,这些位置都是保存着一些引用到全局变量或者外部函数的指令。引用局部变量或者本地函数的指令是不需要被修改的,因为局部变量和本地函数的地址一般都是使用PC相对偏移地址的。需要注意的是,这个section和下面的.rel.data在运行时并不需要,生成可执行的ELFobject文件时会去掉这个section。
.rel.data:保存全局变量的重定位信息。一般来说,如果一个全局变量它的初始化值是另一个全局变量的地址,或者是外部函数的地址,那么它就需要被重定位。
.debug:保存debug信息。
.strtab:一个字符串表,保存着.symtab和.debug,和各个section的名字。.symtab,.debug和sectiontable里面,凡是保存name的域,其实都是保存了一个偏移值,通过这个偏移值在这个字符串表里面可以找到相应得字符串。
下面仔细讨论一下.symtab:
每一个可重定位的object文件,都会有一个.symtab。这个符号表保存了在这个object文件中所有被定义的和被引用的符号。当源程序是C语言程序时,.symtab中的符号直接来源于C编译器(cc1)。这里所说的符号主要有三种:
1)在这个object文件中被定义的可以被其他object文件全局符号。在C语言源程序中,主要就是那些非静态(没有static修饰的)的全局变量和非静态的函数。在ARM汇编语言中,就是那些被EXPORT指令导出的变量。
2)在这个object文件中引用到,但是在其他文件中定义的全局变量。在ARM汇编语言中就是通过IMPORT命令引入的变量
3)本地变量。本地变量只在本object文件内可见。这里的本地变量指的是连接器本地变量,应该和一般的程序本地变量作区别。这里所指的本地变量,包括用static修饰的全局变量,object文件中section名称,源代码文件名称。一般意义上的本地变量,是在运行时由系统的运行时环境管理的,linker并不关心。
每个符合上面条件的符号在.symtab文件中都会有一个数据项。这个数据项的数据结构是:

Typedefstruct{
intname;//符号名称,其实就是.strtab的偏移值
intvalue;//在section中的位置,以相对section地址的偏移表示
intsize;//大小
chartype;//类型,一般是数据或函数
charbinding;//是本地变量还是全局变量
charreserved;//保留的位
charsection;//符号所属的section。可选有:.text(用数字1代表),.data(用数
//3代表),ABS(不应被重定位的符号),UND(在本object文件
//中未定义的符号,可能在别的文件中定义),COM(一般的未初//始化的变量符号)。
}ELF_sym

现在假设组成应用的各个模块都已经被汇编,构建出了可重定位的object文件。这些object的结构都是一样的,有各自的.text,.datasection,有各自的.symtab.GCC下一步要做的就是使用linker(ld),把这些object文件,加上必要的库连接成具有绝对运行时地址的可执行文件,就是可执行的ELF格式的文件。
Linker的连接动作可以分为两部分:
1)符号解析。确定引用符号的指向。
2)符号重定位。合并section,分配运行时环境地址,引用符号重定位。
符号解析:
在一个object文件中,有指令定义了符号,也有指令引用了符号。可能存在这样一种情况,一个被引用到的符号,有多重的定义。符号解析的作用就是确定,在这个object文件中,一个符号引用真正引用的是哪个符号。
在编译的时候,除了在本文件中定义的全局变量会由编译器生成一个符号表项之外,当发现一个被引用到的符号在本文件中并没有被定义,编译器也会自动产生一个符号表项,把确定这些引用的工作留给linker。汇编器在汇编时将读取这些符号表项,生成.symtab。在读取的过程中,如果发现有在无法确定的符号引用项,汇编器会为这些符号额外生成一个数据项,称作重定位数据项,存放于rel.text或rel.datasection中,交由linker确定。下面是重定位数据项(relocationentry)的数据结构:

Typedefstruct{
intoffset;//指明需要被重定位的引用在object中的偏移,实际上就是需要被重定位的引用
//在object中的实际位置
intsymbol;//这个被重定位的引用真实指向的符号
inttype;//重定位类型:R_ARM_PC24:使用24bit的PC相对地址重定位引用
//R_ARM_ABS32:使用32bit绝对地址重定位引用
}Elf32_Rel

Linker需要解析的,就是那些被生成了重定位数据项的引用。Linker将根据C语言定义的规则,对于每一个重定位数据项,在输入的各个object文件中查找适合的符号,把这个符号填入symbol项中。但是由于还不知道这个符号的真实地址,所以现在就算知道了引用的真实指向,但我们还是不能确定这个引用指向的地址。
符号重定位:
符号重定位用来解决上面的问题。Linker首先进行section的合并。Linker合并object文件的过程很简单,一般就是相同属性的section合并,例如不同object文件的.textsection将被合并成一个.text。同样,.symtabsection也被合并成一个.symtab。这里面涉及到两个问题:
1)各个object文件合并的顺序。这个问题涉及到最终指令和符号的运行地址。最为重要的是,究竟是哪个section排在最前头?在ARMRAW系统得开发过程中,这个最为重要。ARM系统CPU上电后,系统会自动的从0x00000000地址取指令并执行,这个地址上映射着存储器。这个动作是不

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top