原创 最近学习ARM的总结

2014-6-20 13:16 1304 8 8 分类: 工程师职场

 

自己学习ARM几天,真的很辛苦。。。没有人可以问,网上的资料一般对一些初学者困惑的问题轻描淡写,要想真正搞清楚点东西真的很困难。。。国人的劣根**,写书就抄来抄去,写文章就懒得多写一个字。。。下了几篇小P孩学ARM的心得文章,PDF格式的还设成不许复制,人家LINUX的代码都许你随便看随便改,你自己写那么个狗P心得还搞成不许复制,有什么可保密的嘛,这就是中国人,你抄别人的可以,用盗版可以,别人用点你的东西就不行。。。写出来大部分也是为了显摆,为了赚钱。。。浮躁浅薄的国人。。。

实在是因为看那些资料搞的自己很累,所以发点牢骚先。。。

言归正传。。。

一篇杜云海写的ARM学习报告,文章不错,可也是那个问题,不能复制,作者写文章的时候看来还是个小硕,毕竟那时年轻,心胸没有那么宽阔。。。文章详细解释了ARM映象文件的组成和生成,确实很有用的文章,不知道这么重要的问题那些做开发板的公司怎么不讲解一下。

bin文件是真正的可执行文件,axf文件是ARM的调试文件,除了包含bin的内容之外,还附加了其他的调试信息,这些调试信息加在可执行的二进制数据的前面,所以把axf文件写到ARM的指令执行地址(一般是0x0)将不能运行,因为在此地址前几十个字节的数据不是可执行的二进制数据,而是头部的调试信息;而bin文件正是去掉了调试信息的可以执行的“精华”部分。

下面补充几个术语

1。映象文件(image):是指一个可执行文件,在执行的时候被加载到处理器中。一个映象文件有多个线程。它是ELF(Executable and linking format)格式的。呵呵,这个术语出自书上,不知道写书的明白不,先凑合看吧,俺也是边学边写。

2。域(region):一个映象文件由一个或多个域组成。反过来说域是组成映象文件的最大的结构。

3。段(Section):一个域包含一个或多个输出段,一个输出段包含一个或多个输入段。

输入段中包含4类内容:代码、已经初始化的数据、未经初始化的存储区域、内容初始化为0的存储区域。每个输入段有相应的属性,可以为只读(RO)、可读写(RW)以及初始化为0的(ZI)。ARM连接器根据各输入段的属性将这些输入段分组,再组成不同的输出段以及域。

一个输出段包含一系列的具有相同RO、RW和ZI熟悉的输入段。输出段的属性与其包含的输入段的属性相同。在一个输出段内部,各输入段按照一定的规则排序。

一个域包含1~3个输出段,其中各输出段的属性不用。各输出段的排列顺序是由其属性决定的。其中,RO属性的输出段排在最前面,其次是RW属性的输出段,最后是ZI属性的输出段。一个域通常映射到一个物理存储器上,如ROM和RAM等。

4。加载时地址:是映象文件位于存储器(还没有运行,一般在ROM中)时的地址。

5。运行时地址:是映象文件运行时的地址。

之所以有两种地址是因为映象文件在运行时其中的某些域是要移动进系统的新的存储区域(一般为RAM)。比如RW段,在加载时地址为0x6000,位于ROM中,运行时调入0x8000,位于RAM中。

通常一个映象文件中包含若干的域,各域包含若干的输出段。ARM连接器就需要知道以下信息,以决定如何生成相应的映象文件。

(1)分组信息决定如何将各输入段组织城相应的输出段和域。

(2)定位信息决定各域在存储空间中的其实地址。

数据移动:

上面已经提到了RW段加载地址一般在ROM中,运行时需要被搬运到RAM中。加载时状态的映象文件中的RO、RW和ZI的地址都是临时的,他们在运行时要被BootLoader程序搬运到真正的运行时地址。这个地址是连接时设置的地址。这个问题很重要,如果在编译前没有正确的设置运行时地址,那么程序就不能被搬运到正确的RAM地址中运行。

 了解了以上内容,那么就可以打开ADS1.2来看一下具体的设置。

打开ADS的一个工程后,点击如下图所示的Debug Settings按钮打开对话框。

最近学习ARM的总结

 

 

 打开Target Settings对话框后,在左边列表中选择Linker选项。点击它下面的的ARM Linker。然后在右面的选项卡选择Output选项卡。如下图所示。

最近学习ARM的总结

 

看看ADS 开发文档ARM Developer suite 1.2 的ADS_CodeWarriorIDEGuide.pdf 怎么说的

RO Base  This text field sets both the load address and execution address of the region containing the RO

                 section. If you do not enter a value, the value defaults to 0x8000.

意思是,这个文本框设置加载时地址和运行时地址。如果没有设置值,默认时0x8000。这个值将会对应ADS的预定义变量Image$$RO$$Base,指定了RO的base。这个变量可以被初始化程序IMPORT进去。这个参数有两个意思:1,如果生成可执行bin文件烧写到flash中去,那么这个地址就是要烧到flash中的地址(一般是0x0)。这里又出现一个问题,如果使用的ARM芯片是支持memory remap的(如三星的4510芯片),那么可以在bootloader程序中将RO段搬运到RAM中,并把RAM remap 到0x0,这样系统读取RO段的时候就可以在RAM中读了。如果ARM芯片不支持remap(如三星的44b0x),那么RO段不能搬运到RAM中,而在FLASH中读取。

2,如果生成afx调试文件,那么这个地址是调试时加载到RAM中的地址。

根据上面的1,2可知,如果要烧写FLASH 那么RO Base 应该设置成ARM片选的FLASH 的首地址;如果要调试那么RO Base要设置成RAM地址。

RW Base   This text field sets the execution addresses of the region containing the RW and ZI output sections. If you enter a value in this field, the linker creates an image with an execution view that contains two, possibly
non-contiguous, regions:
* a region containing the RO output section
* a region containing the RW and ZI output sections.
If you enter a value for RW Base and select the Split image option, the linker creates an image that has two load regions in addition to two execution regions. In this case the value you enter for RW Base sets both the load address and the execution address of the region that contains the RW and ZI output sections.

这个文本框设定包含RW和ZI输出段的运行时域地址。如果你在这里输入一个值,连接器创建一个包含两个运行时域的映象,这两个域是:

包含RO输出段的运行时域

包含RW和ZI输出段的运行时域

如果你输入了RW Base值并且选择了Split image选项,连接器创建的映象文件分别包含RW输出段和ZI输出段的装载时地址和运行时地址,并都由你输入的RW Base值指定。

对于简单连接方式,当没有输入RW Base值时,映象文件包含一个加载时域和一个运行时域。这时,RO输出段、RW输出段、ZI输出段都包含在一个域中。当输入RW Base值时,映象文件包含两个运行时域,一个包含RO输出段,一个包含RW输出段和ZI输出段。当指定了-split选项时,映象文件又多包含两个加载时域,一个包含RO输出段,一个包含RW输出段和ZI输出段。

以上内容请参考两篇文档:一篇是twentyone 写的《4510B BOOTLOADER (uCLinux)的实现与分析》,另一篇为杜云海写的《ARM映象文件执行机理》

另外一篇文章:刁雪松写的《ARM 执行文件的生成规律分析》可以帮助理解RO,RW,RZ。

以上三篇文档按照名字搜索应该可以在网上搜到下载。

arm in a c
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条