(三)U-Boot在AT91RM9200上的移植及启动分析

 1.引 言

U-Boot(Universal Boot Loader)是遵循GPL条款的开放源码项目,他支持多种体系结构的上百种开发板,并且支持多种嵌入式操作系统内核,具有较高的可靠性和稳定性,已经成为功能最多、灵活性最强并且开发最积极的开放源码BootLoader。作为通用的BootLoader,U-Boot可以方便地移植到其他硬件平台上。

本文基于AT91RM9200的嵌入式目标板和U-Boot1.1.2源码资源,分析了U-Boot的启动过程,介绍了U-Boot的移植方法和具体操作,最后讲述如何引导内核启动。

2. U-Boot启动分析

在具体移植之前,先来了解一下U-Boot启动过程。U-Boot启动过程可以分成3个阶段。

(1)在FLASH中运行汇编程序,进行基本硬件初始化,并将FLASH中的启动代码复制到SDRAM中,同时创造环境准备运行C程序。

汇编程序start.s是U-Boot启动后执行的第一个程序,他位于CPU/AT91RM9200中,链接脚本Board/AT91RM920DK/U-Boot.1ds决定U-Boot的入口函数位于该程序中,上电后,处理器首先执行该程序,具体工作流程如图1所示。

(2)跳转到SDRAM中执行,对硬件进行初始化,并向显示终端输出启动信息。

start_armboot是U-Boot执行的第一个C语言函数,他位于lib_arm/board.c中,主要完成系统初始化工作,进入主循环,处理用户输入的命令。具体工作流程如图2所示。

全局变量结构体gd用来保存开发板信息、终端存在标志位、环境变量结构体起始地址、环境变量校验标志位、frame buffer基地址等。他是指向gd_t结构体的指针,gd_t结构体定义在include\asm-asm\global_data.h中。

硬件初始化中执行函数及各函数作用如下:

board_init:基本的板级相关配置,主要包括:设置处理器类型和启动参数地址;
interrupt_init:中断处理初始化,主要对TC控制器作设置。
env_init:设置环境变量,初始化环境;
init_baudrate:指定串口的波特率;
setial_init:串口初始化设置;选择通讯端口,设置串口波特率和工作方式;
console_init_f:设置gd->have_console=1,表示可以使用串口通讯控制台;
display_banner:在控制台输出U-Boot信息;
dram_init:设置SDRAM的起始地址和大小;
display_dram_config:在控制台输出SDRAM信息;
FLASH_init:设置FLASH芯片ID号、每个扇区起始地址等信息,将信息送到相应的结构体中;对FLASH中U-Boot和环境变量存储扇区做软件写保护;
display_FLASH_config(size):在上位机终端输出FLASH大小。

(3)将内核映像和根文件系统映像从FLASH拷贝到SDRAM中,为内核设置启动参数,进入内核的入口函数。

 U-Boot作为BootLoader,具备多种引导内核启动的方式,常用bootm命令引导内核映像启动

使用bootm命令时,需要首先使用U-Boot自带的mkimage命令,将内核映像文件转换成U-Boot格式映像。即在内核的前头加上64 B的信息帧头,供建立tag之用。

bootm命令调用do_bootm函数,这个函数专门用来引导各种操作系统映像,可以支持引导Linux,vxWorks,QNX等操作系统。

具体完成的工作有:保存内核引导地址;分析内核帧头;复制内核映像到SDRAM中;调用dobootm_linux()函数。

do_bootm_linux()函数是专门引导Linux映像的函数,他还可以处理ramdisk文件系统的映像。具体完成的工作有:

(1)检查是否有根文件系统映像文件,这里只用bootm命令引导内核映像;
(2)将要传递给Linux的参数存放到标记列表中,内核将会从此处接收参数,完成参数传递;
(3)调用Linux内核,系统采用下列代码来进入内核函数:

第一行代码将theKernel函数指向内核首地址处;

第二行代码调用theKernel()函数,并通过r0,r1,r2将机器编号和参数链表物理地址传递给内核。

3.嵌入式目标板介绍

本目标板以AT91RM9200作为微处理器,板上存储系统包括NOR FLASH,NAND FLASH,SDRAM等;外围支持设备有JTAG、串口、USB接口、网络接口、SD Card接口及显示接口等。目标板硬件架构如图3所示,主要硬件资源如表1所示。

