地址重映射在ARM系统中的实现
移。 一种是不管实际的代码空间有多大,直接将ROM地址空间整个搬移到RAM中。当然,这种方法并不适合在真正的启动代码中使用,但在做初步的Remap测试时,可以用来检验堆栈及异常中断的设置是否合理。 另一种方法较复杂,它使用了SDT链接器ARMLink产生的定位信息,仅把RO风吹草动的有效代码和数据段到RAM中。ARMLink将编译后的程序链接成ELF文件。映像文件内部共有三种输出段:RO段、RW段和ZI段。这三种输出段分别包含了只读代码及包含在代码段中的少量数据、可读写的数据、初始化为0的数据,ARMLink同时还产生了这三种输出段的起始和终止定位信息:Image$$RO$$Base、Image$$RO$$Limit、Image$$RW$$Base、Image$$Limit、Image$$Linit和Image$$ZI$$Limit。可以在程序中使用这些定位信息。将ROM中的代码和数据搬移到RAM中,其实现代码如下: 数据定义: BaseOfROM DCD Image$$RO$$Base TopOfROM DCD Image$$RO$$Limit BaseOfBSS DCD Image$$RW$$Base BaseOfZero DCD Image$$ZI$$Base EndOfBSS DCD Image$$ZI$$Limit 源程序: ;将ROM中的程序搬移到RAM中,重映射后的地址不变 adr r0,ResetEntry ;ROM中程序起始地址 mov r3,#(RamBaseAddr16) ;RamBaseAddr=0x100 Idr r1,BaseOfROM Idr r2,TopOfROM Add r1,r1,r3 Add r2,r2,r3 0 Idmia r0!,{r4-r11} Stmia r1!,{r4-r11} Cmp r1,r2 Bcc%B0 ;将RW段中预初始化的变量搬移到RAM中 sub r1,r1,r2 sub r0,r0,r1 ;将r0指向RO段的结束,即RW段的开始 ldr r1,BaseOfBSS Idr r2,BaseOfZero Add r1,r1,3 Add r2,r2,r3 1 ;基于局部标号的相对跳转,PC+偏移地址,产生与位置无关的代码 cmp r1,r2 ldrcc r4,[r0],#4 strcc r4,[r1],#4 bcc %B1 ;接着把ZI段搬移到RAM中,并其将初始化为0 mov r0,#0 Idr r2,EndOfBSS Add r2,r2,r3 2 cmp r1,2 strcc r0,[r1],#4 bcc%B2 ⑥地址的重新映射。S3C4510B中的Remap过程其实很简单,只需重新设置ROMCON0~ROMCON5和DRAMCON0~DRAMCON3。在本系统中只需重新设置ROMCON0和DRAMCON0。 源代码: ;/*内存控制寄存器重新设置-存储空间重新映射地址空间*/ EXPORT RemapMemory RemapMemory mov r12,r14 adr r0,RemapMem ldmia r0,{r1-r11} ldr r0,=ROMCON0 ;ROMCON0为Bank寄存器的起始地址 stmia r0,{r1-r11} bl ExceptionTalbeInit ;中断向量表重新初始化 mov pc,r12 RemapMem DCD 11040060 ;/*ROMCON0 0x1000000~0x1100000*/ … DCD 10000398 ;/*DRACON0 0x0~0x1000000*/ … ⑦进入C代码空间,开始主程序的运行。此时代码应该运行于RAM中。 3 异常中断的处理 在Remap的启动代码中,需要特别注意的是异常中断的处理。在S3C4510B中,异常中断的入口地址是固定的,按表1次序排列。 地址重新映射之后,入口地址被映射到RAM中,中断处理代码也被搬移到RAM地址空是。此时,中断响应和中断处理的速度都将大大加快,这将有利于提高整个系统的实时性。异常中断向量表的设计结构如图3所示。 下面是各部分的源代码(以IRQ异常中断为例)。 异常向量表的定义:(系统初始化时,将异常处理代码入口地址写入异常中的向量表) _RAM_END_ADDR EQU 0x01000000 ;重映射后RAM的终止地址 MAP (_RAM_END_ADDR-0x100) SYS_RST_VECTOR # 4 UDF_INS_VECTOR # 4 SWI_SVC_VECTOR # 4 INS_ABT_VECTOR # 4 DAT_ABT_VECTOR # 4 RESERVED_VECTOR # 4 IRQ_SVC_VECTOR # 4 FIQ_SVC_VECTOR # 4 异常初始化代码: … b IRQ_SVC_HANDLER ;0x18 … IRQ_SVC_HANDLER SUB sp,sp,#4 ;满递减堆栈 STMFD sp!,{r0} LDR r0,=IRQ_SVC_VECTOR ;读取中断向量, ;IRQ_SVC_VECTOR=SystemrqHandle LDR r0,[r0] STR r0,[sp,#4] LDMFD sp!,{r0,pc};跳转到异常中断处理代码入口 异常处理入口代码: … SystemIrqHandler IMPORT ISR_IrqHandler STMFD sp!,{r0-r12,lr} BL ISR_IrqHandler ;跳转到C代码中异常中断处理程序ISR_IrqHandler LDMFD sp!,{r0-r12,lr} SUBS pc,lr,#4 … 在如上的结构中,不管系统
上面的步骤可以根据实际需要进行适当的添加或删节。值得注意的是:汇编生成的代码应该是与位置无关的代码,即代码在运行期间可以被映射到不同的地址空间,其中的跳转指令都是基于PC寄存器的相对跳转指令。基于PC的标号是位于目标指令前或者程序中数据定义伪操作前的标号,这种符号在汇编时将被处理成PC值加上或减去一个数字常量。
表1 异常类型 工作模式 正常地址 复位 管理 0x00000000 未定义指令 未定义 0x00000004 软件中断(SWI) 管理 0x00000008 预取中止 中止 0x0000000 数据中止 中止 0x00000010 预留 - 0x00000014 IRQ(中断) IRQ 0x00000018 FIQ(快速中断) FIQ 0x0000001
- 使用MMU进行地址重映射的启动代码结构探讨(11-10)
- ARM地址重映射的通俗解释(11-09)
- 基于ARM的嵌入式BootLoader设计与启动过程(05-21)
- 和弦芯片C520的结构与典型应用方案(04-17)
- 基于uCLinux和ARM7的网络通信设计(04-12)
- 嵌入式系统flash接口电路的实现(03-30)