现在的位置: 首页 > 综合 > 正文

ARM7的存储器映射及分散装载

2013年06月07日 ⁄ 综合 ⁄ 共 2546字 ⁄ 字号 评论关闭
  • 缺省的存储器映射

如果用户在程序编译时没有提供指定映象的存储器分布,ADS将为生成的目标代码和数据分配一个缺省的存储器映射图。

 


 

目标映象被连接到0x8000处,存储和执行区域都位于该地址空间。从前至后,依次为RO(只读)RW(读写)ZI(零初始化)部分。在ZI部分之上为HEAP,故HEAP的确切地址在连接时才能确定。但是STACK的基地址是在运用程序启动时由Semihosting操作提供。ARMulator返回配置文件peripherals.ami中的设置值,缺省为0x08000000Multi-ICE返回的是调试器内部变量top_of_memory的值,缺省为0x00080000

 

连接器布局规则

 

映象按属性以RO-RW-ZI次序进行排列,同一种属性里代码优于数据。连接器将输入段根据名字的字母顺序进行排列,输入段的名字与汇编代码里块名字指示一致(汇编程序中使用AREA关键字)。在输入段中,不同对象的代码和数据放置次序与在连接器命令行中指定对象次序一致。如果需要灵活分配,则需要控制代码和数据布局的机制Scatterloading

  • 分散装载

实际嵌入式系统中,用户的目标硬件通常有多个存储器设备位于不同的位置,这样一来Scatterloading需要通过一个文本文件来指定一段代码或数据在加载和运行时在存储器中的不同位置。这个文本文件在命令行由-scatter指定。而scatterfile可以为每一个代码或数据区在加载和执行时指定不同的存储区域地址。其中装载区:当系统启动或加载时应用程序的存放区;执行区:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行块。映象中所有的代码和数据都有一个装载地址和运行地址(二者可能相同也可能不同)。系统启动时,C函数库中的__main初始化代码会执行必要的复制及清零操作,使应用程序的相应代码和数据段从装载状态转入执行状态。

 


 

 

在上图中,只有一个加载块,其实地址为0。该加载块对应两个执行块,一个包含所有的RO代码和数据,执行地址与装载地址相同;另一个起始地址为0x10000的执行块,包含所有的RWZI数据。这样当系统开始启动时,从第一个执行块开始运行(执行地址等于装载地址),在执行过程中,有一段初始化代码会把装载块中的一部分代码转移到另外的执行块中。

LOAD_ROM 0x4000

{

EXE_ROM 0x00000 0x4000; Root region

{

       *(+RO);   All code and constant data

}

RAM 0x100000 0x8000

{

       *(+RW, +ZI); all non-constant data

}

}

 

 

 

 

 

 

 

 

 

 

 


在分散文件中放置对象

        在大多数应用中,有时用户需要特定控制代码和数据段的放置位置。则可用通过scatter文件对单个目标文件进行定义实现。可以使用+FIRST+LAST分散加载指令。典型例子是在执行块的开始处放置中断向量表格:

LOAD_ROM 0x0000 0x4000

{

EXE_ROM 0x0000 0x4000; Root region

{

      vectors.o(Vect, +FIRST)

       *(+RO);   All code and constant data

}

;more exe regions

}

 

 

 

 

 

 

 

 

 

 


上例中,scatter保证了vectors.o中的Vect域被放置在地址0x0000

 

Root Region(根区)

根区是一个执行块,它的加载地址与执行地址一致。每个scatter文件至少有一个根区。分散加载有一个限制,创建执行块的代码和数据(即完成复制和清零的代码和数据)无法复制到另一个位置。根区必须包含:__main.o,包含复制代码/数据的代码,连接器输出变量$$TableZISection$$Table,包含被复制代码/数据的地址。由于这两个属性是只读的,故被*(+RO)匹配。如果将*(+RO)被用在非根区,则在根区必须显式地指明另一个RO区域。

LOAD_ROM 0x0000 0x4000

{

EXE_ROM 0x0000 0x4000; root region

{

      _main.o(+RO)            ;copying code

     *(Region$$Table)       ;RO/RW address to copy

      *(ZISection$$Table)  ;Ziaddress to zero

}

RAM 0x10000 0x8000

{

     *(+RO)                         ;all other RO sections

     *(+RW, +ZI)                ;all RW and ZI sections

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 


放置堆栈和heap

Scatterloading机制提供了一种指定代码和静态数据布局的方法。应用程序的堆栈和heap是在C库函数初始化过程中建立起来的。可用通过重定向对应的子程序来改变堆栈和heap的位置。在ADS库函数中,为_user_initial_stackheap()函数。可用汇编语言或C语言来完成,返回参数有:r0heap基地址;r1,堆栈基地址;r2heap长度限制值;r3,堆栈长度限制值。当用户使用分散装载功能时,必须重调用_usr_initial_stackheap()

 

                                                                                                                            

若存储器模型使用one-region,则应用的堆栈和heap位于同一存储器区块,使用时相向生长,此时,当heap区分配一块存储器空间时需要检查堆栈指针。另外一种情况是堆栈和heap使用两块独立的存储器区域,快速度的RAM,可选择只作为堆栈使用。使用two-region模型,用户需要导入符号use_two_region_memoryheap使用时检查heap的长度限制值。

 

抱歉!评论已关闭.