Bootloader技术

发布时间:2024-06-02 21:08:29 作者:汉语成语

BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。

Bootloader的操作模式

大多数BootLoader都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,BootLoader的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。

启动加载(Bootloading)模式:这种模式也称为"自主"(Autonomous)模式。也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时侯,BootLoader显然必须工作在这种模式下。

下载(Downloading)模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。BootLoader的这种模式通常在次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用BootLoader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。

像Blob或U-Boot等这样功能强大的BootLoader通常同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。比如,Blob在启动时处于正常的启动加载模式,但是它会延时10秒等待终端用户按下任意键而将blob切换到下载模式。如果在10秒内没有用户按键,则blob继续启动Linux内核。

BootLoader所支持的CPU和嵌入式板

每种不同的CPU体系结构都有不同的BootLoader。有些BootLoader也支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行在一块板子上的BootLoader程序也能运行在另一块板子上,通常也都需要修改BootLoader的源程序。

BootLoader的安装媒介

系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。比如,基于ARM7TDMIcore的CPU在复位时通常都从地址0x00000000取它的条指令。而基于CPU构建的嵌入式系统通常都有某种类型的固态存储设备(比如:ROM、EEPROM或FLASH等)被映射到这个预先安排的地址上。因此在系统加电后,CPU将首先执行BootLoader程序。

下图就是一个同时装有BootLoader、内核的启动参数、内核映像和根文件系统映像的固态存储设备的典型空间分配结构图。

图固态存储设备的典型空间分配结构

Bootloader程序流程

系统上电复位后,在完成各种初始化配置后首先判断0x500地址单元中值是否为0xFF,如果是,则说明系统从未下载过用户程序,系统会一直运行Bootloader程序等待PC机发送下载命令;如果0x500中的值不是0xFF,则说明系统中已经下载过用户程序了,这时候根据0x500中的值来设置定时器Timer2的初值并开始计时,如果UART2在指定的自举周期内未接收到PC机发来的下载命令(说明系统不需要下载程序),系统会自动跳出Bootloader程序而去运行已有的用户代码,如果UART2在自举周期内接收到了下载命令,Bootloader程序会进入循环状态等待PC机发送数据。如图所示。

图程序流程图。

如前文所述,PC机发送的数据是从.hex文件中提取的,PC机首先发送扩展地址部分,下位机接收保存后会继续等待接收32个指令字(96字节)并保存到RAM中,然后根据接收到的地址擦除FLASH存储器中的1行,擦除FLASH是通过调用汇编函数EraseMem来进行的,函数原型如下:

mov#0x4041,NVMCON;使NVMCON寄存器为擦除FLASH模式

mov#0x55,W0

movW0,NVMKEY

mov#0xAA,W0

movW0,NVMKEY;将0x55、0xAA写入密钥寄存器

bsetNVMCON,#WR;开始擦除

nop

nop

return

擦除FLASH存储器的一行后需要把接收到的32个指令字写入到FLASH存储器写锁存器中,这一过程可以通过函数WriteLatch实现,函数原型如下:

movW0,TBLPAG;写表寄存器

tblwtlW3,[W1]

tblwthW2,[W1];写入锁存器

return

这一步完成之后就可以将接收到的32个指令字写入FLASH存储器了,其方法与擦除FLASH类似,写完一行后向PC机发送应答。待FLASH存储器全部写完之后,PC机会发送表示结束下载的命令,下位机接收后退出Bootloader程序,进入新的用户程序继续运行,从而完成整个在线自编程过程。

Bootloader的原理

Bootloader相当于PC主板上的BIOS,是层的引导软件。Bootloader是一段固化在嵌入式系统目标系统ROM或者是诸如FLASH等非易失存储器中的一段程序,它的主要作用就是引导操作系统或用户程序的运行。系统上电后Bootloader将首先接管系统,在进行一些最基本的上电自检后,Bootloader将对系统的硬件进行初始化,为引导操作系统作好准备,接下来,Bootloader需要将操作系统的代码拷贝到主存储器的特定地址,Bootloader将控制权交给操作系统,由操作系统完成接下来的工作;在不含操作系统的系统中,Bootloader可以完成这样一些操作:分配程序存储空间;重新映射复位和中断向量;将程序代码从片外加载到程序区,执行时再将代码加载到RAM中以便快速执行;检测是否需要下载新的用户代码,若需要则通过某种通信方式接收新代码并将其写入指定程序存储空间中,若不需要,则执行原有用户代码。