基于ARM的嵌入式系统引导装载程序分析

2016-01-18 13:25贺小慧
电脑知识与技术 2015年33期
关键词:嵌入式系统

贺小慧

摘要:引导装载程序(Bootloader)是嵌入式系统CPU上电或复位以后执行的第一段代码,在嵌入式系统的开发过程中起着重要的作用。该文分析了引导装载程序的功能与结构,并介绍了其移植过程。

关键词:嵌入式系统;引导装载程序;ARM;Linux

中图分类号:TP391 文献标识码:A 文章编号:1009-3044(2015)33-0142-02

Analyzing of Bootloader in Embedded System Based on ARM

HE Xiao-hui

(College of Electronics and Information, Xi'an Polytechnic University, Xi'an 710048, China)

Abstract: Bootloader, the first running program after a power-on or reset of a cpu in an embedded system, plays an important role in the development of an embedded system. This paper introduces and analyzes the function, structure and porting process of the bootloader.

Key words: embedded system; Bootloader; ARM; Linux

嵌入式系统是以应用为中心,以计算机技术为基础,软件与硬件可裁剪,满足应用系统对功能、可靠性、成本、体积和功耗的严格要求的专用计算机系统。基于ARM核的32位嵌入式RISC微处理器具有高性能、低功耗、低成本等优点,在嵌入式系统开发领域获得了广泛的应用。Linux操作系统支持多种不同体系结构的CPU,易于裁剪和移植,并且开放源码,功能完善与更新的速度很快,越来越适应嵌入式系统开发的需要。

嵌入式系统的引导过程,就是指从CPU上电或复位的时刻起,直到操作系统内核开始执行的全过程。引导过程的最终目的是为操作系统的运行准备好硬件和软件环境。在PC机中,CPU上电或复位以后,首先由BIOS检测系统各项硬件资源,然后由引导设备的主引导扇区中的引导程序加载操作系统,再跳转到操作系统入口处,将控制权交给操作系统,然后执行操作系统。而在嵌入式系统中没有专门的BIOS,所以以上的功能通常都由引导装载程序(Bootloader)来完成。Bootloader是用于初始化CPU及其他目标板上硬件设备,为嵌入式操作系统内核提供硬件信息,并装载和引导嵌入式操作系统内核的固件,它是CPU上电或复位以后执行的第一段代码,在嵌入式系统的开发过程中起着非常重要的作用。

1 常用Bootloader简介

1)ARMboot

ARMboot是一个为基于ARM系列微处理器的嵌入式系统所设计的开放源码项目,目前已经与PPCBoot合并成新的项目U-Boot。

ARMboot专用于支持ARM7,ARM9,StrongARM,XScale等ARM系列的微处理器。

ARMboot支持多种类型的Flash存储器,可通过bootp、dhcp、tftp等协议从网络下载映像文件,并且支持PCMCIA和CF等存储卡引导系统。

2)U-Boot

U-Boot全称为Universal Bootloader,是一个遵循GPL的开放源码项目,由PPCBoot以及ARMboot等发展而来。

U-Boot支持的处理器包括PowerPC、MIPS、ARM和x86等不同体系结构的多种系列。U-Boot与Linux的关系非常紧密,一部分源代码也来自于Linux源码,为Linux内核的引导提供了特别的支持。

3)Blob

Blob全称为Boot Loader OBject,最初是专门为使用StrongARM系列中SA-1100处理器的LART板所设计的,现在已经移植到多种平台上。

Blob的主要功能包括初始化硬件(CPU,存储器,中断控制器,串口等),引导Linux内核以及为Linux内核提供虚拟盘(Ramdisk)支持,下载Linux内核或Ramdisk到目标板上,烧写Flash存储器,确定存储器布局,向Linux内核传递命令行等。

4)vivi

vivi是由韩国MIZI公司为ARM系列处理器设计的一个Bootloader,支持SA-1110,S3C2400,S3C2410,PXA250等处理器,目前仅支持通过串口与主机通信。

vivi易于增加对新处理器和新目标板的支持,易于移植设备驱动,支持多种MTD驱动,可以下载测试代码到RAM中执行。

2 Bootloader的典型结构

虽然Bootloader的种类很多,但是其基本结构框架都是比较相似的。由于Bootloader需要对系统硬件进行检测和初始化设置,其中的很多代码都直接对CPU和其他硬件设备进行操作,因此Bootloader依赖于CPU的体系结构和目标板具体的硬件配置,所以大多数的Bootloader都分为stage1和stage2两个部分。

2.1 stage1部分

stage1部分主要包括依赖于CPU体系结构和目标板上具体硬件配置的那部分代码,通常用汇编语言来实现,这样可以使代码短小精悍,执行速度最快。这部分的主要功能如下:

2.1.1 初始化硬件

