BootLoader概述
一个嵌入式Linux系统从软件的角度看通常分为4个层次:引导加载程序、Linux内核、文件系统、用户应用程序。
引导加载程序是系统加电后运行的第一段代码。大家熟悉的PC中的引导程序一般由BIOS和位于MBR的操作系统BootLoader(例如LILO或者 GRUB)一起组成。然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动任务就完全由BootLoader来完成。在嵌入式 Linux中,引导加载程序即等效为BootLoader。简单地说,BootLoader就是在操作系统内核运行前执行的一段小程序。通过这段小程序,我们可以初始化必要的硬件设备,创建内核需要的一些信息并将这些信息通过相关机制传递给内核,从而将系统的软硬件环境带到一个合适的状态,最终调用操作系统内核,真正起到引导和加载内核的作用。
BootLoader 是依赖于硬件实现的,特别是在嵌入式系统中。不同体系结构需求的BootLoader是不同的,除了体系结构,BootLoader还依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们基于相同的CPU构建,运行在其中一块电路板上的BootLoader,未必能够运行在另一块电路开发板上。
Bootloader 的启动过程可以是单阶段的,也可以是多阶段的。大多数单阶段的BootLoader应用于简单的系统,比如没有操作系统的系统。通常多阶段的 BootLoader能提供更为复杂的功能以及更好的可移植性。从固态存储设备上启动的BootLoader大多数是两阶段的启动过程,也就是启动过程可以分为stage 1和stage 2两部分。依赖于CPU体系结构的代码,比如设备初始化代码 等,通常都放在stage1中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而stage2则通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。
大多数BootLoader都包含两种不同的操作模式:启动加载(Boot loading)模式和下载(Down loading)模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,BootLoader的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。
(1)启动加载模式:这种模式也称为自主(Autonomous)模式,即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程没有用户的介入。这种模式是BootLoader的正常工作模式。因此在嵌入式产品发布的时候,BootLoader显然必须工作在这种模式下。
(2)下载模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机上下载文件,比如下载应用程序、数据文件、内核映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中然后再被BootLoader写到目标机上的固态存储设备中, BootLoader的这种模式通常在系统更新时使用。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口,比如U -Boot、Blob、VIVI等。
常用的嵌入式Linux BootLoader
从上一节的内容可以了解到BootLoader是嵌入式系统中非常重要的一部分,也是系统运行工作的必要组成部分。在嵌入式系统中常见的BootLoader有以下几种。
U-Boot
U- Boot是德国DENX小组开发的用于多种嵌入式CPU的BootLoader程序,它可以运行在基于PowerPC、ARM、MIPS等多种嵌入式开发板上。从或 de/pub/u-boot/站点都可以下载U-Boot的源代码,U-Boot源代码的主要目录解释如下。
● board 目标板相关文件,主要包含SDRAM、Flash驱动;
● common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;
● cpu 与处理器相关的文件,如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;
● driver 通用设备驱动,如CFI Flash驱动(目前对Intel Flash支持较好);
● doc U-Boot的说明文档;
● examples 可在U-Boot下运行的示例程序,如hello_world.c、timer.c;
● include U-Boot头文件,尤其是configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;
● lib_xxx 处理器体系相关的文件,如lib_ppc、lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;
● net 与网络功能相关的文件目录,如bootp、nfs、tftp;
● post 上电自检文件目录,尚有待于进一步完善;
● rtc RTC(Real Time Clock,实时时钟)驱动程序;
● tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具。
VIVI
VIVI 是由韩国MIZI公司开发的专门用于ARM产品线的一种BootLoader。因为VIVI 目前只支持使用串口和主机通信,所以必须使用一条串口电缆来连接目标板和主机。VIVI的源代码下载地址为:http: //www.mizi.com/developer/s3c2410x/download/vivi.html,VIVI一般有如下作用。
(1)把内核(kernel)从Flash复制到RAM,然后启动它;
(2)初始化硬件;
(3)下载程序并写入Flash;
(4)检测目标板。
vivi.tar.bz2源代码包解压后的目录结构如下所示:
# tree –L 1
.
|-- COPYING
|-- CVS
|-- Documentation
|-- Makefile
|-- Rules.make
|-- arch
|-- drivers
|-- include
|-- init
|-- lib
|-- scripts
|-- test
`-- util
10 directories, 3 files
其中VIVI主要目录介绍如下。
● CVS 存放CVS工具相关的文件;
● Documentation 存放一些使用VIVI的帮助文档;
● arch 存放一些平台相关的代码文件;
● drivers 存放VIVI相关的驱动代码;
● include 存放所有VIVI源码的头文件;
● init 存放VIVI初始化代码;
● lib 存放VIVI实现的库函数文件;
● scripts 存放VIVI脚本配置文件;
● test 存放一些测试代码文件;
● util 存放一些NAND Flash烧写image相关的工具实现代码。
Blob
Blob是Boot Loader Object的缩写,是一款功能强大的BootLoader。其源码在上可以获取。Blob最初是由Jan-Derk Bakker和Erik Mouw两人为一块名为LART(Linux Advanced Radio Terminal)的开发板写的,该板使用的处理器是StrongARM SA-1100,现在Blob已经被成功地移植到许多基于ARM的CPU上。
RedBoot
RedBoot 是一个专门为嵌入式系统定制的引导启动工具,最初由Redhat开发,它是基于eCos(Embedded Configurable Operating System)的硬件抽象层,同时它继承了eCos的高可靠性、简洁性、可配置性和可移植性等特点。RedBoot集Bootloader、调试、 Flash烧写于一体,支持串口、网络下载,执行嵌入式应用程序。既可以用在产品的开发阶段(调试功能),也可以用在最终的产品上(Flash更新、网络启动)。RedBoot支持下载和调试应用程序,开发板可以通过BOOTP/DHCP协议动态配置IP地址,支持跨网段访问。用户可以通过tftp协议下载应用程序和image,或者通过串口用x-modem/y-modem下载。RedBoot支持用GDB(the GNU debugger)通过串口或者网卡调试嵌入式程序,可对gcc编译的程序进行源代码级的调试。相比于简易jtag调试器,它可靠、高速(CPU的 cache打开后,通过网卡tftp下载能达到1Mbps,GDB下载的速度能达到2Mbps)、稳定,用户可通过串口或网卡,以命令行的形式管理 Flash上的image,下载image到Flash。动态配置RedBoot启动的各种参数、启动脚本,上电后RedBoot可自动从Flash或 tftp服务器上下载应用程序执行。在站点可以下载RedBoot源码,同时可以了解更多的关于RedBoot的详细信息,它在嵌入式系统应用中非常广泛。
ARMboot
ARMboot 是一个以ARM或StrongARM 为内核CPU的嵌入式系统的BootLoader固件程序,该软件的主要目标是使新的平台更容易被移植并且尽可能地发挥其强大性能。它只基于ARM固件,但是它支持多种类型的启动,比如Flash,网络下载通过bootp、dhcp、tftp等。它也是开源项目,可以从http: //网站获得最新的ARMboot源码和详细资料,它在ARM处理器方面应用非常广泛。
DIY
DIY (Do It Yourself),即自己制作。以上U-Boot、VIVI、Blob、RedBoot和ARMboot等成熟工具移植起来简单快捷,但同时它们都存在着一定的局限性,首先是因为它们是面向大部分硬件的工具,所以说在功能上要满足大部分硬件的需求,但一般情况下我们只需要与特定的开发板相关的实现代码,其他型号开发板的实现代码对它来说是没有用的,所以通常它们的代码量较大。其次它们在使用上不够灵活,比如在这些工具上添加自己的特有功能相对比较困难,因为必须熟悉该代码的组织关系,以及了解它的配置编译等文件。用DIY的方式自己编写针对目标板的BootLoader不但代码量短小,同时灵活性很大,最重要的是将来容易维护。所以在实际嵌入式产品开发时大都选择DIY的方式编写BootLoader。
原帖地址: