ARM 上电启动流程+ Cortex-M/R 内核启动过程 / 程序启动流程
因为异常向量表是在IROM的起始位置上,即0x00000000开始的地方,如下所示,IROM建立起的环境只能支持中断(异常的一种)注册,即注册到0xd0037418,对于其他异常的支持需要在启动或者OS阶段进行重建,并将其定位到SDRAM区域,并设置异常向量的基地址(通过改变协处理器P15的C12-Vector Base Address Register)指向该区域。从上图我们可以发现在0地址处是
1、Arm芯片上电启动流程剖解_Yannick_J的博客-CSDN博客_arm上电启动流程
2、ARM 之九 Cortex-M/R 内核启动过程 / 程序启动流程(基于ARMCC、Keil)_ShouZC的博客-CSDN博客
关键字:
stepping stone:(可以看做是Internal RAM)
IROM (Internal ROM):固化在CPU内部ROM里的一段代码,它的运行叫做BL0.
IRAM: 因为IROM启动运行的时候,外置SDRAM还没有初始化好,而IRAM是可用的,因此必须要把BL1加载到IRAM中运行,由BL1对SDRAM进行初始化。ROM为什么不初始化SDRAM呢?那是因为支持的SDRAM规格是可变的,由固化代码来初始化显得不够灵活,而且固化代码往往代码量比较小,因为越多越容易出BUG,出BUG就会导致SOC芯片重新掩膜tapout,一次可要好几百万人民币呢。
BL0: (BootLoad 0阶段),BL0做了些什么?
s5pc100芯片手册见2.2FUNCTIONAL SEQUENCE,翻译成中文如下
1.初始化PLL和时钟,将其设定为固定值;
2.初始化栈和堆区域;
3.初始化指令Cache 控制器;
4.从外部起动设备中加载BL1;
5.如果起动安全机制开启,则检查BL1数据完整性;
6.如果校验通过,则跳转到0x34010地址处运行;
7.如果校验失败则停止。
BL1: 从CPU上电起,把系统启动过程分为3个阶段BL0、BL1、BL2。BL0是固化在内部ROM上电就执行的一小段程序,BL0引导u-boot的第一个阶段称为BL1。通常加载到CPU 内的 IRAM中执行
BL2: 把u-boot的第二阶段代码用于引导内核的阶段称为BL2,通常加载到SDRAM中执行。
谈到arm的启动流程不得不说的是bootloader,但是我这篇文章主要来谈谈arm启动流程的,所以bootloader只是跟大家简介一下就ok。这篇文章我会谈到以下内容:
1、bootloader简介以及其作用
2、2440、6410、210当下比较常见的3款处理器的启动流程进行简单分析,通过这三款处理器的分析希望大家掌握arm处理器的启动分析。
Ok我们进入主题
l Bootloader简介及其作用
在我看来bootloader的作用是初始化必要的硬件,引导内核启动。(当然这是主要作用,今天的重点不在bootloader,所以在我后面的博文会继续谈到的)
l 启动流程分析
在分析启动流程的时候我们将会使用的文档是三星公司提供的芯片手册,通过手册我们搞清楚芯片的启动。
在分析启动流程之前我们首先要清楚不论是arm的何种处理器,其都是从0x0000 0000地址处开始执行程序的。下面的分析我将会通过三个方面:1、芯片支持的启动方式2、地址布局3、启动流程
1. 2440
a) 启动方式
由上图可知,S3C2440支持两种启动模式:NAND和非NAND(这里是Nor Flash),具体采用的方式取决于OM0、OM1两个引脚的状态。
b) 地址布局
我们知道arm从0地址出运行代码那么我们的零地址处到底存放的是什么东西呢?我们通过地址布局图来分析
从上图我们可以清楚的看到左边的是从Nor Flash启动的地址布局,右边是从NAND启动的地址布局,因为Nor Flash内可以运行程序(Nor flash 地址线和数据线独立,nand flash地址线/数据线复用),所以我们在放bootloader的时候放在0地址处即可,所以我们重点分析从NAND启动。
c) 启动流程
我们从地址布局图中可以看到,当我们从NAND启动的时候0地址处是BootSRAM(又叫做stepping stone垫脚石),当我们上电时其会做以下事情
上电后处理器自动将nandflash前4KB的内容复制到boot sram(I RAM,CPU内部RAM)开始执行,这一过程就是BL1加载过程(由CPU内部的 BL0 代码程序完成)。
通过bootsram(即刚才复制进来的4k)来初始化相关硬件和寄存器从而访问nandflash,接下来把剩余的bootloader复制到内存(SDRAM/DRAM)中 (即BL1->BL2),当stepping stone 里面的4KB执行完以后跳转到内存继续执行,完成系统的启动。
2. 6410
a) 启动方式
从上图我们可以看到6410支持的启动方式比较多有SROM(Nor Flash)启动,oneNAND启动,IROM,即内置ROM(IROM是处理器内部的固件/存储器,但不是stepping stone)启动。其中IROM中又有sd卡、NAND,我们可以配置相应的管脚去选择其启动方式。
b) 地址布局
从上图我们可以发现在0地址处是一个镜像区,不放置任何设备,当我们选择不同的启动方式的时候,其通过映射关系将对应的设备映射到镜像区域。比如我们选择从IROM启动其就会将IROM映射到该区域。
c) 启动流程
假设我们从NAND启动,从启动方式中我们可以知道从NAND启动是属于从IROM启动的,所以当我们上电的时候其会做以下事情:
1. 将IROM映射到镜像区
2. IROM中有芯片厂商写好的BL0,由BL0将系统引导至启动选项,然后将BL1(NAND中前8k)拷进stepping stone(IRAM,即内置RAM)进行运行
3. BL1将剩下的BL2拷进内存,当BL1执行完以后跳转到内存继续执行,完成系统的启动。
-
D-TCM==数据紧密耦合内存 (Data Tightly Coupled Memory)。
-
TCM 是一段始终有效的连续内存区域(如果启用了 TCM)。 TCM 用作系统的物理内存映射的一部分,不必由物理地址相同的外部存储器来支持。因此,TCM 的行为与标记为直写可高速缓存的内存区域的高速缓存不同。 在这类区域中,向 TCM 中的内存位置写入时,不会发生任何外部写入。
-
TCM 用于向处理器提供低延迟内存,它没有高速缓存特有的不可预测性。 可以使用 TCM 来存放重要例程,如中断处理例程或者极需要避免高速缓存不确定性的实时任务。此外,可以使用 TCM 来保存暂时寄存器数据、局部属性不适合高速缓存的数据类型,以及中断堆栈等重要数据结构。
-
有关 TCM 的完整体系结构描述,请参阅《ARM 体系结构参考手册》以及处理器的《技术参考手册》(Technical Reference Manual)。
-
参考:https://blog.csdn.net/otianshizairenjian/article/details/78330724
3. S5PV210
S5PV210属于这一类系统,外挂SDRAM内存和NAND、SD卡等外存设备,系统和应用代码等作为固件存放在外存设备中,并通过S5PV210内置的IROM启动并逐步引导到SDRAM中。S5PV210的SPEC是《S5PV210_UM_REV1.1.pdf》,在其第29页~30页中描述了IROM和IRAM的内存映射图。IRAM,即内置RAM,在启动引导阶段有两个作用:一是IROM运行时使用的数据变量所在的区域,二是IROM,即BL0会将外存中的BL1引导到该区域中。因为IROM启动运行的时候,外置SDRAM还没有初始化好,而IRAM是可用的,因此必须要把BL1加载到IRAM中运行,由BL1对SDRAM进行初始化。IROM为什么不初始化SDRAM呢?那是因为支持的SDRAM规格是可变的,由固化代码来初始化显得不够灵活,而且固化代码往往代码量比较小,因为越多越容易出BUG,出BUG就会导致SOC芯片重新掩膜tapout,一次可要好几百万人民币呢。由内存映射图可以得到:
IROM是64K,在0x0000-0000开始的区域,而IRAM是96K,在0xD0020000-0xD0037FFF。我们可以看到其地址布局和6410类似,采用了映射的方法。S5PV210的IROM的SPEC是《S5PV210_iROM_ApplicationNote_Preliminary.pdf》,其主要描述以下内容
1. 启动流程,分析如下:
1)BL0位于IROM中,其选择引导的介质受外围引脚OM电平所决定。
其能引导的介质包括:nor,nand,onenand,SD/MMC等等。如下图,0x2表示nand(page为2k byte,5个command周期,8bit ECC)启动,0xc表示SD/MMC。OM的值可以通过读寄存器0xE000-0004得到。
2)根据OM的值,IROM中的BL0选择其固话的对应驱动将对应介质的前16K代码数据读到IRAM中。引导代码之后会进行校验,校验和BL1的长度信息放在16K代码数据的最前面16个字节。为什么需要长度?因为校验是对确定长度的内容进行计算得到,而BL1的有效代码数据可能并没有16K。BL1头部信息和校验算法如下图:
加载BL1之后,BL0会将给PC赋值为0xd0020010,即BL1代码真正的入口应该设置链接到0xd0020010。在编译链接生存BL1之后需要用专门的工具计算出BL1的长度和校验码,并填充到BL1的头部,在uboot中称为NAND_SPL.BIN。
3)启动过程中的示意图的第三步只是一种方案的建议,在实际的启动模块中,BL2一般比较大,因为其包括引导操作系统,还包括在启动阶段支持下载等交互功能,所以BL2会大于IRAM中剩下的80K,因此,BL1执行时会先初始化好SDRAM,然后将BL2引导到SDRAM。因此图中的第三步示意图并不准确。BL1执行时MMU是关闭的,其在建立好临时页表后,会开启MMU,并跳转到BL2开始执行。
4)BL2会提供与用户交互的模式命令,一般用于研发人员调试,如果是真正的产品则没有这种模式,直接开始引导OS到SDRAM。并跳转到OS开始执行。
5)一般的启动流程图如下(这个图很赞,可以仔细看看):
从上图可以得知,当引导OM所对应的介质的BL1失败(如介质接口有问题、校验失败等)时,还有另外的备选引导方案,即2nd boot,那就是USB引导和串口引导,这里不再展开。
2. IROM除了引导之后,还做了一些硬件和软件环境初始化工作。主要流程包括:
1)关闭看门狗
2)初始化指令cache,开启指令cache
3)初始化 IRAM中的栈(中断栈、SVC栈)和堆,异常向量注册表等。具体如下图:
IROM运行是处于SVC模式。这里的exception vector table并不是异常向量表,而应该称为异常向量注册表。因为异常向量表是在IROM的起始位置上,即0x00000000开始的地方,如下所示,IROM建立起的环境只能支持中断(异常的一种)注册,即注册到0xd0037418,对于其他异常的支持需要在启动或者OS阶段进行重建,并将其定位到SDRAM区域,并设置异常向量的基地址(通过改变协处理器P15的C12-Vector Base Address Register)指向该区域。
_start: b reset
.word 0x0
.word 0x0
.word 0x0
.word 0x0
.word 0x0
ldr pc, _irq
.word 0x0
4)填充好IRAM的块设备读接口区域。如上图,0xd0037f80开始的128个字节存放的是块设备的拷贝函数地址,如nand,sd/mmc等的读接口地址。其用于后续BL1和BL2使用。即BL1和BL2代码不需要实现外存设备的读驱动函数,只需要调用IROM的接口就可以了。SPEC的p14-p18具体描述了各种不同的介质设备的操作接口地址以及相关的信息。
5)开启PLL,初始化系统时钟。
6)copy 16k字节的BL1到 IRAM。
7)对BL1进行校验,即计算BL1的校验值,并与BL1的头部的校验值进行比较,失败即会跳到2nd boot中去引导,成功即跳到BL1的0xd0020010执行。
转载:
扩展:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)