嵌入式Linux的引导加载程序——Bootloader

对于嵌入式Linux系统来说,从开机上电到操作系统启动需要一个引导过程,引导过程体现在引导程序上,而这个引导程序就叫作Bootloader。


嵌入式Linux的引导加载程序——Bootloader


Bootloader的概念与作用

Bootloader 是嵌入式系统的引导加载程序,它是系统上电后运行(操作系统运行之前)的第一段程序 。通过这段程序可以初始化硬件设备、建立内存空间的映射表,从而建立系统的软硬件环境,为最终调用Linux操作系统内核做好准备。在完成对系统的初始化任务之后,它会将非易失性存储器(通常是Flash)中的内核拷贝到RAM中去,然后跳转到内核的第一条指令处继续执行,从而启动Linux内核。另外,几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader,Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。


Bootloader的种类

现在已经有各种各样的Bootloader,种类划分也有多种方式。下面就来看一下常用的引导加载程序:

ROLO:从ROM引导Linux而不需要BIOS,支持X86架构,不支持ARM和PowerPC;

Etherboot:通过以太网卡启动Linux系统的固件,支持X86架构,不支持ARM和PowerPC;

U-boot:通用引导加载程序,支持X86架构,并支持ARM和PowerPC;

RedBoot:基于eCos的引导加载程序,支持X86架构,并支持ARM和PowerPC;

值得指出的是Redboot,它几乎能够支持所有的体系结构,包括MIPS、SH、M68K等体系结构。Redboot是以eCos为基础,采用GPL许可的开源软件工程。


Bootloader的启动流程

Bootloader的实现依赖于CPU的体系结构,因此大多数的bootloader一般都是分为两个阶段的,第一个阶段使用汇编来实现,它完成一些依赖于CPU体系结构的初始化,并调用第二阶段的代码;第二阶段则通常使用C语言来实现,这样可以实现更复杂的功能,而且代码会有更好的可读性和移植性。


Bootloader的第一阶段

主要包含以下步骤:

1、一些基本的硬件初始化工作 :主要设置CPU的速度和时钟频率、屏蔽所有中断和清除指令与数据缓存

2、准备RAM空间:所谓准备RAM空间,就是初始化内存芯片,使它可被用

3、设置好堆栈:设置堆栈指针是为执行C语言代码做准备,栈的设置灵活性很大,只要让sp寄存器指向一段没有使用的内存即可

4、跳转到第二阶段的C入口点:在ARM中,通过修改PC寄存器为相应的地址来实现


Bootloader的第二阶段

主要包含以下步骤:

1、初始化本阶段要使用到的硬件设备:最重要的是设置系统时钟和初始化串口

2、检查系统内存映射

3、将内核映像和根文件系统从Flash上读到RAM空间中:

对于内核映像,一般将其拷贝到从0x30008000这个基地址开始的大约1MB大小的内存范围内(嵌入式 Linux 的内核一般都不操过 1MB),在这一区域前空出来的32KB内存是为了放置一些全局数据结构

4、为内核设置启动参数

5、调用内核:BootLoader调用Linux内核的方法是直接跳转到内核的第 一条指令处,在跳转时,下列条件要满足: CPU 寄存器的设置: R0=0; R1=机器类型 ID; R2=启动参数标记列表在 RAM 中 起始基地址; CPU模式: 必须禁止中断;CPU必须为SVC模式; Cache 和 MMU 的设置: MMU 必须关闭; 指令 Cache 可以打开也可以关闭; 数据 Cache 必须关闭


结语

嵌入式系统的开发过程除了涉及软件和硬件,同时还需要结合上层应用综合考虑,而其中成本约束又是最关键的因素之一,嵌入式系统的硬件平台通常是根据应用量身定制,通常所用的MPU、存储器、外围设备等有多种选择余地,使系统的引导加载设计变得十分复杂,如果我们从零开始实现的话是非常困难且低效率的,正确的做法应该是从相关的例程中寻找与硬件平台最接近的作为参考程序,然后根据硬件平台作相应的修改。


嵌入式Linux的引导加载程序——Bootloader


分享到:


相關文章: