u-boot之基础知识

一、简介

u-boot是操作操作系统运行前的引导加载程序,它的作用是初始化硬件设备、建立内存空间的映射表,为最后调用操作系统内核做好准备。

主要任务是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点运行,即开始启动操作系统。

 

BootLoader的操作模式一般分为自启动模式和交互模式。

自启动模式:BootLoaderd从目标机上的某个固态设备(FLASH)上将操作系统加载到RAM中运行,整个过程没有用户的介入;

下载模式:目标机上的BootLoader将通过串口或网络等通信手段将内核映像和根文件系统映从PC机下载到到目标机中,或者直接进行系统的引导。也可以通过串口接收用户的命令。

 

二、u-boot启动流程

目前大多数 BootLoader 都分为stage1 和stage2 两大部分。依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在 stage1中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而stage2 则通常用C 语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。

1、stage1(汇编代码部分)

(1)系统复位转入U-BOOT的stage1入口点

2)设置异常向量             (本阶段硬件设备初始化)

3)设置CPU的速度、时钟、频率及终端控制寄存

4)初始化内存寄存器

(5)拷贝U-BOOT的stage2到RAM空间

(6)设堆栈、初始化数据段

2、stage2(c语言代码部分)

(1)跳转到stage2的C入口点

2)初始化FLASH设备          (本阶段硬件设备初始化)

3)初始化系统内存

4)初始化NAND、显存、网络等设备

(5)将kernel和根文件系统映射从flash读到RAM空间中

(6)设置内核启动参数和调用内核

三、u-boot目录结构

从u-boot-2010.06版本开始把体系结构相关的内容合并,原先的cpu与lib_arch内容全部纳入arch中,并且其中增加inlcude文件夹;分离出通用库文件lib。

 

├── api             存放uboot提供的接口函数

├── arch            与体系结构相关的代码,uboot的重头戏

├── board           根据开发板定制的代码,主要包含SDRAMFLASH驱动

├── common        通用的代码,涵盖各个方面,已命令行处理为主

├── disk            磁盘分区相关代码

├── doc            文档,一堆README开头的文件

├── drivers          驱动,很丰富,每种类型的设备驱动占用一个子目录

├── examples        示例程序

├── fs             文件系统,支持嵌入式开发板常见的文件系统

├── include          头文件,已通用的头文件为主

├── lib              通用库文件

├── nand_spl         NAND存储器相关代码

├── net             网络相关代码,小型的协议栈

├── onenand_ipl           一个小loader

├── post            加电自检程序

└── tools           辅助程序,用于编译和检查uboot目标文件

 

目录详细图

 

四、u-boot.lds链接顺序

以u-boot-2010.6举例,u-boot的链接脚本\arch\arm\cpu\arm926ejs\u-boot.lds,它定义了目标程序各部分的链接顺序。

 

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")

/*指定输出可执行文件是elf格式,32ARM指令,小端*/

OUTPUT_ARCH(arm)

/*指定输出可执行文件的平台为ARM*/

ENTRY(_start)

/*指定输出可执行文件的起始代码段为_stext*/

SECTIONS

{

/*指定可执行文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。必须使编译器知道这个地址,通常都是修改此处来完成*/

    .= 0x00000000;

    .= ALIGN(4);    /*代码以4字节对齐*/

    .text:

    {

           arch/arm/cpu/arm920t/start.o (.text)

           *(.text)

    }

    .= ALIGN(4);

    .rodata: { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

/*代码段结束后,有可能4bytes不对齐了,此时做好4bytes对齐,以开始后面的.rodata*/

    .= ALIGN(4);

    .data: { *(.data) }   /*和前面一样,4bytes对齐,以开始接下来的.data*/

    .= ALIGN(4);

    .got: { *(.got) }

    .= .;

//__u_boot_cmd_start赋值为当前位置, 即起始位置*/

    __u_boot_cmd_start= .;    //指定u_boot_cmd, uboot把所有的uboot命令放在该段.*/

    .u_boot_cmd: { *(.u_boot_cmd) }

    __u_boot_cmd_end= .; //__u_boot_cmd_end赋值为当前位置,即结束位置*/

    .= ALIGN(4);

    __bss_start= .;    //__bss_start赋值为当前位置,bss段的开始位置*/

    .bss(NOLOAD) : { *(.bss) . = ALIGN(4); } //指定bss*/

    _end= .;        //_end赋值为当前位置,bss段的结束位置*/

}

 

第一个链接的是arch/arm/cpu/arm926ejs/start.o,也就是u-boot的入口指令在start中,且以复位向量开头:

 

五、start.s与board.c分析

start.s主要作用是初始化运行环境;初始化内存;重新放置u-boot代码到内存中;跳入到内存中执行第二段初始化代码。

1、        关闭开门狗,屏蔽所有中断

2、        设置分频比

3、        bl     cpu_init_crit()     关MMU,初始化内存

bl    lowlevel_init()      配置内存,修改内存刷新率参数等

4、        relocate                  判断当前代码是在NORFLASH还是RAM

copy_loop               将FLASH代码复制至RAM中

5、        stack_setup               栈设置

clear_bss _bss_start到_bss_end之间的数据清0

6、        ldr    pc , start_armboot  跳转到第二阶段

 

board.c主要作用是初始化两个重要数据结构,对SDRAM的内存分配设置,对各种需要用到的外设进行初始化,最后循环跳入main_loop()函数,首先执行start_armboot分为board_init_f和board_init_r。

(1)执行的board_init_f部分:

1、为gd数据结构分配地址,并清零

2、执行init_fnc_ptr函数指针数组中的各个初始化函数,如下

board_early_init_f     

timer_init      

env_init      

init_baudrateserial_init    

console_init_f      

display_banner          

dram_init

3、A、 分配SDRAM高64KB为TLB,用于U-BOOT

B、分配SDRAM下一单元为U-BOOT代码段,数据段,BSS段

(BSS段是用来存放未初始化的全局变量与静态变量)

C、接着开辟malloc空间,存bd, gd , 3个字大小的异常堆空间

4、将relorate的地址值赋给gd结构体相应变量

(2)执行的board_init_r部分

1、对gd , bd数据结构赋值初始化

2、各种外设初始化:

初始化NORFLASH,NANDFLASH,           

初始化ONENANDFLASH

初始化环境变量    

初始化PCI   

设置IP地址 初始化各类外设:IIC、LCD、键盘、USB        

初始化控制台             

建立IRQ中断堆栈   

初始化以太网

初始化跳转表(定义了u-boot中基本的常用函数库)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值