深入理解BootLoader.html.pdf
《深入理解BootLoader.html.pdf》由会员分享,可在线阅读,更多相关《深入理解BootLoader.html.pdf(53页珍藏版)》请在三一文库上搜索。
1、前言 BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射,从而将系统的软硬件环境设置 成一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。 在嵌入式系统中,通常没有像PC中的BIOS那样的固件程序,因此整个系统的加载启动任务就完全由BootLoader来完成。BootLoader是CPU上电后运行的第一段程 序,它的作用就是对嵌入式系统中的硬件进行初始化,创建内核需要的一些信息并将这些信息通过相关机制传递给内核,从而将系统的软硬件环境带到一个合适的状 态,最终调用操作系统内核,真正起到引导和加载内核的作用。实际上
2、,一个功能比较强大的BootLoader已经相当于一个微型的操作系统了。 不同的CPU体系结构有不同的BootLoader。有些BootLoader支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体 系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行 在一块板子上的BootLoader程序也能运行在另一块板子上,通常需要修改BootLoader的源程序。因此每款嵌入式产品的BootLoader都是独一无二的,但我们可以总结出 开发或者
3、维护特定BootLoader需要哪些背景知识,掌握了这些背景知识,我们就可以做到以不变应万变。 为了引导操作系统,BootLoader与CPU体系结构和操作系统有着非常紧密的联系。在本书中,我们以ARM体系结构和嵌入式Linux操作系统为原型讲述BootLoader 的原理。通过理论联系实践的方法论,让读者理解BootLoader的概念,掌握开发BootLoader的方法。本书适合从单片机向ARM过渡并希望了解嵌入式开发的在校学生 以及想要从事BootLoader开发移植工作的工程师参考使用。 下面来梳理一下需要哪些背景知识: 1)因为我们引导的操作系统是Linux,所以需要熟悉Linux开发
4、环境。BootLoader也是一串代码,我们必须了解Linux下编辑器和编译器的用法;作为Linux下的开发 者,对shell脚本和Make工程管理工具也要有必要的了解。第1章对BootLoader做了基本介绍,第2章则详细介绍了Linux开发环境。 2)因为我们仅仅以ARM体系结构作为原型,所以会在第35章讲述ARM体系结构、ARM指令集和ARM独特的寻址模式。 3)很多嵌入式开发人员都是通信、电子和自动化等专业的,对于计算机的编译和链接掌握得不够深入,因此第6章介绍编译和链接。控制链接行为的链接脚本是 特有的脚本语言,第7章比较详细地介绍了该脚本的细节。 4)第8章采用流水灯的实验融会贯通
5、前面各章节的理论,接着第9章对U-Boot代码展开分析,最后在第10章一步一步地实现了BootLoader。在此过程中,我们更注 重ARM体系结构、编译链接等知识的融会贯通,不会花太多篇幅讲解DRAM、MMC等模块的驱动。 本书能够成书,要感谢LinkSprite团队的资源支持和左宝柱在pcDuino v3平台上的帮助。最后感谢家人和朋友对我的支持,鼓励我完成这项值得用心去做的工作。 因作者水平有限且时间仓促,书中难免存在疏漏,还望广大读者不吝赐教。 胡尔佳 2014年11月 第1章 BootLoader的概念 本章导读 本书讲述的主题是BootLoader,那么BootLoader是什么呢?
6、首先从字面上来看,BootLoader是一个英文单词,那它是什么意思呢?如果使用词典查询一下,会得到 这样的结果:“对不起,词库中没有您查询的单词!您要查找的是不是:Boot Loader Boot-Loader”Boot Loader计引导装载程序。 可以看到BootLoader应该是Boot和Loader这两个单词的组合。Boot的意思是“计算机科学引导”,而Loader是“加载器”的意思。因此可以推断 BootLoader这个词是随着计算机科学的发展而衍生出现的。 1.1节介绍BootLoader在嵌入式系统或者计算机系统中所扮演的角色。 1.2节结合半导体芯片技术、计算机技术以及软件工
7、程技术的发展历史来探究BootLoader的出现过程,从而说明BootLoader的来历和它在整个计算机系统中的 定位、概念以及作用。 1.3节阐述BootLoader的概念,并以MCU下的BootLoader、嵌入式ARM和Linux下的BootLoader和PC下的引导流程为例进行说明。 1.1 BootLoader的角色 当一个嵌入式开发板上电时,哪怕执行最简单的程序,都要初始化非常多的硬件。每种体系结构、处理器都有一组预定义的动作和配置,它们包含从单板的存储 设备获取初始化代码的功能。最初的初始化代码是BootLoader的一部分,它负责启动处理器和相关硬件设备。 在上电复位时,大多数
8、处理器都有一个获取第一条执行指令的默认地址。硬件设计人员利用该信息来进行存储空间的布局。这样一来,上电的时候可从一个通用 的已知地址获取代码,然后建立软件的控制。 BootLoader提供最初的初始化代码,并初始化单板,这样就可以执行其他的程序。最初的初始化代码都是由该处理器体系结构下的汇编语言写成。当然,在 BootLoader已经执行完基本的处理器和平台的初始化之后,它的主要工作就是引导完整的操作系统。它将定位、加载操作系统,并将控制权移交给操作系统。另 外,BootLoader可能含有一些高级特性,比如校验OS镜像、升级OS镜像、从多个OS镜像中选择性引导。与传统的PC-BIOS不同,当
9、操作系统获取控制权后,嵌入 式下的BootLoader就不复存在了。 1.2 BootLoader的来历 我们从4个角度来阐述BootLoader的来历,第一个是从半导体芯片技术(特别是处理器的发展)来看Boot的出现: 在集成电路只读存储器出现之前,早期的计算机ENIAC在存储中并没有程序,而是通过连接电缆的配置来解决问题。ENIAC中并没有自举电路或引导程序,因为 它只要上电,其硬件配置就开始解决问题。在早期的计算机中,根本就没有BootLoader的概念,连Boot这个名称都没有。 稍晚时间出现的IBM 701计算机(19521956年)有一个“Load”按键,按下它,可以从外部储存中加
10、载最初的36位的字到主存中。有一个加载选择开关来决 定外部储存是穿孔卡片、磁带,还是磁鼓(看到这里是不是觉得它和现代的嵌入式系统有些类似,在有些嵌入式电路板中,同样用一些拨码开关来控制电路板从SD 卡、Flash等多种存储设备中选择某一种存储设备进行启动)。接下来的18位半字作为一条指令执行,它通常会读取更多的字到主存中。这时开始执行Boot程序,它 将依次从外部存储媒质加载更大的程序到主存中。在1958年,“Boot”这个计算机名词便开始使用了。请读者注意,这里的“Load”按键和Loader是有本质区别 的:“Load”是通过外部操作来进行加载的,而Loader是软件实现的加载器,它可以自
11、行完成加载的动作。 Boot这个词的原意是靴子,那靴子怎么会与计算机系统中的引导发生关联呢?原来,这里的Boot是Bootstrap(鞋带)的缩写,它来自于一句谚语:“Pull oneself up by ones own bootstraps”,直译的意思是“拽着鞋带把自己拉起来”,这当然是不可能的事情。最早的时候,工程师用它来做比喻,比如自举电路 振荡器(Bootstrap Generator)就是指,不外加激励信号而自行产生恒稳和持续的振荡。对于早期计算机的启动,也存在这样一个问题:必须先运行程序,然后计 算机才能启动,但是计算机不启动就无法运行程序。于是,当时的人们想尽各种办法,他们把
12、一小段程序装进内存,之后计算机就能正常运行了。因此,工程师们将 这个过程称为“拉鞋带”,久而久之就简称为Boot了。而且随着处理器的发展,Boot处理的事务越来越多,比如对CPU运行模式的设置,比如对CPU内部时钟的配 置,还包括对Cache和MMU的配置。 第二个是从存储技术的发展来看Loader的出现: 首先介绍两类半导体存储器:ROM和RAM。ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写。ROM在系统停止供电的时候仍然 可以保持数据,而RAM通常在掉电之后就丢失数据,但是其存储单元的内容可按需随意取出或存入,且存取的速度与存储单元
13、的位置无关。 ROM分为ROM、PROM、EPROM和EEPROM等。只读存储器(ROM)是只能读取资料的内存。其资料内容在写入后就不能更改。此种内存的制造成本极低, 常用于电脑中的开机启动。可编程只读存储器(PROM)一般可编程一次。PROM存储器在出厂时各个存储单元皆为1,或皆为0,用户在使用时,再采用编程的方法 使PROM存储所需要的数据。可擦除可编程存储器(EPROM)可多次编程,这是一种便于用户根据需要来写入,并能把已写入的内容擦去后再改写,即为一种多次 改写的ROM。由于能够改写,因此能对写入的信息进行校正,修改错误后再重新写入。电子可擦除可编程只读存储器(EEPROM)的运作原理
14、类似于EPROM,但是 擦除的方式更加方便。 RAM按照存储单元的工作原理分为静态随机存储器(SRAM)和动态随机存储器(DRAM)。SRAM的存取速度要比DRAM快,同时价格也更高。在计算机中 SRAM常用来作为Cache,而DRAM常作为内存来使用。 闪存(Flash Memory)是一种高密度、非易失性的读/写半导体存储器。它既有EEPROM的特点,又有RAM的特点,是一种全新的存储结构。Nor Flash和 Nand Flash是市场上两种主要的闪存技术。Intel公司于1988年首先开发出Nor Flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,1989
15、 年,东芝公司发表了Nand Flash结构,强调降低每比特的成本,提供更高的性能,并且Nand Flash像磁盘一样可以通过接口轻松升级。Nor Flash和Nand Flash有 几个重要的区别:Nor Flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取内部的每一个字节,可以做到芯片内执行(XIP),应用程序可以直接在 Nor Flash内运行。Nand Flash使用复杂的I/O口来串行地存取数据,并且读写操作都是块操作,因此它无法做到XIP。Nor Flash的读取速度比Nand Flash稍快,但 是写入速度却要慢很多。Nand Flash的存储密度更高,成本更低。
16、因此,很多嵌入式单板都使用小容量的Nor Flash来运行启动代码,而使用Nand Flash存储其他 信息。 假如说当时已经有一种既可以运行程序,而且价格低廉、存储空间大的非易失性存储的设备,那么我们的所有程序都可以存放在此类存储设备中,这样就不存在 加载的问题了。然而实际上,一般的计算机系统都使用多级存储器层次结构,既有存储空间大、价格低廉、运行速度慢的非易失性存储设备(磁盘),也有空间小、 价格高、运行速度略快的非易失性存储设备(PROM等),还有价格高,运行速度非常快的易失性存储设备(RAM)。这样的层次结构会保证硬件最佳的性价比, 然而从软件上,我们必须引入Loader。它将自动完成
17、从非易失性存储设备向易失性存储设备加载程序的功能。 在现实的发展过程中,随着集成电路只读存储器时代的到来,由于集成电路技术的发展和ROM的出现(包括可掩码编程的ROM、可编程的ROM(PROM)、 可擦除可编程的ROM和Flash存储器),引导流程发生了极大的改变。它们使得固件引导程序开始安装到计算机中。 通常情况下,在上电和复位的条件下,每个微型处理器会执行下面两种可能的启动流程:开始执行从某一特定地址开始的代码;在特定地址处查询代码,然 后跳转到指定地址,开始执行代码。运用这种微处理器的系统使用ROM来保存这些特定的位置,如此,系统就不需要操作人员的干预就能开始运转。举个例 子,Intel
18、 x86处理器一直从位于FFFF:0000的指令处开始运行,而MOS 6502处理器,读取位于$FFFD(MS byte)和$FFFC(LS byte)的两个字节长度的向量地 址,然后跳转到该地址开始运行引导程序。 Apple的第一代计算机(1976年推出的Apple1)使用了PROM芯片而不再需要前面板的配置。因此当时Apple的宣传广告是“No More Switches,No More Lightshttp:/ firmware in PROMS enables you to enter,display and debug programs(all in hex)from the key
19、board”。 由于当时只读存储器的造价很高,Apple II系列采用多种存储器来构建存储器系统,以保证性能和价格的最优化。它使用一串小步骤来引导磁盘上的操作系统, 每一个小步骤都将控制权递交到愈加复杂的引导流程中。我们可以预见,每个步骤都必须能控制下一个步骤所用的存储器的读取操作,从而才能将其内容加载到特定 的位置以执行,这样就有了Loader(加载器)的概念。结合Boot和Loader的概念,BootLoader是既能“自举”又能“举人”的一段程序,由此,BootLoader在整 个计算机系统中可以说起着举足轻重的作用,任何一个计算机系统都需要一个稳定强大的BootLoader。 第三个是
20、从软件语言的发展(特别是C语言的出现)来看BootLoader的发展: 最早的计算机用于读取纸带的数据,上面记录着二进制格式的机器指令,计算机每读一条机器指令就执行一条机器指令。机器指令繁多,而且不适合人来阅读和 使用,所以后来出现了汇编语言,汇编语言实质上是机器语言的助记符。汇编语言中出现了函数的概念,那么在编写汇编代码时,就需要对栈进行小心的设计,并注 意保护好上下文现场。再往后,出现了C语言,C语言是一种更抽象的语言,它是针对于程序员的语言,隔离了许多底层上的概念,比方说隔离函数调用栈的设计。 并且C语言无法完成很多底层操作,因为只有汇编语言才能使用芯片架构上的一些特殊的指令。因此对于B
21、ootLoader来说,它是由汇编和C语言混合编码的,Boot中 的汇编代码完成只能用汇编指令完成的操作,并提供C语言的运行环境,还需要对栈指针和堆空间进行初始化和分配。C语言的出现无疑加快了BootLoader的设计和 开发,从而促进了BootLoader的发展。 第四个是从软件工程的角度来看BootLoader的发展: 最初的计算机软件统称为Firmware,而随着软件的复杂度提高,操作系统的出现,我们相应地将BootLoader独立出来,并作为专门的一个固件。BootLoader 和操作系统分开设计,使得各自的扩展性、跨平台、可移植性都大大提高。另外从软件工程的模块化设计、分层设计来讲,
22、像UBoot这样的BootLoader的设计越来 越像Linux了,其代码布局和Linux十分类似,使用了按照模块划分的结构,并且充分考虑了体系结构和跨平台问题。 1.3 BootLoader的概念 这一节我们全面地介绍BootLoader的基本概念。 简单地说,BootLoader就是在操作系统内核运行前执行的一段小程序。通过这段小程序,可以对硬件设备,如CPU、SDRAM、Flash、串口等进行初始化,也 可以下载文件到系统板、对Flash进行擦除和编程,真正起到加载和引导内核镜像的作用。但是随着嵌入式系统的发展,BootLoader已经逐渐在上述基本功能的基础 上进行了扩展,BootLo
23、ader可以增加更多的对具体系统的板级支持,即增加一些硬件模块功能上的使用支持,以方便开发人员进行开发和调试。 从这个层面上看,功能扩展后BootLoader可以虚拟地看成一个微小的系统级的代码包。BootLoader是依赖于硬件实现的,特别是在嵌入式系统中。不同的体系 结构下,对BootLoader的需求是不同的;除了体系结构,BootLoader还依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式电路板而言,即使 它们基于相同的CPU构建,运行在其中一块电路板上的BootLoader,都未必能够运行在另一块电路板上。 当现代的计算机关机时,它的软件,包括操作系统、应用程序和数
24、据,都会存放在非易失性存储设备上,比如硬盘、CD、DVD、Flash存储卡(SD卡)、USB 盘和软盘。当计算机上电时,在它的RAM中是没有操作系统和加载器的。计算机会首先执行存放在ROM中的相对较小的程序,读取小容量的必需数据,这样才能访 问非易失性存储设备中的操作系统和数据,并将其加载到RAM中。 这个过程中的小程序被称为“Bootstrap Loader”“Bootstrap”或“Boot Loader”。这段小程序的目的是加载其余的数据和程序到RAM中并开始执行。若使 用多阶段的Boot Loader,它们会一个接一个的加载。 有一些计算机系统,当从操作人员或者外设接到一个引导信号后,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 深入 理解 BootLoader html
链接地址:https://www.31doc.com/p-5518211.html