ADS1.2中RO base与RW base

简介: <span style="color:#800080">ARM映像文件</span> <p>           ARM中的各种源文件(包括汇编文件,C语言程序及C++程序等)经过ARM编译器编译后生成ELF(Executable and linking format)格式的目标文件。这些目标文件和相应的C/C++运行 时用到的库经过ARM连接器处理后,生成ELF格式的映像文件(imag
ARM映像文件

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

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

      ARM映像文件的组成:ARM映像文件是一个层次性结构的文件,包括了域(region),输出段(output section)和输入段(input section)。一个映像文件由一个或者多个域组成;每个域最多由三个输出段组成组成;每个输出段又包含一个或者多个输入段;各输入端包含了目标文件中的代码和数据。

相关术语:

1。域 (region):一个映象文件由一个或多个域组成。反过来说域是组成映象文件的最大的结构。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。加载域就是映像文件被静态存放的工作区域,一般来说flash里的整个bin文件所在的地址空间就是加载域,当然程序一般都不会放在flash里执行,一般都会搬到sdram里运行工作,它们在被搬到sdram里工作所处的地址空间就是运行域。一个域通常映射到一个物理存储器上,如ROM和RAM等。

2。段(Section):一个域包含一个或多个输出段,一个输出段包含一个或多个输入段。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,每个输入段都有相应的属性,可以为只读(ro),可读写的(rw)以及初始化成0的(zi)。

3。RO,RW,ZI:输入段中包含4类内容:代码、已经初始化的数据、未经初始化的存储区域、内容初始化为0的存储区域。每个输入段有相应的属性,可以为只读(RO)、可读写(RW)以及初始化为0的(ZI)。ARM连接器根据各输入段的属性将这些输入段分组,再组成对应属性的输出段。对于加载域中的输出段,一般来说ro段后面紧跟着rw段,rw段后面紧跟着zi段。在运行域中这些输出段并不连续,但rw和zi一定是连着的。zi段和rw段中的数据其实可以是rw属性。

       注:(1); C中的指令以及常量被编译后是RO类型数据。

       (2); C中的未被初始化或初始化为0的变量编译后是ZI类型数据。

       (3); C中的已被初始化成非0值的变量编译后市RW类型数据。

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

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

 通常一个映像文件中包含若干个域,各个域又包含若干的输出段。ARM连接器就需要知道如下信息以决定生成相应的映像文件。烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。

    *分组信息 :决定如何各将输入段组织成相应的输出段和域。
    *定位信息 :决定各个域在存储器空间中的起始地址。

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

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

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

  数据移动:

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

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

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

ARM映像文件 - tianwaike1 - 开拓-进取

 

看看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   这个文本框设定包含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输出段。

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

      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 (在加载域中,是RW的起始地址)
     |Image$$RW$$Base| :RW段起始地址 (在运行域中即运行的时候,是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段在运行域中的搬运过程:

 ;Copy and paste RW data/zero initialized data
    ldr r0, =|Image$$RO$$Limit|     /*取RO区末地址后面的地址,即RW数据源的起始地址*/
    ldr r1, =|Image$$RW$$Base|    /*取RW区在RAM里的执行区起始地址,即编译器选项RW_Base指定的地址*/
    ldr r3, =|Image$$ZI$$Base|       /*取ZI区在RAM里面的起始地址*/

    
    ;Zero init base => top of initialised data
    cmp r0, r1      /* 比较ROM区中数据段首地址和RAM区中RW段目标首地址*/
    beq %F2       /*相等代表当前已经是在RAM中运行*/(F表示after,B表示before,r0与r1相等则转跳)
                             /*B %F2表向前跳到标号为2的Lable处*/
1      
    cmp r1, r3               /*不相等则和RAM区中ZI段的目标地址比较*/ 
    ldrcc   r2, [r0], #4     /*如果r1<r3,则把r0地址上的数据读出到r2中,然后r0=r0+4*/     
    strcc   r2, [r1], #4     /*如果r1<r3,则把r1地址上的数据读出到r2中,然后r0=r0+4*/
    bcc %B1              /*如果r1<r3,则跳转到Lable为1处继续执行*/
2      
    ldr r1, =|Image$$ZI$$Limit|          /* 取ZI段的结束地址 */
    mov r2, #0                                /*将r2赋值为0*/
3      
    cmp     r3, r1      ; Zero init
    strcc   r2, [r3], #4    /*如果r3<r1,将r2内容写入到r3地址单元中,然后r3=r3+4*/     
    bcc     %B3            /*如果r3<r1,则跳转到Lable为3处继续执行*/

相关文章
|
3月前
|
Oracle 关系型数据库 应用服务中间件
Supplemental Readme - Grid Infrastructure Release Update 12.2.0.1.x / 18c /19c (Doc ID 2246888.1)
Supplemental Readme - Grid Infrastructure Release Update 12.2.0.1.x / 18c /19c (Doc ID 2246888.1)
31 7
|
10月前
|
SQL 存储 监控
Supabase
Supabase 是一款开源的后端服务平台,可以帮助开发人员快速构建和部署应用程序。Supabase 提供了基于 PostgreSQL 数据库的服务,支持实时数据同步、身份验证和授权等功能。
867 1
|
分布式计算 资源调度 Hadoop
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
ROOT_DIR=os.path.abspath(os.path.join(p, '..', 'data/raw/'))代码含义
这行代码的作用是设置一个名为 ROOT_DIR 的变量,其值为指向项目根目录下的"data/raw/"目录的绝对路径。下面是对每个部分的详细解释: os.path.abspath():这个函数返回参数路径的绝对路径,也就是完整路径,包括盘符或根目录和所有子目录。 os.path.join(p, '..', 'data/raw/'):这个函数使用操作系统特定的路径分隔符将参数连接起来,并返回一个新的路径。这里,它连接了当前工作目录(也就是代码所在的目录)的父目录("..") 和"data/raw/",生成了一个相对路径。 p:这是一个之前定义过的变量,代表了当前工作目录的路径。 ROOT_DI
The Soft Link between IM Level Storage Location and WM level Storage Type?(1)
The Soft Link between IM Level Storage Location and WM level Storage Type?(1)
The Soft Link between IM Level Storage Location and WM level Storage Type?(1)
The Soft Link between IM Level Storage Location and WM level Storage Type?(2)
The Soft Link between IM Level Storage Location and WM level Storage Type?(2)
The Soft Link between IM Level Storage Location and WM level Storage Type?(2)
|
Java Android开发
【错误记录】Android 应用配置第三方 so 动态库 ( /data/app/comxxx==/base.apk/lib/arm64-v8a]couldn‘t find “libx.so“ )
【错误记录】Android 应用配置第三方 so 动态库 ( /data/app/comxxx==/base.apk/lib/arm64-v8a]couldn‘t find “libx.so“ )
525 0
【错误记录】Android 应用配置第三方 so 动态库 ( /data/app/comxxx==/base.apk/lib/arm64-v8a]couldn‘t find “libx.so“ )
|
安全 API
Read-only dynamic data
lwn文章翻译,原文[链接](https://lwn.net/Articles/750215/) ## 简介 本文主要讲述的是一种动态内存的只读保护机制。 ## 原文 内核开发者可以对想保护的数据设置为read-only权限,借助于MMU来避免恶意攻击者的篡改。kernel目前已经支持只读内存保护,但这些内存必须在操作系统自举完成前被初始化,所以局限性很大。Igor Stoppa的
958 0
|
关系型数据库 MySQL