Bootloader的基本概念以及内部原理

发布者:SereneGardener最新更新时间:2012-10-10 来源: 21ic 关键字:Bootloader  基本概念  内部原理 手机看文章 扫描二维码
随时随地手机看文章

    u-boot是一种普遍用于嵌入式系统中的Bootloader。

    Bootloader介绍

    Bootloader是进行嵌入式开发必然会接触的一个概念,它是嵌入式学院<嵌入式工程师职业培训班>二期课程中嵌入式linux系统开发方面的重要内容。本篇文章主要讲解Bootloader的基本概念以及内部原理,这部分内容的掌握将对嵌入式linux系统开发的学习非常有帮助!

    Bootloader的定义:Bootloader是在操作系统运行之前执行的一小段程序,通过这一小段程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。意思就是说如果我们要想让一个操作系统在我们的板子上运转起来,我们就必须首先对我们的板子进行一些基本配置和初始化,然后才可以将操作系统引导进来运行。具体在Bootloader中完成了哪些操作我们会在后面分析到,这里我们先来回忆一下PC的体系结构:PC机中的引导加载程序是由BIOS和位于硬盘MBR中的OS Boot Loader(比如LILO和GRUB等)一起组成的,BIOS在完成硬件检测和资源分配后,将硬盘MBR中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。Boot Loader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,即开始启动操作系统。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注:有的嵌入式cpu也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由Boot Loader来完成。比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的Boot Loader程序。(先想一下,通用PC和嵌入式系统为何会在此处存在如此的差异呢?)

    Bootloader是基于特定硬件平台来实现的,因此几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader,Bootloader不但依赖于cpu的体系结构,还依赖于嵌入式系统板级设备的配置。对于2块不同的板子而言,即使他们使用的是相同的处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般也需要修改Bootloader的源程序。

    Bootloader的启动方式

    Bootloader的启动方式主要有网络启动方式、磁盘启动方式和Flash启动方式。

    1、网络启动方式

     

    图1 Bootloader网络启动方式示意图

    如图1所示,里面主机和目标板,他们中间通过网络来连接,首先目标板的DHCP/BIOS通过BOOTP服务来为Bootloader分配IP地址,配置网络参数,这样才能支持网络传输功能。我们使用的u-boot可以直接设置网络参数,因此这里就不用使用DHCP的方式动态分配IP了。接下来目标板的Bootloader通过TFTP服务将内核映像下载到目标板上,然后通过网络文件系统来建立主机与目标板之间的文件通信过程,之后的系统更新通常也是使用Boot Loader的这种工作模式。工作于这种模式下的Boot Loader通常都会向它的终端用户提供一个简单的命令行接口。

    2、磁盘启动方式

    这种方式主要是用在台式机和服务器上的,这些计算机都使用BIOS引导,并且使用磁盘作为存储介质,这里面两个重要的用来启动linux的有LILO和GRUB,这里就不再具体说明了。

    3、flash启动方式

    这是我们最常用的方式。Flash有NOR Flash和NAND Flash两种。NOR Flash可以支持随机访问,所以代码可以直接在Flash上执行,Bootloader一般是存储在Flash芯片上的。另外Flash上还存储着参数、内核映像和文件系统。这种启动方式与网络启动方式之间的不同之处就在于,在网络启动方式中,内核映像和文件系统首先是放在主机上的,然后经过网络传输下载进目标板的,而这种启动方式中内核映像和文件系统则直接是放在Flash中的,这两点在我们u-boot的使用过程中都用到了。

    U-boot的定义

    U-boot,全称Universal Boot Loader,是由DENX小组的开发的遵循GPL条款的开放源码项目,它的主要功能是完成硬件设备初始化、操作系统代码搬运,并提供一个控制台及一个指令集在操作系统运行前操控硬件设备。U-boot之所以这么通用,原因是他具有很多特点:开放源代码、支持多种嵌入式操作系统内核、支持多种处理器系列、较高的稳定性、高度灵活的功能设置、丰富的设备驱动源码以及较为丰富的开发调试文档与强大的网络技术支持。另外u-boot对操作系统和产品研发提供了灵活丰富的支持,主要表现在:可以引导压缩或非压缩系统内核,可以灵活设置/传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,支持多种文件系统,支持多种目标板环境参数存储介质,采用CRC32校验,可校验内核及镜像文件是否完好,提供多种控制台接口,使用户可以在不需要ICE的情况下通过串口/以太网/USB等接口下载数据并烧录到存储设备中去(这个功能在实际的产品中是很实用的,尤其是在软件现场升级的时候),以及提供丰富的设备驱动等。

    u-boot源代码的目录结构

    1、board中存放于开发板相关的配置文件,每一个开发板都以子文件夹的形式出现。

    2、Commom文件夹实现u-boot行下支持的命令,每一个命令对应一个文件。

    3、cpu中存放特定cpu架构相关的目录,每一款cpu架构都对应了一个子目录。

    4、Doc是文档目录,有u-boot非常完善的文档。

    5、Drivers中是u-boot支持的各种设备的驱动程序。

    6、Fs是支持的文件系统,其中最常用的是JFFS2文件系统。

    7、Include文件夹是u-boot使用的头文件,还有各种硬件平台支持的汇编文件,系统配置文件和文件系统支持的文件。

    8、Net是与网络协议相关的代码,bootp协议、TFTP协议、NFS文件系统得实现。

    9、Tooles是生成U-boot的工具。

    对u-boot的目录有了一些了解后,分析启动代码的过程就方便多了,其中比较重要的目录就是/board、/cpu、/drivers和/include目录,如果想实现u-boot在一个平台上的移植,就要对这些目录进行深入的分析。

    u-boot的启动过程[page]

    系统启动的入口点。既然我们现在要分析u-boot的启动过程,就必须先找到u-boot最先实现的是哪些代码,最先完成的是哪些任务。另一方面一个可执行的image必须有一个入口点,并且只能有一个全局入口点,所以要通知编译器这个入口在哪里。由此我们可以找到程序的入口点是在/board/lpc2210/u-boot.lds中指定的,其中ENTRY(_STart)说明程序从_start开始运行,而他指向的是cpu/arm7tdmi/start.o文件。因为我们用的是ARM7TDMI的cpu架构,在复位后从地址0x00000000取它的第一条指令,所以我们将Flash映射到这个地址上,这样在系统加电后,cpu将首先执行u-boot程序。

    u-boot的启动过程是多阶段实现的,分了两个阶段。依赖于cpu体系结构的代码(如设备初始化代码等)通常都放在stage1中,而且通常都是用汇编语言来实现,以达到短小精悍的目的。而stage2则通常是用C语言来实现的,这样可以实现复杂的功能,而且代码具有更好的可读性和可移植性。

    下面我们先详细分析下stage1中的代码,如图2所示:

    图2 Start.s程序流程

    代码真正开始是在_start,设置异常向量表,这样在cpu发生异常时就跳转到/cpu/arm7tdmi/interrupts中去执行相应得中断代码。在interrupts文件中大部分的异常代码都没有实现具体的功能,只是打印一些异常消息,其中关键的是reset中断代码,跳到reset入口地址。

    reset复位入口之前有一些段的声明。在reset中,首先是将cpu设置为svc32模式下,并屏蔽所有IRQ和fiq。在u-boot中除了定时器使用了中断外,其他的基本上都不需要使用中断,比如串口通信和网络等通信等,在u-boot中只要完成一些简单的通信就可以了,所以在这里屏蔽掉了所有的中断响应。

    初始化外部总线。这部分首先设置了I/O口功能,包括串口、网络接口等的设置,其他I/O口都设置为GPIO。然后设置BCFG0~BCFG3,即外部总线控制器。这里bank0对应Flash,设置为16位宽度,总线速度设为最慢,以实现稳定的操作;Bank1对应DRAM,设置和Flash相同;Bank2对应RTL8019。

    接下来是cpu关键设置,包括系统重映射(告诉处理器在系统发生中断的时候到外部存储器中去读取中断向量表)和系统频率。

    lowlevel_init,设定RAM的时序,并将中断控制器清零。这些部分和特定的平台有关,但大致的流程都是一样的。

    下面就是代码的搬移阶段了。为了获得更快的执行速度,通常把stage2加载到RAM空间中来执行,因此必须为加载Boot Loader的stage2准备好一段可用的RAM空间范围。空间大小最好是memory page大小(通常是4KB)的倍数,一般而言,1M的RAM空间已经足够了。flash中存储的u-boot可执行文件中,代码段、数据段以及BSS段都是首尾相连存储的,所以在计算搬移大小的时候就是利用了用BSS段的首地址减去代码的首地址,这样算出来的就是实际使用的空间。程序用一个循环将代码搬移到0x81180000,即RAM底端1M空间用来存储代码。然后程序继续将中断向量表搬到RAM的顶端。由于stage2通常是C语言执行代码,所以还要建立堆栈去。在堆栈区之前还要将malLOC分配的空间以及全局数据所需的空间空下来,他们的大小是由宏定义给出的,可以在相应位置修改。基本内存分布图:

    图3 搬移后内存分布情况图

    接下来是u-boot启动的第二个阶段,是用c代码写的,这部分是一些相对变化不大的部分,我们针对不同的板子改变它调用的一些初始化函数,并且通过设置一些宏定义来改变初始化的流程,所以这些代码在移植的过程中并不需要修改,也是错误相对较少出现的文件。在文件的开始先是定义了一个函数指针数组,通过这个数组,程序通过一个循环来按顺序进行常规的初始化,并在其后通过一些宏定义来初始化一些特定的设备。在最后程序进入一个循环,main_loop。这个循环接收用户输入的命令,以设置参数或者进行启动引导。

    本篇文章将分析重点放在了前面的start.s上,是因为这部分无论在移植还是在调试过程中都是最容易出问题的地方,要解决问题就需要程序员对代码进行修改,所以在这里简单介绍了一下start.s的基本流程,希望能对大家有所帮助。

