严格的说,ARM内核真正支持的启动方式只有一个:通过操作CP15来实现对reset vector的重定向,比如:硬件复位时指向ROM区域0xffff0000,而在启动代码中再重定向到RAM区域0x00000000。
另一个方法更常用,就是memory remap:reset vector始终不变固定在0x00000000,ROM还是在0xffff0000,RAM还是0x00000000,复位后硬件在逻辑上复制ROM的 映像到0x00000000,原来的RAM则被覆盖看不见了,等软件完成初始化之后再通过寄存器设置取消memory remap,将RAM重新显现出来。这一机制并非ARM内核本身所支持的,而是在SoC的时候人为修改memory的访问逻辑而实现的。对ARM内核而 言,所有4GB访问空间全部是存储器,不是代码便是数据,读写这4GB空间并不会影响ARM自身的状态,只是有时我们人为地将某些地址实现为寄存器(如 FIQ寄存器),当数据被写入这些特定地址之后(中断bit置位),其硬件逻辑便会向ARM发送各类硬件信号(FIQ电平有效),改变ARM的运行状态 (进入FIQ中断模式)。
ARM和大多数CPU内核一样,上电复位之后就立刻从某个固定地址(一般是0x00000000)开始取指执行,在这之前。硬件仅负责诸如【禁止全 局FIQ IRQ,进入SVC模式】之类的非常有限的初始化工作,软件需要完成绝大多数的初始化工作之后才能为之后的主程序建立足够的运行环境。直观上我们觉得将 ROM放在ARM的复位地址处,并且在ROM中固化好我们的启动代码是一个好主意,但是实际情况却不是如此,原因有以下几个:
1. ARM人都知道,所有的异常中断入口组成了reset vector,其第一个入口(偏移0处)就是reset地址,如果将reset vector放在ROM中,FIQ、IRQ等异常入口也跟着被放在了ROM中,如果我们希望在程序运行时改变FIQ、IRQ的中断入口,ROM就显得不方便了。(虽然也有间接的办法)
2. 有时硬件设计上code并不存放在一个NAND ROM中,可能是串行FLASH,甚至根本没有ROM(如从UART下载)。这时,ARM复位后就不得不指向RAM区域