嵌入式linux系统从软件的角度通常分为四个层次:
1。引导加载程序,包括固化在固件(firmware)中的boot代码(可选)和BootLoader两部分。
2。Linux 内核,特定于嵌入式板子的定制内核以及内核的启动参数
3。文件系统,包括根文件系统和建立于Flash 内存设备之上的文件系统,通常用ramdisk来作为rootfs
4。用户应用程序,特定于用户的应用程序,有时在用户应用程序和内核层之间还可能会包括一个嵌入式图形用户界面,常用的GUI有MicroWindows和MiniGUI。
引导加载程序是系统加电之后运行的第一段软件代码,PC中的引导加载程序由BIOS(其本质是一段固件程序)和位于硬盘MBR中的BootLoader(如LILO和GRUB)一起组成。在嵌入式系统中,通常没有像BIOS那样的固件程序(有的嵌入式CPU也会有一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。
BootLoader 就是在操作系统内核运行之前运行的一段程序,完成硬件设备的初始化,建立内存空间的映射图的功能,将系统的软硬件环境带到一个合适的状态,为最终调用系统内核做好准备。嵌入式的BootLoader一般非常依赖于硬件,建立一个通用的BootLoader是不可能的。
BootLoader的功能:
1。初始化RAM(必须)
2。初始化串口(可选,推荐)
3。启动内核镜像(必须)
根据内核镜像的保存方式不同,有两种启动方式:FLASH启动以及RAM启动,但无论何种启动,均满足一下条件:
(1)CPU寄存器的设置
R0 = 0
R1 = 机器类型
R2 = 启动参数标记列表在RAM中的起始地址
这3个寄存器的设置是在最后启动内核时通过启动参数来传递完成的
(2)CPU模式
关闭终端,属于SVC模式
BootLoader中没有必要支持中断的实现,这属于内核机制以及设备驱动管理的管理范畴, SVC模式是系统的一种保护模式,这样就可以进行一些只能在SVC模式下的操作,例如一些特定寄存器的访问操作。
(3)Cache和MMU的设置
MMU必须关闭
数据Cache必须关闭
指令cache可以关闭可以打开
BootLoader中所有对地址的操作均为物理地址,不存在虚拟地址,因此MMU必须关闭。BootLoader主要是装在内核镜像,镜像数据必须真实写回SDRAM中,所以数据Cache必须关闭;而对于指令Cache,一般情况下,推荐关闭。
BootLoader的启动流程
分为Stage1和Stage2两个阶段。
1。BootLoader的Stage1
主要完成以下工作:
(1)完成基本的硬件初始化。初始化工作主要包括屏蔽所有的中断,设置CPU的速度和时钟频率,RAM初始化,初始化LED,关闭CPU内部指令和数据Cache 等。
(2)为加载Stage2准备RAM空间,为了获得更快的执行速度,通常把Stage2加载到RAM空间中来执行,因此必须加载BootLoader的Stage2准备一段可用的 RAM空间范围。
(3)拷贝Stage2到RAM空间,确定Stage2的可执行映像在固态存储设备的存放起始地址和终止地址以及RAM空间的起始地址。
(4)设置堆栈指针sp,这是为了执行Stage2的C语言代码做准备。
2。BoootLoader的Stage2
主要完成一下工作:
(1)用汇编语言跳到main入口函数
为了实现更复杂的功能和更好的代码可读性可移植性,Stage2的代码通常用C语言来实现。在编译和链接BootLoader时,不能使用glibc库中的任何支持函数。
(2)初始化串口,初始化计时器等硬件设备。在初始化这些设备之前,可以输出一些打印信息。
(3)检测系统的内存映射,所谓内存映射就是指在整个4GB物理地址空间中有哪些地址范围被分配用来寻址系统的RAM单元。
(4)加载内核映像和根文件系统映像,这里包括规划内存占用的布局和从Flash上拷贝数据。
(5)设备内核的启动参数
UBoot
UBoot是在ppcboot和ARMboot基础上发展而来的较为通用的bootloader,支持的嵌入式操作系统和嵌入式处理器种类众多,U-boot的源码目录,编译形式,与linux内核很相似,很多U-boot源码就是linux内核源程序的简化。
U-boot不仅支持嵌入式linux系统的引导,还支持netbsd,vxworks,,等嵌入式系统。
U-boot除了支持PowerPC系列的处理器外,还能支持MIPS,X86等多种类型处理器
U-Boot主要功能:
(1)系统引导
(2)基本辅助功能
(3)设备驱动
(4)上电自检功能
(5)特殊功能