关键字:Bootloader  基本概念  内部原理 引用地址:Bootloader的基本概念以及内部原理

上一篇:基于FPGA的通信接口模块的设计
下一篇:利用DSP/BIOS操作系统进行快速开发设计的软件架构设计

推荐阅读最新更新时间:2024-03-16 13:10

剖析:从中外对比看混合动力车型技术基本概念
近年来,新能源车型备受国家推崇,这其中,纯电动车型占据了大半壁江山。在国人印象当中,购买新能源车型目的之一便是省油。纯电动车型因为不依赖燃油行驶,从而可以达到“绝对省油”。其自身结构又相对来说较为简单,所以国家层面也大力发展纯电动车型,随之而来的便是大额资金补贴。说了这么多,我们只是为混合动力车型稍稍鸣不平。要知道,同样作为全球新能源车型的重要一环,国内外混合动力的发展现状差别还是蛮大的。   在此之前,我想先给大家梳理下混合动力技术的基本概念。笔者觉得第一个要说明的便是混合动力的组成形式。分为油电混动和插电混动两个大类。   第一代丰田普锐斯 油电混动即燃料和电能的混合。其电能来源相对来说最为高效。
[嵌入式]
S12(X)微控制器的Bootloader程序
实测在MC9S12XEP100上可以使用,但是对我来说需要修改了一个小地方: 可能是由于这个程序的版本太老,PARTID没有考虑到我手头上这个XEP100的PARTID(0xCC95),这个PARTID甚至在芯片手册中都没有提到,不过问题也不大,测试后发现只要和0xCC94一样的处理方法即可了。想知道自己设备的PARTID是多少可以直接去看地址在1A-1B的这两个字节的值是多少。 修改方式为: 首先在PARTID.h中添加一个宏 …… //S12XE: #define MASK_0M48H 0xCC90 //1024k flash #define MASK_1M48H 0xCC91 #define MASK_2M48H
[单片机]
S12(X)微控制器的<font color='red'>Bootloader</font>程序
写一个自己的bootloader(一)汇编系列
此bootloader是根据韦东山先生的开发板而制定的 是一个最小的boot系统 必须首先把内核拷nandflash里面才行。 我们先一步步的完成这个小的bootloader 1. 首先我们需要关闭看门狗: ldr r0, 0x53000000 //this is the address of watch mov r1, #0; str r1, //disable watch dog 看门狗的地址在0x53000000 我们给他赋值0 即可 设置时钟: 时钟的比例是 FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1 所以应该是: MDIV 0x5C PDIV 0x
[单片机]
写一个自己的<font color='red'>bootloader</font>(一)汇编系列
矢量信号发生器的基本概念及使用
矢量信号发生器是一种能提供各种频率、波形和输出电平电信号的设备。在测量各种电信系统或电信设备的振幅特性、频率特性、传输特性及其它电参数时,以及测量元器件的特性与参数时,用作测试的信号源或激励源。矢量信号发生器基本应用是在通信测试领域作为简单的数字调制信号发生设备进行整机测试以及整部件级的测试。 矢量信号发生器的基本概念及使用 矢量信号发生器基本概念 在通信领域,由于通信业务的增长每一天都有更多的用户需要占用新的频谱,而可用的频谱资源是有限的,因此必须尽可能提高系统单位带宽传输的信息量。数字调制与模拟调制技术相比,可带来更大的信息容量、更好的兼容性、更高的数据保密性、更好的通信质量。因此,近年来数字调制技术在通信领域得到大量应
[测试测量]
矢量信号发生器的<font color='red'>基本概念</font>及使用
使用USBASP给Arduino烧写bootloader教程
arduino板由于操作不发导致固件损坏,或者想更新固件怎么办?今天给大家介绍一下如何使用UsbAsp烧写bootloader.个人认为,此种方法比使用TinyIsp要方便并且成本更低。 首先确保手上有一个USBASP下载器,某宝上一搜一大堆,下面以TSROBOT的兼容型UNO板,分别介绍mega16u2的固件和mega328p的固件烧写。______________________________________________________________________ 下载器的驱动安装: 将USBasp 插入电脑usb 接口后,系统提示找到硬件,按下列图示安装。 ignore_js_op 选择“从列表或指定位置安装
[单片机]
使用USBASP给Arduino烧写<font color='red'>bootloader</font>教程
BootLoader与Linux内核的参数传递
  在嵌入式系统中,BootLoader 是用来初始化硬件,加载内核,传递参数。因为嵌入式系统的硬件环境各不相同,所以嵌入式系统的BootLoader 也各不相同,其中比较通用的是U-Boot,它支持不同的体系结构,如ARM,PowerPC,X86,MIPS 等。本文着重介BootLoader与内核之间参数传递这一基本功能。本文的硬件平台是基于AT91RM9200 处理器系统,软件平台是Linux-2.6.19.2 内核。内核映像文件为zImage。   1. 系统硬件平台简介   AT91RM9200 处理器,它是由Atmel 公司基于ARM920T 内核的微处理器,带有内存管理单元,CPU 时钟最高可达240MHz,它具有丰
[单片机]
ARM-Linux嵌入式系统的BootLoader分析与设计
0 引言 由Boot Loader和固化在固件(firmware)中的Boot代码(可选)共同组成一个嵌入式系统的引导加载程序。它的作用和功能就像固化到计算机内主板上的一个ROM芯片程序BIOS(basic input output system)。但是它一般不配置像BIOS那样的固件程序,这是因为要考虑经济方面的原因,因此必须自己完成这方面的工作。Boot Loader可以初始化硬件设备,建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。它的实现严重地依赖于硬件,特别是在嵌入式系统中,即使基于同一个CPU的Boot Loader,对于不同的板子,也有很大的不同。 1
[工业控制]
ARM-Linux嵌入式系统的<font color='red'>BootLoader</font>分析与设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved