`
cjc
  • 浏览: 680992 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

u-boot启动过程分析——基于lpc2210的移植代码

阅读更多
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

作者:华清远见嵌入式培训中心讲师。

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、网络启动方式

按此在新窗口浏览图片
图1Bootloader网络启动方式示意图

如图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的启动过程

系统启动的入口点。既然我们现在要分析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所示:

按此在新窗口浏览图片
图2Start.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的基本流程,希望能对大家有所帮助。

分享到:
评论

相关推荐

    u-boot启动过程分析——基于lpc2210的移植

    u-boot启动过程分析——基于lpc2210的移植.mht

    嵌入式系统/ARM技术中的u-boot启动过程分析——基于lpc2210的移植代码

    在基于LPC2210的嵌入式系统中,u-boot的移植和理解对于开发者来说至关重要。 Bootloader的基本概念在于它是在操作系统运行前执行的初始化程序,其主要任务包括硬件设备的初始化、内存管理的设定以及创建系统运行所...

    U-Boot在LPC2210上的移植分析

    本文将深入探讨U-Boot在LPC2210处理器上的移植过程和主要特点。 LPC2210是由PHILIP公司生产的微控制器,基于ARM7TDMI架构,常用于嵌入式设计。由于U-Boot原生并不直接支持LPC2210,因此需要对其进行特定的移植工作...

    U-boot在LPC2210处理器上的移植.pdf

    【标题】:U-boot在LPC2210处理器上的移植 【描述】:本文详细介绍了如何将U-boot引导加载程序移植到飞利浦LPC2210处理器,包括移植的关键点、难点以及编译方法。 【标签】:处理器, 微型机器, 数据处理, 参考文献, ...

    ARM Cortex-M3嵌入式开发实例详解——基于NXP LPC17XX[张燕妮][程序源代码]

    《ARM Cortex-M3嵌入式开发实例详解——基于NXP LPC17XX》是一本深入讲解基于ARM Cortex-M3架构微控制器NXP LPC17XX的实战书籍,由张燕妮编写并提供了丰富的程序源代码。这本书旨在帮助读者掌握如何在实际项目中应用...

    u-boot移植到 LPC2210 上的串口打印问题解决

    ### U-Boot 移植到 LPC2210 上的串口打印问题解决方案 #### 一、背景介绍 U-Boot(Universal Boot Loader)是一种开放源码的引导加载程序,适用于多种嵌入式处理器和系统架构。它为硬件提供了一个灵活且强大的启动...

    u-boot-lpc2294.rar_lpc2294_lpc2294 can_nxp boot

    5. **引导过程**:应用补丁后,用户需要编译u-boot,生成适合LPC2294的二进制镜像,然后将其烧录到微控制器的闪存中,以实现自启动。 6. **开发资源**:NXP官网提供的"uboot get started"指南是开发者的重要参考资料...

    U-boot quick start guide

    由于 U-boot 支持包括 ARM7 在内的多种 CPU 架构,而 LPC2294 正是一款基于 ARM7 的处理器,因此在 LPC2294 上部署 U-boot 作为引导加载程序不仅可行,而且非常有用。U-boot 可以帮助开发者更高效地开发和调试基于 ...

    lpc3250.u-boot.zip

    U-Boot是嵌入式系统中广泛使用的开放源代码引导加载程序,它为各种硬件平台提供启动服务,包括加载操作系统内核、初始化硬件设备以及提供基本的用户交互界面。 【描述】提到这个压缩包"可以直接使用",意味着它已经...

    基于LPC2210的嵌入式Linux开发平台构建.pdf

    总结来说,基于LPC2210的嵌入式Linux开发平台构建是一个综合了处理器选择、操作系统移植、驱动开发和应用程序设计的过程。这样的平台对于提高嵌入式系统的性能和扩展性具有重要意义,尤其在需要网络功能和复杂数据...

    u-boot-1.3.3-icu-20111109.tar.gz

    《U-Boot 1.3.3 ICU 20111109:嵌入式系统的启动专家》 在嵌入式系统的世界里,U-Boot(Universal Boot Loader)是一个至关重要的组件,它扮演着引导加载器的角色,负责初始化硬件、加载操作系统内核以及提供与用户...

    u-boot-2009.03_lpc32x0-v1.07.patch.tar.bz2

    基于phy3250(或相似的)开发板的uboot-2009.03补丁文件。 有了这个文件即可完成phy3250开发板中uboot的移植工作了。当然,还需要确认自己的开发板与phy3250开发板是否相同等工作要做。 交叉编译工具链建议选用arm-...

    LPC3250 u-boot 串口下载脚本

    利用stage1 loader,通过串口下载u-boot到LPC3250。

    u-boot-lpc2294.patch

    在lpc2294上运行u-boot 的补丁,使用方法见Getting started uboot.pdf

    基于LPC2210定时器源代码

    【基于LPC2210定时器源代码】 在嵌入式系统开发中,定时器是一种重要的硬件资源,用于执行周期性任务、实现延时、中断服务等。LPC2210是一款基于ARM7TDMI-S内核的微控制器,由NXP(原飞利浦半导体)制造。该芯片...

    基于LPC2210的嵌入式系统设计

    基于LPC2210的嵌入式系统设计基于LPC2210的嵌入式系统设计

    Micrium-Book-uCOS-III-NXP-LPC1768

    Micrium-Book-uCOS-III-NXP-LPC1768

    EasyARM-C.rar_Easyarm_LPC2210_串口 工具_串口工具_串口调试工具

    《EasyARM-C.rar:LPC2210串口调试...总之,EasyARM-C.rar提供的LPC2210串口调试工具是开发和调试基于LPC2210的串口应用时不可或缺的助手,它简化了串口通信的调试过程,让复杂的嵌入式系统开发变得更加简单和高效。

    [原创]uCOS-II到SkyEye_LPC2210的移植

    本文档旨在记录嵌入式系统分析与设计课程的大作业成果——将uCOS-II操作系统移植到SkyEye模拟器下的LPC2210平台上,并实现串口中间件功能。这一项目不仅涉及到了uCOS-II操作系统的移植,还包括了对嵌入式平台SkyEye...

Global site tag (gtag.js) - Google Analytics