0 导言
由Boot Loader和固化在固件(firmware)中的Boot代码(可选)一起组成一个嵌入式体系的引导加载程序。它的效果和功用就像固化到计算机内主板上的一个ROM芯片程序BIOS(basic input output system)。可是它一般不装备像BIOS那样的固件程序,这是由于要考虑经济方面的原因,因而有必要自己完结这方面的作业。Boot Loader能够初始化硬件设备,树立内存空间的映射图,从而将体系的软硬件环境带到一个适宜的状况,以便为终究调用操作体系内核预备好正确的环境。它的完结严重地依赖于硬件,特别是在嵌入式体系中,即便根据同一个CPU的Boot Loader,关于不同的板子,也有很大的不同。
1 Boot Loader剖析
体系加电,然后复位后,根本上一切的CPU都是从复位地址上取得指令的。以微处理器为中心的嵌入式体系中,一般都有某种类型的固态存储设备(FLASH,E2PROM等),这个固态存储设备被映射到一个预先设置好的地址上。在体系加电复位后,一开端处理器就会去履行寄存在复位地址处的程序,并且经过开发环境能够将Boot Loader定位在复位地址一开端的存储空间上,因而Boot Loader是体系加电后,在操作体系内核或许一些应用程序被运转之前,首要会运转的程序。关于嵌人式体系来说,比较杂乱的或许为了便利后期开发大的应用程序,有的运用操作体系,也有许多的情况下,因功用简略,或仅包含应用程序的体系不运用操作体系,可是不管有无操作体系在发动时都有必要履行Boot Loader,为的是预备好软硬件运转环境。
以微处理器为中心的嵌入式体系中,一般都有某种类型的固态存储设备(FLASH,E2PROM等),这个固态存储设备被映射到一个预先设置好的地址上。在体系加电复位后,一开端处理器就会去履行寄存在复位地址处的程序。并且经过开发环境能够将Boot Loader定位在复位地址一开端的存储空间上,因而Boot Loader是体系加电后,在操作体系内核或许一些应用程序被运转之前,首要会运转的程序。关于Linux体系,它的主要使命有以下7个方面。
(1)初始化处理器及外设的硬件资源装备。一般嵌入式体系的处理器在上电复位后,外部的I/O引脚都处于输入状况,处理器的片内和片外设备资源都需求装备。
(2)树立内存空间的映射图,从而将体系的软硬件环境带到一个适宜的环境,这样就能为终究发动操作体系的内核供给最好条件。
(3)把操作装载到映射的内存中,这也是一切使命傍边最重要的一个,只要完结这个使命,操作体系才干被装载到内存傍边去,Boot Loader一般会供给串口和网络装载两种方法。
(4)为了把操作体系的映像保存在FLASH中,以便今后发动,能够直接装载FLASH的数据,而不必从头下载程序,但需求对FLASH进行编程。
(5)运转操作体系。设置相关的寄存器和资源,跳转到操作体系的地点空间,进行相关的引导,这便是Boot Loader。
(6)在Linux体系发动时,传递体系的发动参数,能够给内核传递指令行等参数,经过指令行能够挑选操控体系的发动形式。
(7)指令行的解析和输入/输出操控。为了开发的便利,大都的Boot Loader都选用串口作为终端的操控方法。
Boot Loader的发动进程可分为两个重要阶段。第一阶段:由于Boot Loader的完结依赖于CPU的体系结构,所以设备代码的初始化等功用都在该阶段完结。并且,为了到达缩短代码的意图,一般用汇编言语来编写。在这一阶段的履行进程中,又可分为几个方面。
①硬件设备的初始化。在该阶段的履行进程中,首要需求对硬件设备进行初始化,其意图主要是为第二阶段的履行以及随后Kernel的调用预备根本的硬件环境。
②为加载Boot Loader的第二阶段预备RAM空间。为了取得更快的履行速度,一般把第二阶段加载到RAM空间中来履行。因而,有必要为加载Boot Loader预备好一段可用的RAM空间规模。
③设置仓库指针。设置仓库是为了履行C言语代码作好预备。
④跳转到第二阶段的C进口点。当程序履行到这个方位时,能够经过修正PC寄存器的值,使其跳转到第二阶段。
第二阶段阶段的发动流程剖析:为了便于完结杂乱的功用和取得更好的代码可读性和可移植性,一般第二阶段的代码用C言语来完结。可是,与一般C言语的不同之处是,这儿运用了“弹簧床”的概念,即先用汇编言语写一段小程序,并将这段小程序作为第二阶段可履行映像的履行进口点,然后在汇编程序顶用CPU跳转指令跳入main()函数中去履行,当main()函数回来时,CPU履行途径再次回来到汇编程序中第二阶段,包含初始化本阶段要运用的硬件设备,检测体系内存映射,会将Kernel映像和根文件体系映像从FLASH中读到RAM空间中,为内核设置发动参数调用内核。
2 Boot Loader的规划
2.1 中止向量表(二级)的规划与树立
假如有中止或许反常产生时,处理器便会强制性地把PC指针指向向量表中它所对应的中止类型地址值。为了进步中止响应速度,FLASH的0x0地址寄存能跳转到0x33FFFF00地址处中止向量的跳转指令,也便是会在在RAM中树立一个二级中止向量表,开端地址为0x33FFFF00。除了复位外,一切的反常进口地址都由FLASH跳转得到,代码如下:
2.2 第二阶段复制到RAM
把第二阶段Stage2复制到RAM地址的最顶巨细为1 MB的开端空间,RAM的开端地址为0x30000000。代码如下所示:
2.3 仓库指针的设置
用户运用哪些中止决议了体系仓库的初始化,以及体系需求处理的哪些过错类型。一般情况下,仓库设置是有必要,并且是由管理者自己设置的。假如需求运用IRQ中止,那么IRQ仓库的设置也是有必要的,下面是IRQ仓库的设置:
3 Stage2的规划
3.1 可履行映像Stage2的进口
由于Glibc库支撑的函数不能用于编译和链接Boot Loader这样用C言语编写的程序,因而把main()函数的开端地址作为第二阶段的进口点是最直接的主意。能够用汇编编写一段Trampoline小程序,用CPU跳转指令跳到main()函数去履行,当函数回来时会再次回到Trampoline程序,代码如下:
程序顺畅时就不会再回到开端的Trampoline程序,否则就会回到最终的句子,体系就会从头发动。
3.2 内存暗射
一般S3C2410上装备的SDRSAM巨细为64 MB,该SDRAM的物理地址规模是Ox30000000~Ox33FFFFFF(归于Bank 6)。由Section的巨细可知,该物理空间可被分红64个物理段。由于ARM体系结构中数据缓冲有必要经过MMU敞开,因而Boot Loader功率不是很高,可是MMU能够经过平板映射(虚拟地址和物理地址相同)方法被敞开,这样运用内存空间Dcache,从而使Boot Loader的运转速度得到有用的进步。映射联系代码如下:
3.3 装载内核映像和根文件体系映像
像ARM这样的嵌入式CPU一般都是在一致的内存地址空间中寻址FLASH等固态存储设备的,因而从Flash上读取数据与从RAM单元中读取数据相同,用一个简略的循环就能够完结从FLASH设备上复制映像的作业:其间count为根文件体系映像的巨细或内核映像的巨细。
3.4 内核的发动参数的设置
内核发动能够从NAND FLASH(NOR FLASH)中发动运转Linux,需求修正发动指令如下:
LCD发动参数一般都包含root,init和console。noinitrd不运用ramdisk。root根文件体系在MTD分区。Init内核运转进口指令文件。co-nsol内核信息操控台,ttys0表明串行口0;tty0表明虚拟终端。
4 结语
经过对Boot Loader的剖析能够看出,规划一个功能优秀的Boot Loader能够进步体系的安稳性及实时性,它是嵌入式开发中不可或缺的一部分。只要规划出一个安稳的Boot Loader,才干进行下一步的体系开发作业,直至完结整个嵌入式体系的开发。规划Boot Loader是一项很杂乱的作业,需求对硬件资源和所用的操作体系有很深的了解。