记录一些简单的ARM的映像文件的内容组成及原理。
1.ARM映像文件(axf和bin文件)的组成。
ARM是32位处理器,地址位宽也是32位,因此其存储器的映射范围可以达到4GB空间。基本上对于ARM处理器,上电或复位时都会从0x00000000出开始执行指令,因此必须保证映像文件的起始位置放置在0x00000000处,无论是采用NAND或NOR flash,这一点都无法改变。正确放置之后,处理器会获取到正确的指令从而顺序执行。
ARM的映像文件(即可执行文件)。生成的ARM映像文件有分为axf和bin两种。bin文件时真正的可执行文件,而axf文件是ARM特有的调试文件,除了包含了bin文件的内容外还包含了很多其他的调试信息。在axf的文件头和文件尾部都包含了可以用在ADW或AXF的load image的调试中。
2.ARM的映像文件的加载域和运行域的不同
加载域映像文件。尽量简单地说,即那些可执行文件例如bin文件,一般由域组成。而域由最多的三个输出段组成即(RO、RW、ZI),RO是只读的代码段,RW是可读写的数据段和ZI未初始化的数据段。分析bin映像文件的具体内容,也可以印证上面的内容,基本上在bin的前半部分是RO的内容而后半部分是RW的内容,ZI由于是为初始化数据,因此不需要保存在bin文件中。即bin文件时RO+RW的内容的集合。而这三个输出段又是可以由多个输入段组成的,因为在汇编文件中,可以设置多个段名称,只需要在链接的时候链接到相应的位置即可,因此多个输入段可以对应到一个输出段上。上面所说的bin文件都是指的是加载域的情况,因为这都是可执行文件被初始放置在flash中时各个部分的分布情况,即是加载到系统时的情况,所以叫加载域。但系统此时是并不能运行的。
加载域的映像文件必须顺利地过渡到运行时域,这时系统才能够正确地被执行。因为有个很明显的一点,程序一般都固化在flash中。而flash是只读的,上面也说到可读写的RW数据段的内容是跟在RO段后面(即bin文件中),被放置在了flash上,RW段要求可读写,flash显然不满足要求,因此加载域必须过渡到运行时域。最直观的理解就是,我们必须把RW段的内容转移到可读写的SDRAM或SRAM上去,因此就引发了运行域的问题。
如何转换,如何保证前面RO段的程序的内容能够正确地寻址到被转移了的RW段的内容。因为大部分汇编程序的转移指令都是绝对寻址的,比较少的伪指令能提供相对寻址,绝对寻址的效率显然比较高。因此我们必须在代码中就必须知道将来运行时RW段被放置在了什么一个地方。在程序链接之后,所有的代码中的地址都将固定。解决这样的问题也并不复杂,需要链接器确保RO段的运行时起始地址和RW段的运行时起始地址,这就是为什么我们要在ADS设置连接选项ro_base和rw_base的目的了。所有的RO段的地址都是基于ro_base指定的内容,而所有代码段的内容也是基于rw_base上的,这样程序在链接后就已经确定了所有的相对地址,剩下的事就是将相应的段的内容从加载域的位置搬移到运行时域的位置。
这样的代码搬移的工作如果是在调试状态的话,一般调试器就会帮我们做好所有事情了,而如果是在非调试状态,就需要我们自己复制代码段的搬移工作,有趣的是,不少ARM都支持从NAND flash中启动,而NAND flash本身就是不能直接执行的,需要将代码搬移到SDRAM中,因此这里的运行时域和加载域的区别被屏蔽掉了。一般我们做代码搬移这样的工作的时候,采用的跳转地址都要用相对跳转指令。这样的好处是,无论用户将程序加载到什么地址,代码搬移指令都能正确地将程序从加载域转换到运行时域,从而保证程序顺利执行。
|