颤宿世界 笔趣阁:ARM的固件和bootloader,STANDSTONE固件程序,OS初始化

来源:百度文库 编辑:九乡新闻网 时间:2024/04/17 00:39:30
ARM的固件和bootloader,STANDSTONE固件程序,OS初始化  Firmware和bootloader
固件程序通常驻留在ROM中的,当系统上电时,首先执行的程序。
一个主要的目的就是加载和启动操作系统,这部分程序叫为bootloader。

固件程序执行流程为:



系统的image储存在某种媒介上,通常是有文件系统(file system)的,这时候image就是一个文件,操作文件需要固件程序能够支持文件系统。

image也可能就是一组二进制代码,这是最原始的image。通常ARM的image是ELF格式的,带有头和调试信息,ELF是老的COFF格式的升级版。

----------------------------
STANDSTONE固件程序
书中介绍了一个叫STANDSTONE的简单固件程序,它完成设置系统环境、加载并启动镜像的功能。所谓启动就是将系统的控制权交给启动了镜像,也就是一般所说的操作系统了。

STANDSTONE的程序工程组织结构:


可以看出,编译好的STANDSTONE产生的image,不仅包含了STANDSTONE的代码,而且包含了payload的bin(二进制镜像)。

STANDSTONE的执行流程:



ARM上电时从0x00000000开始执行,向量表就放在该地址,上电即进入reset异常。
STANDSTONE较简单,没用其他异常,将其都设置成循环。
reset异常,处理器跳转到standstone_init1的地方去运行,接着是第二步:


这一步在设置系统寄存器里特定的LED显示寄存器。




这部分代码完成了内存重映射,本来flash ROM是0地址开始的,现在编程了0x01800000,当然物理上是没变,只是逻辑上改了。
并且初始化了两个bank的SRAM。
分析代码:第一句是重映射钱standstone_init2的绝对地址,standstone_init2是固件程序的一部分,所以肯定在0x0到0x00080000范围内,重映射好要接着执行standstone_init2,所以需要计算出重映射好之后的地址,这也就是第三句指令做的事。
然后r0指向memorymaptable_str,然后将memorymaptable_str开始的数据赋值给r1-r12,r0后又赋值为某个系统寄存器,将r1-r12的数据赋值给这个系统寄存器。这几句就完成了重映射,这个系统寄存器是内存控制器,它接受memorymaptable_str这类能够表明内存分布情况的数据。
最后跳转到standstone_init2,这句很巧妙,因为STMIA执行好之后,PC所指向的地址已经变成了SDRAM里的内容,指令都到0x01800000以后的地址去了,但因为ARM的流水线结构,所以MOV语句已经取出,能够执行。

第四步是初始化串口,用于交互式命令通信,由于这部分和特定芯片相关,没有显示。

第五步是bootloader,就是加载之前那个payload的bin镜像


程序里假设了payload的bin镜像的起始地址payload_start_address,结束地址payload_end_address。
一开始将r12设为payload_start_address,将r13设为0地址,也就是SRAM的地址。
将payload_start_address拷贝至{r0-r11}再由{r0-r11}拷贝至SRAM。
拷贝完成之后跳转到0地址去执行payload的bin镜像。

----------------------------
OS初始化
通过前一篇的固件程序,假设已经完成了内存重映射和OS的拷贝,即将SRAM映射到了0x00000000和0x00080000之间,OS从固件拷贝到了0x00000000起始的地方。另外,假设芯片内的配置寄存器的基地址是0x03ff0000。

看一下OS的工程结构:

e7t/devices文件夹包含驱动程序,events下包含异常中断服务程序,core下是OS,apps下是应用程序。

虽然固件程序里完成了初始化,但那个初始化是针对芯片而言的,比如设置栈指针、内存映射、OS拷贝等;OS拷贝到0x0地址之后,固件程序将pc也置为了0x0,要知道0x0地址是存放异常向量表的,第一个是reset异常,这也就是这个OS的第一条指令了,这不过这个reset指的是OS的reset,和固件程序里的reset不是同一个。

OS的reset异常完成OS的初始化工作,分成三个阶段:栈设置、PCB设置、开始C程序。首先是栈设置:

bringupInitFIQRegisters程序段将FIQ的寄存器用作系统状态记录,所以对FIQ的三个寄存器做了设为了0。接下去的几句是设置了栈指针,因为使在SVC模式下,所以可以通过MSR指令改写模式,并设置该模式下的栈。设置好之后,再回到SVC模式。

PCB设置:PSB指的是process control blcok,是一种数据结构,当任务发生切换时,将PCB数据拷贝到栈上:



最后跳转至C程序:

进入C程序后,第一个函数初始化了驱动、IO、异常中断服务等;然后开始定时器即时;然后切换至user模式;然后开始第一个任务。


系统内存分布


----------------------------
reference:ARM System Developer's Guide.pdf