织梦CMS - 轻松建站从此开始!

罗索

ARM映像文件简介及简单的初始化C运行环境

jackyhwei 发布于 2011-12-07 14:04 点击:次 
ARM映像文件一开始总是存储在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面执行,也可以转移到速度更快的RAM中执行;而RW和ZI这两部分是必须转移到可写的RAM里去,其实RW包括ZI区域,ZI区域放的是未赋值的全局变量,RW 区域放的是已赋值(赋0除外)的全局变量。
TAG:

1.ARM映像文件

      ARM中的各种源文件(包括汇编文件,C语言程序及C++程序等)经过ARM编译器编译后生成ELF格式的目标文件。这些目标文件和相应的C/C++运行 时用到的库经过ARM连接器处理后,生成ELF格式的映像文件(image),这种ELF格式的映像文件是一种可执行文件,可被写入嵌入式设备的ROM 中。

      ARM映像文件的组成:ARM映像文件是一个层次性结构的文件,包括了域(region),输出段(output section)和输入段(input section)。

      一个映像文件由一个或者多个域组成;每个域最多由三个输出段组成组成;每个输出段又包含一个或者输入段;各输入端包含了目标文件中的代码和数据。

      所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。加载域就是映像文件被静态存放的工作区域,一般来说flash里的整个bin 文件所在的地址空间就是加载域,当然程序一般都不会放在flash里执行,一般都会搬到sdram里运行工作,它们在被搬到sdram里工作所处的地址空 间就是运行域。

      我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,每个输入段都有相应的属性,可以为只读(ro),可读写的(rw)以及初始化成0的 (zi)。ARM连接器根据各输入段的属性将这些输入段分组,再组成对应属性的输出段。对于加载域中的输出段,一般来说ro段后面紧跟着rw段,rw段后 面紧跟着zi段。在运行域中这些输出段并不连续,但rw和zi一定是连着的。zi段和rw段中的数据其实可以是rw属性。

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

      *分组信息 :决定如何各将输入段组织成相应的输出段和域。

      *定位信息 :决定各个域在存储器空间中的起始地址。

      根据映像文件中地址映射的复杂程度有两种方法告诉ARM连接器这些相关的信息。

      (1)当映像文件中最多包含两个域,每个域最多有三个输出段时,可以使用连接器选项告诉连接器相关的地址映射关系。选项有-ropi,-rwpi,-ro_base,-rw_base,-split等。

      (2)当映像文件地址映射关系更复杂时,可以使用一个配置文件(分散加载文件)告诉连接器相关的地址映射关系。

2.简单的初始化用户程序的执行环境

      ARM映像文件一开始总是存储在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面执行,也可以转移到速度更快的RAM中执行;而RW和ZI这两部分是必须转移到可写的RAM里去,其实RW包括ZI区域,ZI区域放的是未赋值的全局变量,RW 区域放的是已赋值(赋0除外)的全局变量。所谓应用程序执行环境的初始化,就是完成必要的从ROM到RAM的数据传输和内容清零。

      先介绍几个必要的符号,编译器使用下列符号来记录各段的起始和结束地址:

     |Image$$RO$$Base| :RO段起始地址 

     |Image$$RO$$Limit| :RO段结束地址加1

     |Image$$RW$$Base| :RW段起始地址

     |Image$$RW$$Limit| :ZI段结束地址加1

     |Image$$ZI$$Base| :ZI段起始地址

     |Image$$ZI$$Limit| :ZI段结束地址加1

     这些符号的值是根据链接器中设置的中ro-base和rw-base的设置来计算的。 由于rw和zi相连,|Image$$ZI$$Base|就等于|Image$$RW$$Limit| .其它的值都是编译器自动计算出来的。我们还可以通过scatter文件更详细得指定各个输出段的工作地址。

     初始化用户执行环境主要是把ro、rw、zi三段拷贝到指定的位置。

     下面的程序是rw、zi段在运行域中的搬运过程:

                IMPORT |Image$$RO$$Limit|  

                IMPORT |Image$$RW$$Base|   

                IMPORT |Image$$ZI$$Base|   

                IMPORT |Image$$ZI$$Limit|  

                IMPORT Main   ; 声明C程序中的Main()函数

                AREA Start,CODE,READONLY ; 声明代码段Start

                ENTRY     ; 标识程序入口

                CODE32     ; 声明32位ARM指令

Reset        LDR   SP,=0x40003F00

               ; 初始化C程序的运行环境

                 LDR      R0,=|Image$$RO$$Limit|   

                 LDR      R1,=|Image$$RW$$Base|  

                 LDR      R3,=|Image$$ZI$$Base|     

  

                CMP      R0,R1    

                BEQ      LOOP1    

LOOP0      CMP      R1,R3       

                LDRCC    R2,[R0],#4     

               STRCC    R2,[R1],#4    

               BCC      LOOP0

LOOP1       LDR      R1,=|Image$$ZI$$Limit|

                MOV      R2,#0

LOOP2       CMP      R3,R1

                STRCC    R2,[R3],#4         

                BCC       LOOP2           

                 Main   ; 跳转到C程序代码Main()函数

(kellycan)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201112/15422.html]
本文出处:kellycan.blogbus.com 作者:kellycan 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容