ARM体系结构中,系统上电或复位后,处理器将从地址0x0处取第一条指令,因此,上电的时候,地址0x0处必须是非易失性的ROM或FLASH。但是,为了加快中断响应速度,方便更改中断向量表,有时需要把中断向量表复制到RAM中去,然后把RAM重新映射到地址0x0处,这就用到了地址重映射机制。因为地址重映射是在程序执行过程中进行的,必须考虑程序执行流程的连续性。
引导加载程序:
一个嵌入式系统的软件通常可以分为3个部分:引导加载程序, 嵌入式操作系统, 用户应用程序. 引导加载程序是系统加电后运行的第一段软件代码. 简单地说, 就是在操作系统内核运行之前运行的一段小程序(在嵌入式系统中通常叫做Bootloader). 通过这段小程序, 可以初始化硬件设备、建立内存空间的映射图, 从而将系统的软硬件环境配置到一个合适的状态,以便为最终调用操作系统内核设置适当的环境. 而在嵌入式系统中, 通常并没有像PC机中BIOS那样的固件程序(有的嵌入式CPU也会内嵌一段短小的启动程序), 因此整个系统的加载启动任务就完全由Bootloader来完成. 由于每个用户对嵌入式CPU的应用千差万别, 每个用户对系统的启动有不同的要求, 所以Bootloader程序一般都由用户根据自己的实际要求编写.
ARM处理器的地址重映射机制可分为三种情况:1、处理器内部有专门的寄存器完成重映射(Remap),只需将Remap寄存器相应位置“1”,由硬件逻辑来完成地址的重新映射。2、没有专门的Remap控制寄存器,需要重新改写用于控制存储器起始地址的块(Bank)寄存器,来实现Remap。3、没有Remap寄存器,而Bank寄存器的起始地址固定,这就需要MMU实现地址重映射。另外,有一些ARM处理器没有地址重映射机制。
(第一种情况)由于处理器地址重映射机制不同,其具体实现方式也是不同的。AT91M55800A采用一个专用寄存器EBI_RCR(重映射控制寄存器),通过向EBI_RCR的RCB寄存器的第0位写“1”实现地址重映射。系统复位瞬间,系统将FLASH地址映射在0x0的位置,而将内部SRAM映射在0x00300000的位置。启动代码需将FLASH中的中断向量拷贝到内部SRAM中,然后,执行重映射命令,把内部SRAM的地址重新映射到0x0的位置,而将FLASH的地址映射到其他位置,如0x01000000(由NCS0片选,配置EBI—CSR0寄存器)的位置。这样便可以在内部SRAM中0x0开始的位置修改中断向量。同时,为了保证程序执行流程的连续性,必须调整PC指针,即调整到程序真正被连接的地方(0x01000000)去。这时,程序仍在FLASH中运行。如下所示:
(第二种情况)三星S3C4510B最大可寻址空间为64MB,它把64MB的地址空间分为10个块,每个块的起始地址和大小都可以通过寄存器来设置。上电时默认FLASH映射到地址空间为0x0000,0000~0x0200,0000的位置,这样,程序从FLASH中的启动代码开始执行。在启动代码中,把SDRAM映射到地址空间的其他位置,如0x0040,0000~(0x0140,0000-1)。接着将FLASH中从0x0开始的程序一一对应地复制到SDRAM中从0x0040,0000开始的地址空间,然后,把SDRAM映射到从0x0开始的地址空间,FLASH映射到其他位置,如从0x0100,0000开始的地址空间,至此,完成了地址重映射。而它的PC指针不需要调整,这时的PC指针已经指向SDRAM中了。
开始启动时, 存有启动代码的FlashROM被映射到0x0000000地址, 系统从此开始运行. 但在实际应用中, 为提高系统的实时性, 加快代码的执行速度, 系统启动后程序往往要被搬移到存取速度要比FlashROM快得多的SDRAM中, 以此大幅提高系统的实时性能.又由于S3C4510B芯片中的异常中断入口地址被固定在0x0000000开始的8个字(每个字包括4个字节)中, 因而系统只能将存储器进行地址重映射( Remap),把SDRAM映射到0x000000地址处, 把FlashROM的地址映射到系统高端地址.S3C4510B硬件系统有4MB的FlashROM, 使用16位数据总线; 16MB的SDRAM, 使用32位数据总线. 如图2所示, Remap前系统地址0x0000000~0x03FFFFF 分配给 Flash ROM, 0x0400000 ~0x13FFFFF分配给SDRAM; Remap后0x0000000~0x0FFFFFF分配给SDRAM, 0x1000000~ 0x13FFFFF分配给FlashROM。
Remap后, SDRAM被映射到0x0000000~0x0FFFFFF的地址空间, 而FlashROM则被映射到高于0x0FFFFFF的地址上. 为保证Remap后程序能够正常运行, 整个过程必须确保FlashROM中的代码和数据地址不变地被移到SDRAM中.程序编译时链接器ARMLink将自动生成RO段、RW段和ZI段3种段, 同时还将产生这3种段的起始和终止定位信息: Image $$RO$$Base、Image$$RO $$Limit、Image $$RW$ $Base、Image$RW$Limit、Image$ZI$Base和Image$$ZI$$-Limi.t 使用这些定位信息, 将FlashROM中的代码和数据搬移到SDRAM中, 源程序如下:
Start_FlashDCD |Image$$RO$ $Base|
End_FlashDCD |Image$$RO$ $Limit|
Start_BSS DCD |Image$$RW$$Base|
End_BSS DCD |Image$$RW$$Limit|Start_Zero DCD |Image$$ZI$$Base|
End_Zero DCD |Image$$ZI$$Limit|; / /复制FlashROM中的代码到SDRAM中/ /;
LDRr0, = Start_Flash
LDRr1, = End_Flash
LDRr2, = Start_BSS
LDRr3, = End_BSS
SUBr1, r1, r0
SUBr3, r3, r2
ADDr1, r1, r3
LDRr2, = 0x400000; / /Remap前SDRAM起始地址
COPLDRr3, [ r0], #4
STRr3, [ r2], #4
SUBSr1, r1, #4
BNECOP
LDRr0, = End_Flash
LDRr1, = Start_BSS
LDRr3, = Start_Zero
CMP r0, r1
BEQLOOP1
; / /复制RW段到SDRAM/ /
LOOPCMP r1, r3
LDRCCr2, [ r0], #4
STRCCr2, [ r1], #4
BCCLOOP
; / /复制ZI段并清0/ /
LOOP1LDRr1, =End_Zero
MOVr2, #0
LOOP2CMP r3, r1 ;
STRCCr2, [ r3], #4
BCCLOOP2
在实际应用系统中, 由于FlashROM存储器相对而言比较小速度慢且价格高, 为了节约成本提高运行速度, 通常将会把应用程序和在存储器中的数据先压缩然后再写入FlashROM中同时将解压缩程序也写进去. 当系统上电启动后, 在搬移程序和数据时解压程序先将被压缩过的程序和数据解压后再搬到SDRAM的适当位置中. 由于压缩解压程序比较复杂不在这里讨论。
(第三种情况)三星S3C44B0X的地址空间分成8个块,Bank0~Bank6的起始地址固定,大小可变。Bank7虽起始地址可变,但只是为了保证与Bank6地址连续,因为Bank6、Bank7主要用于DRAM。S3C44B0X没有提供地址重映射机制。三星S3C2410X把1GB的地址空间分为8个块(Bank0~ Bank7),它们的起始地址固定,大小可变。S3C2410X没有进行地址重映射的控制寄存器,只有内存管理单元(MMU)。MMU把物理地址空间映射到虚拟地址空间,通过这种方式可以实现地址重映射。
(第四种情况)Intel公司StrongRAM SA-1110和XscalePXA255微处理器存储区域分成若干块,每个块的起始地址固定。它们都没有地址重映射机制,但可采用存储器管理单元来完成地址映像的重映射。