ARM有内部启动和外部启动之分,究竟何为内部何为外部有必要做个说明,这也是熟悉ARM运作的基础。下文以我目前所使用的Atmel公司AT91SAM9260系列ARM9单板机为例。
ARM启动时会产生复位异常,程序计数器指向异常向量地址0x0000_0000,即启动时首先运行的是位于地址0x0000_0000处的指令。因此,从0x0000_0000到0x0010_0000的1M的内部存储区域(内部存储区0)在上电后将决定系统的启动过程。若BMS(Boot Mode Select)=1,则系统将内部存储区1(0x0010_0000--0x0010_8000)的数据映射到内部存储区0,即从内部启动;若BMS=0,则将外部存储器的区域0映射到内部存储区0,实现外部启动。
ARM芯片的生产厂商一般都会在芯片内部集成BOOTROM,里面固话了一段用于内部启动的代码,该段代码完成的功能是:设备初始化,设定PMC得到主震荡器的频率,分频得到PLLB输出至USB的48MHz时钟频率,为各种ARM模式建立堆栈,设定中断控制器,初始化C变量。跳到Main执行;完成这部分初始化后就要检测片外非易失存储器内是否有有效的可执行代码,检测顺序为SPI DataFlash,TWI EEPROM,EBI并行存储器,有效的可执行代码指的是外部存储器的起始32字节必须是ARM异常向量入口,有效的了执行代码总是从片外的存储器0地址下载到片内的SRAM,在地址重新映射后下载代码为片内0x0000_0000处。当要运行更为复杂的功能时候,可能需要二级bootloader,这时候SRAM中运行的可执行代码还要有搬运功能,将在norflash或者NandFlash中的二级引导代码搬移到SDRAM中运行,该部分二级bootloader运行后又将嵌入式操作系统的代码搬移到SDRAM中,将控制权交给操作系统,这样整个内部启动完毕。
外部启动过程相对简单,但是需要自行编写整个启动过程的代码,代码量要大一些。外部启动一般将bootloader代码放在容量小相对昂贵但是可以片内执行代码(XIP)的Norflash中,操作系统和应用程序以及数据放在低价大容量的NandFlash中。系统上电后将在norflash中运行bootloader,bootloader一般为功能较为全面的UBOOT,EBOOT,REDBOOT等,完成系统硬件初始化和堆栈分配的任务,同时搬移操作系统内核代码到SDRAM某一地址,最后跳转到该地址将指挥权交给操作系统内核,内核运行后挂在在NandFlash中的文件系统,整个外部启动过程完毕。