第十四讲嵌入式系统的BootLoader张朋月,手机13701338957zhangpy@yeah.net面向二十一世纪的嵌入式系统技术达盛知天培训中心课程简介课程内容:通过与PC系统与51单片机启动代码的比较来阐明嵌入式系统的bootloader.课程目的:使学员了解嵌入式系统的BootLoader的概念及嵌入式处理器大体的启动配置流程。讲座时间:25分钟51单片机的初始化代码与PC机的BIOS(一)各种处理器在上电或复位后都要从各自的ROM中读取一段代码来进行系统自身的初始化,在嵌入式系统开发过程中,这段代码被称为BootLoader在51类单片机中这种代码相对简单。下面就是51单片机的初始化代码。ORG0000HLJMPMAINORG0023HLJMPSETINTMAIN:CLREA------SETINT:------51单片机的初始化代码与PC机的BIOS(二)在我们所熟知的X86的PC体系结构中,PC机的引导加载程序由BIOS来完成的,所说的BIOS就是一种存贮在一片EEPROM中的一段配置代码程序,主要完成PC机外设的硬件检测和系统资源的分配,然后将硬盘中MBR主分区中操作系统启动程序读取到RAM中,并将控制权交给操作系统的启动程序,从而启动操作系统。由此可见51单片机系统的初始化是靠数行汇编语句来完成,而PC机的初始化是靠存贮在固定芯片中的BIOS程序代码来实现。51单片机的初始化代码与PC机的BIOS(三)接下我们研究一下PC的启动,PC的启动流程如下图示51单片机的初始化代码与PC机的BIOS(四)从现象来看,PC的BIOS更象是一种Boot程序,当Boot将控制权交给操作系统启动程序后,我们在PC的键盘按下F5或F8后,会看到系统提示我们是否正常启动还是进行到安全模式,如果我们安装有双操作系统,比如XP和Linux共同安装在同一台PC上,那可能就会提示,进入到那个操作系统,这种带有交互功能的Boot启动程序就可以定义为成是BootLoader了,这个BootLoader就存于主引导分区中,只是BootLoader体现的相对较弱。因此在PC系统中Boot和BootLoader共存于同一系统中,只是分属和位置不同而已。PC的BootLoader与操作系统密切相关,并侧重于与系统的交互装载引导功能,而Boot更侧重于引导功能,在非PC架构下的应用系统中,当Boot将控制权交给操作系统后,就无法再干预操作系统启动了,这也就是Boot与BootLoader的主要区别。嵌入式系统BootLoader的概念简单地说,BootLoader就是在嵌入式操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用处理方法,以指导特定的BootLoader设计与实现。Boot与BootLoader区别Boot是与CPU最小核心系统(SDRAM和FLASH)密切相关的,其功能上应该分为两种,一种是主要负责最小核心系统的配置,并把BootLoader或操作系统从固态存储器复制到内存中,并将控制权交给BootLoader。而另一种就是较为复杂的Boot,要全面配置适应操作系统的环境,然后把控制权直接交给操作系统,相当于BootLoader功能的载减。BootLoader可以说是首先含有Boot功能,但属于功能简单型,同时增加的交互功能和为适应操作系统启动的进一步配置功能,其与嵌入式操作系统有直接的关系,一些网络设备的启动都要在BootLoader下才能完成。Boot侧重于引导,BootLoader侧重于引导和交互,很多情况下BootLoader就完全完全当做Boot使用,但Boot一定不具有BootLoader的功能BootLoader几个关键点(一)1.BootLoader与最小核心系统硬件平台的关系每种不同的CPU体系结构都有不同的BootLoader。有些BootLoader也支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行在一块板子上的BootLoader程序也能运行在另一块板子上,通常也都需要修改BootLoader的源程序。比如我们把核心系统板上的内存加大一倍,那相应的BootLoader就要重新改动。BootLoader几个关键点(二)2.BootLoader在核心系统内存中的位置系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。比如,基于ARM7TDMI的S3C44B0在复位完成后,片选CS0有效,开始从地址0x00000000所连接的存储器中取它的第一条指令。这样CPU就开始执行BootLoader程序。下图是一个同时装有BootLoader、内核的启动参数、内核映像和根文件系统映像的固态存储设备的典型空间分配结构图。BootLoader几个关键点(三)3.BootLoader大多通过串口与主机交互信息主机和目标机之间一般通过串口建立连接,BootLoader软件在执行时通过串口输出打印信息给串口监控设备,用户也可以通过串口发送BootLoader能接受的控制字符,从而实现信息交互。BootLoader几个关键点(四)4.BootLoader加载启动过程CPU首选通过读出BootLoader前面相当于Boot功能的指令,完成CPU自身初级化及最少系统配置,然后将具有BootLoader功能的程序段复制到内存中,同时把控制权交给内存中的BootLoader。这个BootLoader再次把系统进行配置重新配置已适应操作启动环境。BootLoader几个关键点(五)5.BootLoader的操作模式(OperationMode)大多数BootLoader都包含两种不同的操作模式:启动加载模式和下载模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,BootLoader的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。这就等同于Boot功能。启动加载(Bootloading或Boot)模式:这种模式也称为自主(Autonomous)模式。也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时侯,BootLoader显然必须工作在Boot这种模式下。BootLoader几个关键点(五)下载(Downloading)模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用BootLoader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。像Blob或U-Boot等这样功能强大的BootLoader通常同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。比如,Blob在启动时处于正常的启动加载模式,但是它会延时10秒等待终端用户按下任意键而将blob切换到下载模式。如果在10秒内没有用户按键,则blob继续启动Linux内核。E-Boot是针对于WindowsCE操作系统的,情况与上述相同。BootLoader几个关键点(六)BootLoader与主机之间进行文件传输所用的通信设备及协议最常见的情况就是,目标机上的BootLoader通过串口与主机之间进行文件传输,传输协议通常是xmodem/ymodem/zmodem协议中的一种。但是,串口传输的速度是有限的,因此通过以太网连接并借助TFTP协议来下载文件是个更好的选择。基于PXA255平台的操作系统因为内核(15-30MB)很大,因此只有通过TFTP方式来下载才是最好的选择。BootLoader几个关键点(七)7.嵌入式系统的BootLoader写入实现与内核下载。一般情况下BootLoader代码,是通过JTAG方式下载并烧写到系统FLASH中的,这是嵌入式系统开发阶段最常用的做法。而内核是依赖于BootLoader启动后通过与其交互,依靠BootLoader里的下载命令来实现内核的下载与烧写。最终的产品化时,BootLoader会被裁减成Boot,同时和内核代码一同用烧写器或器件出厂时将程序用掩膜的方式事先放置在Flash中。涉及操作系统升级的产品,要保留BootLoader功能,因为大多数产品操作系统升级是依赖于BootLoader的BootLoader的启动配置流程(一)系统启动代码完成基本软硬件环境初始化后,对于有操作系统的情况下,启动操作系统、启动内存管理、任务调度、加载驱动程序等,最后执行应用程序或等待用户命令;对于没有操作系统的系统直接执行应用程序或等待用户命令。下图就是解析启动代码如何对系统进行配置的。BootLoader的启动配置流程(二)1.启动代码的第一步是设置中断和异常向量。这与51单片机的类似。2.完成系统启动所必须的最小的寄存器配置,某些处理器芯片包含一个或几个全局寄存器,这些寄存器必须在系统启动的最初进行配置,这一点至关重要,而且在顺序上不要出差错。3.设置看门狗,用户设计的部分外围电路如果必须在系统启动时初始化,就可以放在这一步。4.配置系统所使用的存储器,包括Flash,SRAM和DRAM等,并为他们分配地址空间。如果系统使用了DRAM或SDARM,就需要设置相关的寄存器,以确定其刷新频率,数据总线宽度等信息,初始化存储器系统。有些芯片可通过寄存器编程初始化存储器系统,而对于较复杂系统通常集成有MMU来管理内存空间。5.为处理器的每个工作模式设置栈指针,ARM处理器有七种工作模式,每种工作模式都需要设置单独的栈空间。BootLoader的启动配置流程(三)6.变量初始化,这里的变量指的是在软件中定义的已经赋好初值的全局变量,启动过程中需要将这部分变量从只读区域,也就是Flash拷贝到读写区域中,因为这部分变量的值在软件运行时有可能重新赋值。还有一种变量不需要处理,就是已经赋好初值的静态全局变量,这部分变量在软件运行过程中不会改变,因此可以直接固化在只读的Flash或EEPROM中。7.数据区准备,对于软件中所有未赋初值的全局变量,启动过程中需要将这部分变量所在区域全部清零。8.最后一步是调用高级语言入口函数,比如main函数等。BootLoader高级语言的主函数所具有的大体功能BootLoader在配置完成并跳转到高级语言函数中后,首先要将串口打通,通过串口与监控终端交互信息。这个函数可以系统进行一些检查、设置、下载管理等一些工作。如下所示是PXA270的E-boot启动后的界面。基于PXA270有E-boot功能说明其中设置系统板上网络的IP地址,供下载内核用。设置子网掩码启动时间大约50秒BOOT延时1秒,如果不按空格则直接启动内核,按下空格出现该图界面。DHCP自适应网络是否使能复位到出厂状态下载新的内核映像文件把RAM中的内容写入到Flash中编程网络的MAC地址Boot启动顺序,先