Linux之u-boot启动流程

本文介绍了Linux系统中u-boot引导加载器的作用和优点,详细阐述了bootloader的启动方式,包括自启动模式和交互模式。同时,文章解析了u-boot的启动过程,分为两个阶段,分别介绍了每个阶段的主要功能,如硬件初始化、内存映射检测、内核加载等。最后,文章提到了u-boot启动顺序的Stage1和Stage2,并提供了参考资料链接。
  • Bootloader介绍

(一)为什么需要bootloader

       由于Linux内核不支持自启,因此我们需要一个引导程序来引导Linux内核启动,并且做一些前期准备,这个引导程序就是bootloader,但是由于每种开发板资源不同,而且cpu架构之间也有差别,因此一款bootloader程序不可能适用于所有的环境。但是经过大师们的努力,经过简单的配置改动,就能够实现引导很多操作系统,这款引导代码就是U-Boot。

       U-Boot的优点:

  1. 源码开放;
  2. 支持多种嵌入式系统操作内核(Linux、vxworks);
  3. 支持多种处理器系列(arm,x86);
  4. 灵活性和可靠性较高;
  5. 高度灵活的功能设置,适合U-Boot调试、产品发布等;
  6. 拥有丰富的设备驱动源码;
  7. 较为丰富的开发调试文档以及强大的技术支持。

(二)bootloader的启动方式

       CPU在上电或者复位时,会从某个地址开始执行。ARM结构的CPU从0x0000000开始,通常这个开始地址处就存放了BL1+bootloader这样一上电就可以执行的代码(bootloader相当于BL2)。

       从开发和用户使用角度看,bootloader分为以下两种操作模式。

       自启动模式(Boot loading):

       在这种模式中,bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程不需要用户介入,在产品发布以后,基本采用这种工作模式。

       交互模式(Downloading):

       在这种模式下,开发人员可以使用各种命令通过串口或者网络从主机下载文件到RAM中,可以被bootloader写到目标机的固态存储介质中,或者直接进入系统的引导。

(三)常用bootloader

       由于各个开发板的差异以及CPU的不同,导致bootloader的种类也非常多,以下列出了Linux的开发源码的bootloader及其支持的结构:

开放源码的linux引导程序

Bootloader

Monitor

描述

X86

ARM

PowerPC

LILO

linux磁盘引导程序

GRUB

GNU的LILO替代程序

Loadlin

从DOS引导linux

ROLO

从ROM引导linux而不需要BIOS

Etherboot

通过以太网卡启动linux系统的固件

LinuxBIOS

完全替代BUIS的linux引导程序

BLOB

LART等硬件平台的引导程序

U-Boot

通用引导程序

RedBoot

基于eCos的引导程序

Vivi

Mizi公司针对SAMSUNG的ARM CPU设计的引导程序

 

  • bootloader启动的两个阶段

U-Boot运行过程

  1. 程序启动过程

(1)u-boot上电后执行的第一个文件是arch/arm/cpu/armv7/start.S,start.S文件准备好第二阶段运行环境。

(2)start.S执行完毕时会调用到arch/arm/lib/board.c中的board_init_r函数,这个函数会对flash、net、串口等进行初始化,并且最终进入死循环,如下:

for (;;) {              main_loop ();  //进入等待命令解析状态,直到启动内核后,u-boot就退出了。}
  1. boot loader的两个阶段

Bootloader的启动过程可以分为单阶段(single Stage)、多阶段(Multi-stage)两种。通常多阶段的Bootloader能提供更为复杂的功能以及更好的可移植性。从固态存储设备上启动的Bootloader大多都是两阶段的启动过程。第一阶段使用汇编来实现,它完成一些依赖于CPU体系结构的初始化,并调用第二阶段的代码;第二阶段则通常使用C语言实现,这样可以实现更复杂的功能,而且代码会有更好的可读性和可移植性。

一般而言,这两个阶段完成的功能可以如下分类:

  1. boot loader第一阶段的功能:
    • 硬件设备初始化
    • 为加载boot loader第二段代码准备RAM空间
    • 设置CPU的速度、时钟频率以及终端控制寄存器
    • 初始化内存控制器
    • 复制boot loader的第二段到RAM空间中
    • 设置栈
    • 跳转到boot loader第二阶段的c代码入口

在第一阶段的硬件初始化一般包括:关闭WATCHDOG、关中断、设置CPU速度和时钟频率、RAM初始化等。但是这些并不是必须的,比如S3C2410/S3C2440的开发板所使用的U-Bppt中,就将CPU速度和时钟频率的设置放在第二阶段。

  1. Boot loader第二阶段功能
    • 初始化本阶段所需要用到的硬件设备;
    • 检测系统内存映射;
    • 将内核映像和根文件系统映像从flash读到ram空间;
    • 为内核设置启动参数;
    • 调用内核。

C语言代码部分arch/arm/lib/board.c中的board_init_f是C语言开始的函数,也是整个启动代码中Cyuy按的主函数,同时还是整个u-boot的主函数,该函数只需要完成如下操作:

    • 调用一系列的初始化函数;
    • 初始化flash设备;
    • 初始化系统内存分配函数;
    • 如果目标有NAND设备,则将其初始化;
    • 如果目标有显示设备,则初始化;
    • 初始化相关的网络设备,填写ip和mac地址;
    • 进入命令循环(即整个boot的工作循环),接收用户从串口输入的命令,然后执行命令

为了方便开发,至少要初始化一个串口以便程序员与Bootloader进行交互。

所谓检测内存映射,就是确定板上使用了多少内存、它们的地址空间是什么。由于嵌入式开发中Bootloader多是针对某一类板子进行编写,所以可以根据板子的情况直接设置,不需要考虑可以适用于各类情况的复杂算法。

FLASH上的内核映像有可能是经过压缩的,在读到RAM之后,还需要进行解压。当然对于有自解压功能的内核,不需要Bootloader来解压。

将根文件系统映像复制到RAM中,这不是必需的。这取决于是什么类型的根文件系统,以及内核访问它的方法。内核存放在适当的位置后,直接跳到它的入口点即可调用内核。

 

       U-Boot启动顺序流程图如下: 

       Stage1阶段,运行依赖于CPU体系架构的代码,这部分主要完成cpu从上电后的初始化过程,使用汇编语言编写,在对于u-boot是arch/arm/cpu/armv7/start.S

进入进行分析(每一个内核文件夹都有一个start.S文件,cpu上电首先从start.S运行)

 Stage2一般用C语言实现,因此可以实现较为复杂的功能,并且具有良好的可读性和可移植性。(可参考网址 http://blog.chinaunix.net/uid-23193900-id-3184107.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值