4. U-Boot源码修改与编译

根据目标板的配置,主要考虑修改以下U-Boot源码文件:

(1)include/configs/AT91RM9200dk.h:该头文件包含了SDRAM的一些设置和定义,主要修改内容包括:定义CONFIG_BOOTBINFUNC宏变量;修改SDRAM大小;修改FLASH大小和扇区数。

(2)board/AT91RM9200dk/FLASH.c:该程序完成的功能包括FLASH初始化、打印FLASH信息、FLAH擦除和FLASH写入等操作。可在参考已有FLASH驱动的基础上,结合目标板FLASH数据手册,进行适当修改。

(3)include/FLASH.h:FLASH程序头文件,结合目标板修改FLASH型号和ID定义。

U-Boot的源码通过GCC和Makefile组织编译。顶层目录下的Makefile设置开发板的定义,递归地调用各级子目录下的Makefile,把编译过的程序链接成U-Boot映像。

这里上位机操作系统采用Redhat 9.0,交叉工具链采用cross-2.95.3。GCC安装路径为/usr/loacal/arm/2.95.3,在环境变量PATH中添加相应路径,就可以直接使用arm-linux-gcc命令。

编译U-Boot分两步:第一步配置,执行命令:makeat91rm9200dk_config;第二步编译,执行命令:make。编译完成,生成3个映像文件system.map,U-Boot,U-Boot.bin,和1个符号表system.map,一般U-Boot.bin最为常用,直接按照二进制格式下载。 使用FLASH烧写程序将U-Boot.bin烧进NORFLASH中,目标板重新上电复位后,U-Boot启动成功,在超级终端会显示如下启动信息:


出现Warning的原因是还未设置环境变量,设置环境变量后执行saveenv命令即可去掉Warning。

5.引导内核

U-Boot的最终目的是引导内核启动。上述仅仅启动了U-Boot,要引导内核启动还需要设置环境变量、下载内核和根文件系统映像、执行引导内核启动命令。假设内核映像文件为zImage,根文件系统映像文件为myram-disk.gz(生成方法略)。具体方法如下:

(1)启动目标机,在U-Boot中进行网络参数等环境变量设置:


这里网络环境变量设置的目的是为了能够使用TFTP协议;bootargs用来定义传递给Linux内核的命令行参数;Bootcmd定义自动启动时执行的命令;bootm10100000表示从0x10100000处引导内核程序。

(2)给内核映像加帧头

在上位机Linux环境下,将U-Boot\tools\mkimage.exe COPY到\bin目录下,输入如下命令:

这里zImage为原始内核映像文件名;zImage.img为生成的加过帧头的内核映像名。

(3)加载内核和根文件系统映像到FLASH中

加载zImage.img到0x10100000,加载myramdisk.gz到0x10300000。

至此,我们将UBOOT、内核、根文件系统都下载到FLASH中了,并且设置了环境变量。重启目标板,等待延时时间结束自动进入本地装载模式,即可引导内核启动。

上面讲述的是将内核和根文件系统固化到FLASH中的情况,即使用本地加载模式,当以嵌入式产品发布时,BootLoader必须工作在这种模式下。但实际在初期调试的时候,可以在下载操作模式下直接用TFTP命令将这些映像文件下载到SDRAM中,然后用bootm命令从SDRAM中引导。此时在给内核映像加帧头的时候要注意,bootm XXXX指定的地址XXXX是否与mkImage命令处的-a指定的加载地址相同。如果不同,mkImage命令的写法和上面介绍的一致;如果相同,在使用mkImage命令时,-e参数后的入口地址要比-a参数后的存储地址推后64 B。

6.结 语

U-Boot是一个功能强大的BootLoader开源软件,他支持上百种开发板和多种嵌入式操作系统,可方便地移植到各种硬件平台上。目前,笔者移植的U-Boot已成功运行在目标板上,并在此基础上成功地加载了Linux内核和根文件系统,为后续的驱动和应用开发奠定了基础。对于不同的CPU和开发板,U-Boot的启动原理和移植步骤大致相同。希望本文能对学习U-Boot的朋友有所帮助。


原文地址:http://blog.csdn.net/hare_lee/article/details/6944441

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值