下图是大多数开发板所有的一个存储单元框架,接下来以此图为基础描述ARM芯片的上电启动流程。
我们首先来了解几个关键词:
IROM (Internal ROM):芯片内部固化存储代码的存储器
IRAM (Internal RAM): 在IROM启动运行的时候,外置SDRAM还没有初始化好,而IRAM是可用的,因此必须要把BL1加载到IRAM中运行,由BL1对SDRAM进行初始化。ROM为什么不初始化SDRAM呢?那是因为支持的SDRAM规格是可变的,由固化代码来初始化显得不够灵活,而且固化代码往往代码量比较小,因为越多越容易出BUG。
Nand Flash :芯片外部非易失闪存技术的存储器,没有地址总线,不能直接运行代码,需要将代码加载到RAM上面才能运行。
SDROM:芯片外部的运行内存,由运行在IRAM上的BL1进行初始化,用于运行BL2与应用程序。
BL0:固化在芯片iROM中的启动代码。
作用:初始化PPL和时钟,设置看门狗,关闭中断和看门狗,初始化堆和栈;判断硬件的启动方式,去不同的启动方式的启动设备里面加载BL1。
BL1:是指在iRAM自动从外扩存储器(nand/sd/usb)中拷贝的uboot.bin二进制文件的头最大16K(一般是4K或8K)代码。
作用:初始化硬件,初始化RAM,初始化串口,分配堆栈空间,清空.BSS段,加载BL2。
BL2:是指在代码重定向后在内存中执行的uboot的完整代码。
作用:初始化本阶段要使用的硬件设备,加载内核,将内核映像和根文件系统映像从FLASH上读到RAM空间中,为内核设置启动参数。
上电启动流程:
第一步:CPU先读取运行iROM里面固化的启动代码BL0,进行一些基本的初始化,比如初始化PLL和时钟,关闭看门狗初始化堆栈,将flash中BL1的代码加载到IRAM中,跳转到IRAM中BL1的执行地址执行BL1。
第二步:在BL1中初始化硬件设备,初始化串口,初始化SDRAM,将flash中BL2的代码加载到SDRAM中,分配堆栈空间,设置好栈跳转到SDRAM中BL2的执行地址执行BL2。
第三步:初始化本阶段使用的硬件设备,初始化MMU,检测系统内存映射, 将内核和文件系统从Flash读取RAM中,为内核设置启动参数,加载内核,挂载文件系统。
note:
1、为什么BL0不初始化SDRAM呢?
那是因为支持的SDRAM规格是可变的,由固化代码来初始化显得不够灵活,而且固化代码往往代码量比较小,因为越多越容易出BUG。
2、为什么不把BL2也加载到IRAM上运行?
因为IRAM非常小,一般是96KB,而BL2一般会比96KB大,所以要在BL1中初始化SDRAM,然后将BL2加载到SDRAM中运行。