Bootloader第一步要完成的工作就是对目标板硬件的初始化,主要包括禁止看门狗,禁止中断,设置CPU和总线时钟频率,初始化LED数码管和串口等。根据AMBA总线协议,CPU的时钟频率FCLK、AHB总线(Advanced High-performance Bus)的时钟频率HCLK和APB总线(Advanced Peripheral Bus)的时钟频率PCLK可以配置成倍比关系。AHB总线是高速总线,一般用来连接内存等高速设备,APB总线是低速总线,一般用来连接串口,通用I/O口等低速设备。通常FCLK : HCLK : PCLK的比例为1 : 2 : 4,即如果CPU时钟频率为200MHz,则AHB总线时钟频率为100MHz,APB总线时钟频率为50MHz。

2.1.2 加载并执行stage2

为了获得更快的执行速度,以及便于存放变量和堆栈,通常需要把Bootloader的stage2部分加载到RAM空间中执行。由于stage2通常是C语言代码,因此在分配空间时,除了考虑stage2程序映像的大小外,还必须考虑所需堆栈空间的大小。为了确保所分配的地址空间的确是可读写的RAM空间,还必须对其进行检测。然后将stage2代码从Flash上拷贝到RAM空间中,并设置堆栈指针SP,由于堆栈是向下生长的,因此通常把SP设置为stage2的RAM空间的最顶端。接着修改PC 寄存器的值为stage2的入口地址,从而开始执行stage2部分。Bootloader通常用一小段汇编代码作为stage2的入口点,然后在这段汇编代码中用跳转指令跳到main() 函数的起始地址处执行。

2.2 stage2部分

stage2部分主要包括和CPU体系结构以及目标板上其他硬件配置无关的那部分代码,也包括一些复杂硬件的初始化代码,通常用C语言来实现,这样可以实现更复杂的功能,并且保证了代码的可读性和可移植性。这部分的主要功能如下:

2.2.1 检测内存映射

所谓内存映射(Memory Map),就是指在整个RAM地址空间中有哪些地址范围被分配用来寻址真正的RAM单元。在嵌入式系统中通常只将整个RAM地址空间中的一部分映射到实际的RAM单元上,因此stage2必须首先检测系统的内存映射情况,为内核映像和根文件系统映像的加载做好准备。

2.2.2 加载内核映像和根文件系统映像

根据嵌入式系统的具体配置,将操作系统的内核映像和根文件系统映像从Flash存储器中读取到RAM空间中的相应地址。

2.2.3 启动内核

在启动Linux内核之前,可以通过设置内核启动参数,向内核提供一些内核自己不能检测出的硬件信息,或者覆盖内核检测出的信息,可以通过标记列表(tagged list)或命令行参数(command line)的形式来传递启动参数。Bootloader启动Linux内核的方法通常是直接跳转到内核的第一条指令处。这样就将控制权交给了操作系统,从而完成了整个引导过程。

3 Bootloader的移植过程

嵌入式Linux系统的引导过程比较复杂,和系统硬件及操作系统内核都有着密切的关系,自己重新编写Bootloader难度较大。所以,通常都是选择一个最接近要求的现有Bootloader程序,然后根据需要进行修改后再应用到目标板中,这就是Bootloader的移植。

由于Bootloader依赖于CPU的体系结构和目标板具体的硬件配置,因此对于两块不同的嵌入式目标板而言,即使它们使用的是同一种CPU,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,通常也需要对Bootloader进行移植。

Bootloder的移植过程包括以下步骤:

1)选择参考板

根据目标板的具体硬件配置,选择一个与目标板采用同一种或者同一系列的CPU,其他硬件配置也最接近的参考板。

2)确定Bootloader的存放地址

Bootloader是CPU上电或复位以后执行的第一段代码,所以Bootloader的存放地址必须和CPU硬件复位向量所指向的地址相一致。在基于ARM系列的嵌入式Linux系统中,通常将Bootloader放在地址0x0处。

3)修改相关文件

对参考板的Bootloader程序进行修改,需要修改的文件包括stage1的汇编语言文件(如vivi中的head.S文件或U-Boot中的start.S文件等)和stage2中与硬件配置(如Flash,串口等)有关的C语言文件。

4)烧写Bootloader并调试

使用Flash烧写程序将Bootloader烧写到Flash中,烧写完成后,重启目标板,使用超级终端(Windows下)或minicom(Linux下)通过串口查看Bootloader的启动信息,或者进入命令行状态调试。

4 总结

Bootloader初始化和检测系统硬件,然后加载和运行操作系统内核,这些工作为整个嵌入式Linux系统的顺利运行,准备好了硬件和软件的环境。因此,对Bootloader的研究和应用在嵌入式系统开发中有着非常重要的作用。

参考文献:

[1] ARMboot[EB/OL]. (2002-08).http://sourceforge.net/projects/armboot.

[2] U-boot [EB/OL]. (2002-08).http://sourceforge.net/projects/u-boot.

[3] Blob [EB/OL]. (2002-01).http://sourceforge.net/projects/blob.

[3] 邹思轶. 嵌入式Linux设计与应用[M]. 北京:清华大学出版社,2002.

猜你喜欢
嵌入式系统
基于物联网项目驱动的嵌入式系统教学改革的研究与实践
嵌入式系统课程“中断、异常与事件”教学实践及启示
面向实践创新人才培养的嵌入式系统教学研究