1.基本概念
个嵌入式Linux系统从软件的角度看通常可以分为四个层次:引导加载程序、Linux内核、文件系统、用户应用程序。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
用户应用程序
|
文件系统
|
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />Linux内核
|
引导加载程序
|
系统调用接口 |
设备驱动 |
操作系统核心机制 (进程调度、内存管理、 中断管理、时钟管理、 文件系统、网络支持 信号机制、同步机制 等等) |
图
引导加载程序是系统加电后运行的第一段代码。我们熟悉的PC中的引导程序一般由BIOS和位于MBR的OS bootloader(例如LILO或者GRUB)一起组成。然而在嵌入式系统中通常没有像BIOS那样的固件程序(有的嵌入式CPU有),因此整个系统的加载启动任务就完全由bootloader来完成。在嵌入式Linux中, 图中的引导加载程序即等效为bootloader。
简单地说,bootloader就是在操作系统内核运行前运行地一段小程序。通过这段小程序,我们可以初始化必要的硬件设备,创建内核需要的一些信息并将这些信息通过相关机制传递给内核,从而将系统的软硬件环境带到一个合适的状态,最终调用操作系统内核,真正起到引导和加载内核的作用。
bootloader是依赖于硬件而实现的,特别是在嵌入式系统中。不同的体系结构需求的bootloader是不同的;除了体系结构,bootloader还依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们基于相同的CPU构建,运行在其中一块电路板上的bootloader,未必能够运行在另一块电路开发板上。
Bootloader的启动过程可以是单阶段的,也可以是多阶段的。通常多阶段的bootloader能提供更为复杂的功能,以及更好的可移植性。从固态存储设备上启动的bootloader大多数是二阶段的启动过程,也即启动过程可以分为stage 1和stage 2两部分。
2.Bootloader的操作模式
大多数bootloader都包含两种不同的操作模式:“启动加载”模式和“下载”模式,这种区别对于开发人员才有意义。但从最终用户的角度看,bootloader的作用永远就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。
启动加载模式:这种模式也称为“自主”模式,即bootloader从目标机上的某个固体存储设备上将操作系统加载到RAM中运行,整个过程没有用户的介入。这种模式是bootloader的正常工作模式,因此当以嵌入式产品发布的时候,bootloader必须工作在这种模式下。
下载模式:在这种模式下,目标机上的bootloader将通过串口或者网络连接或者其它通信手段从主机下载文件,比如:下载内核镜像和根文件系统镜像等。从主机下载的文件通常首先被bootloader保存到目标机的RAM中,然后被bootloader写到目标机上的FLASH类固态存储设备中。Bootloader的这种模式通常在第一次安装内核与根文件系统时使用;此外,以后的系统更新也会使用bootloader的这种工作模式。工作于这种模式下的bootloader通常都会向它的中断用户提供一个简单的命令行接口。
3.Bootloader的概念扩展
Bootloader最主要的功能是引导加载内核镜像。但是随着嵌入式系统的发展,bootloader已经逐渐在基本功能的基础上,进行了扩展,bootloader可以更多地增加对具体系统的板级支持,即增加一些硬件模块功能上的使用支持,以方便开发人员进行开发和调试。从这个层面上看,功能扩展后的bootloader可以虚拟地看成是一个微小的系统级的代码包。
4.ARM Bootloader的共性
从上面bootloader的基本概念可以看出,bootloader的设计与实现是与具体的CPU以及具体的硬件系统紧密相关的,从上一章的实现就可以看出,要实现一个通用的ARM bootloader,即要适合所有的ARM处理器以及硬件系统,是不太可能的事情。另外,不同的操作系统,可能对具体的bootloader还会有另外额外的要求。
对于一个ARM系统来说,本质上,bootloader作为引导与加载内核镜像的“工具”,在实现上,必须提供以下几个功能,更确切地说,必须做到以下几点:
1)初始化RAM(必需):bootloader必须能够初始化RAM,因为将来系统要通过它保存一些Volatile数据,但具体地实现要依赖与具体的CPU以及硬件系统。
2)初始化串口(可选,推荐):bootloader应该要初始化以及使能至少一个串口,通过它与控制台联系进行一些debug的工作;甚至与PC通信。
3)创建内核参数列表(针对linux操作系统,推荐)。
4)启动内核镜像(必需):根据内核镜像保存的存储介质不同,可以有两种启动方式:FALSH启动以及RAM启动;
但是无论是哪种启动方式,下面的系统状态必须得到满足:
l CPU寄存器的设置: R0=0;
R1=机器类型;
R2=启动参数标记列表在RAM中的起始地址;
这三个寄存器的设置是在最后启动内核时通过启动参数来传递完成的。
l CPU模式: 关闭中断;
属于SVC模式;
Bootloader中没有必要支持中断的实现,这属于内核机制以及设备驱动管理的管理范畴;SVC模式是系统的一种保护模式,这样就可以进行一些只能在SVC模式下的操作,例如一些特定寄存器访问操作。
l Cache和MMU的设置: MMU必须关闭;
数据cache必须关闭;
指令cache可以关闭也可以开启;
Bootloader中所有对地址的操作都是使用物理地址,是实在的实地址,不存在虚拟地址,因此MMU必须关闭。Bootloader主要是装载内核镜像,镜像数据必须真实写回SDRAM中,所以数据cache必须关闭;而对于指令cache,不存在强制性的规定,但是一般情况下,推荐关闭指令cache。
l Bootloader启动内核镜像的方法是通过跳转语句直接跳转至内核镜像的第一句指令语句
文章评论(0条评论)
登录后参与讨论