||
在嵌入式系统中,内核映像与根文件系统映像可以直接在ROM或Flash等固态存储设备中直接运行,但该做法是以牺牲运行速度为代价的。本系统中内核映像与根文件系统映像都被加载到RAM中运行。
大多数BootLoader的启动分为stagel和stageZ两个阶段,依赖于CPU体系结构的代码(如设备初始化代码等),通常都放在stagel中,且常用汇编语言实现,以达到短小精悍的目的。而stageZ则用C语言实现更复杂的功能,且代码有更好的可读性和可移植性。
stagel完成的任务:
①初始化硬件设备、屏蔽所有的中断;
②设置CPU的速度和时钟频率;
③初始化RAM;
④初始化LED(Light一EmittingDiode,发光二极管),通过GpIO驱动LED,表明系统状态是OK或Error。若开发板未配备LED,则通过初始化UART向串口打印BootLoader的Logo字符信息来表明系统的状态;
⑤关闭CPU内部指令/数据cache;
⑥为加载BootLoaderstageZ准备RAM空间;
⑦拷贝BootLoaderstageZ到RAM空间;
⑧设置好堆栈指针,为执行C语言代码作准备;
⑨跳转到stageZ的c程序入口点。
StageZ完成的任务:
①初始化本阶段要使用的硬件设备,包括:至少初始化一个串口,以便向终端用户输出FO信息,初始化计时器等;
②检测系统内存映射;
③将内核映像和根文件系统映像从Flash中读到RAM空l司中;
④规划内存占用的布局,包括内核映像、根文件系统占用的内存范围,需要考虑基地址和映像的大小两方面。对于内核映像,一般将其拷贝到从(MEM_START+0x8000)基地址开始的大约1MB大小的内存范围内(因为嵌入式Linux内核一般不超过1MB)。在MEM_START到MEM_START+0x8000这段32KB的内存里,存放的是Linux内核的全局数据结构,如:启动参数、内核页表等。对于根文件系统映像,一般将其拷贝到(MEM_START+0x0010,0000)开始的地方。如果用Ramdisk作为根文件系统映像,则其解压后一般是1MB。从Flash上读取数据与从RAM单元中读取数据并没有什么不同,用一个简单的循环即可完成从Flash设备上拷贝映像;
⑤设置内核启动参数;
⑥调用内核。Boot Loader调用内核的方法是直接跳转到内核的第一条指令处,即直接跳转到MEM_START+0x8000地址处。