考虑到网上的文档虽然有介绍ARM Linux的启动过程的,但是一般没有给出流程图,也讲的十分零星,没有一个全貌,我就主要以流程图的方式给出,再一点一点的详解每个过程,刚刚接触嵌入式ARM Linux,很多问题理解不深,可能有错误的地方,还望各位高手指出,一起讨论,一起进步,开源万岁!
一 引言
在专用的嵌入式板子运行 GNU/Linux 系统已经变得越来越流行。一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次:
1. 引导加载程序。 包括固化在固件(firmware)中的 boot 代码(可选),和 Boot Loader 两大部分。
2. Linux 内核。 特定于嵌入式板子的定制内核以及内核的启动参数。
3. 文件系统。 包括根文件系统和建立于 Flash 内存设备之上文件系统。通常用 ram disk 来作为 root fs。
4. 用户应用程序。 特定于用户的应用程序。有时在用户应用程序和内核层之间可能还会包括一个嵌入式图形用户界面。常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 懂。
引导加载程序是系统加电后运行的第一段软件代码。回忆一下 PC 的体系结构我们可以知道,PC 机中的引导加载程序由 BIOS(其本质就是一段固件程序)和位于硬盘 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起组成。BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的 Boot Loader 读到系统的 RAM 中,然后将控制权交给 OS Boot Loader。Boot Loader 的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
而在嵌入式系统中,通常并没有像 BIOS 那样的固件程序(注,有的嵌入式 CPU 也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由 Boot Loader 来完成。比如在一个基于 ARM7TDMI core 的嵌入式系统中,系统在上电或复位时通常都从地址 0x00000000 处开始执行,而在这个地址处安排的通常就是系统的 Boot Loader 程序。
——摘自詹荣开《嵌入式系统Boot Loader技术内幕》
http://www.ibm.com/developerworks/cn/linux/l-btloader/
二.基本概念
1.什么是loader?
Loader是在设备上没有任何引导程序是用于引导U-boot的一小段代码。它通过Xmodem协议load到SDRAM里,并启动Xmodem协议,提示用户下载U-boot,一旦用户通过Xmodem协议将U-boot传到SDRAM之后,PC指针就跳到U-boot,U-boot接管CPU。致此,loader的生命周期结束。掉电后,就丢失,因为存放在SDRAM里。我把它理解成PC机的应急启动盘。
2.什么是Boot?
Boot是设备每次上电或复位后执行的第一段代码,也用于引导U-boot。是每个设备必须的一小段代码。我把它理解为BIOS,当然不能完全这样理解,毕竟Boot和U-boot合起来才完成了BIOS的工作。
两者的区别与联系:
区别:
Loader通常在SDRAM里执行,只执行一次。不需要每次都执行
Boot通常存放在不丢失介质,如flash里,在上电后,从flash复制到SDRAM里执行
注:当然对于有些Flash(如Nor Flash)也可以在flash中执行,但是在SDRAM里执行更快,一般会copy到SDRAM里再执行
联系:两者都是为了引导U-boot而设计的
3.什么是U-boot?
U-boot功能非常强大,可以初始化硬件设备、建立内存空间的映射图,可以使用各种命令,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。我觉得U-boot的核心目标就是引导Linux Kernel。
4.什么是Linux Kernel?
Kernel ——操作系统内核:是大多数操作系统的核心部分。它由操作系统中用于管理存储器、文件、外设和系统资源的那些部分组成。操作系统内核通常运行进程,并提供进程间的通信。当然Linux Kernel并不像说的这么简单,但是对程序员来说就像天堂,我觉得是整个操作系统的精华所在,也是成为程序高手的捷径,我也要看内核源码,修炼内功!^_^
5.什么是ramdisk文件系统?
所谓的RAM驱动器,实际上是把系统内存划出一部分当作硬盘使用。对于操作系统来讲内存的存取速度远远大于机械磁盘,所以RAM驱动器肯定要比机械的硬盘快得多。
三.启动过程全流程
首先激活集成在内部ROM的Bootloader,也称为一级Bootloader。依次查找SPI上的DataFlash、连接在两线接口(TWI)上的EEPROM或连接在外部总线接口(EBI)上的8位存储器器件上的8位有效ARM异常向量。
若发现有效序列,会将Flash或EEPROM上的代码load到外部SDRAM中,再跳转到SDRAM开始执行;
若没有发现有效向量就引导Uploader启动,它初始化调试单元串行端口(DBGU)与USB器件端口,然后启动xmodem协议提示用户下载程序,此时用户终端将会显示CCC字符。下载的程序将会load到9200内部的SRAM(16K)。
而用于引导linux的u-boot通常体积很大,在100K以上的数量级,所以此时我们需要一个二级bootloader为u-boot程序的下载、运行创造运行环境,这个二级bootloader就是loader程序。Loader程序体积很小,其功能单一,与内部的bootloader(Uploader)相比,其增加了SDRAM的初始化过程。Loader程序可以通过一级bootloader下载到9200内部的SRAM,然后将CPU交给loader程序,loader程序初始化DEBUG端口、SDRAM之后同样启动xmodem协议,请求用户下载u-boot。具体内容可以参考at91rm9200提供的datasheet。——《AT91RM9200 DateSheet》P83-P94(引导程序章节)
通过xmodem协议将Uboot下载到SDRAM后,进入U-boot执行,在U-boot中可以设置各种环境变量,并且可以通过Kermit协议将Boot和U-boot下载到SDRAM中,再copy到flash里。然后开始引导内核,将内核参数转给内核。致此,U-boot光荣的完成它的任务,生命周期结束,(又一位英雄的逝世,呵呵……),终于我们强大的Linux Kernel接管CPU,系统开始走上正常轨道。