u-boot 第一启动阶段简要分析

1. u-boot 整体启动流程 

bootloader是板子上电到linux系统加载之间的一段执行代码。分为两个启动阶段BL1,BL2。BL1主要用汇编语言编写,做一些初始化工作,并将自身从存储介质如flash拷贝到内存中,然后跳到BL2的c程序入口。BL2加载各个设备的驱动,并提供一个命令行的界面来提供各种操作,最终目的是为了加载linux内核。bootloader将启动参数传递给linux内核让其自举,它的使命也就完成了。下面是s3c6410的启动流程,非常经典。

板子自上电开始启动流程供分为4步:

  1. iRom(片内Rom)做一些初始化工作
  2. iRom将flash 或者 SD中的bootloader的前4KB 代码搬移到 stepping stone中。然后这些代码执行bootloader的BL1(第一阶段)
  3. 第一阶段主要初始化系统时钟、uart、SDRAM。然后将存储介质上的整个bootloader代码搬移到SDRAM中,并跳转到BL2(第二阶段)执行
  4. 初始化系统环境为加载os做准备

本文分析的s3c2440启动流程稍有差异。s3c2440支持两种启动方式,NOR flash和NAND flash. 无论是哪种方式启动,板子在上电以后都是从 0x00000000 地址开始运行,但是它们的工作方式或者叫地址的空间映射是不同的。由于NOR flash支持随机存取,当使用它启动时,它的地址直接被映射为0x00000000, 那么就直接从NOR flash运行bootloader. 由于NAND flash不支持随机存取,不能直接运行程序。为了从其启动,s3c2440 配备了片内的4KB SRAM(stepping stone)。 当s3c2440从NAND Flash启动时,NAND flash的头4KB程序被自动的加载到片内的SRAM中运行。然后控制权交由bootloader执行。下面是这个过程的示意图。

与s3c6410相比,s3c2440并没有iRom,u-boot的前4KB代码被自动加载到iRAM中运行。接下来就到了u-boot的执行流程了。

2. 两大启动阶段

U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:

(1). 第一阶段的功能

硬件设备初始化

加载U-Boot第二阶段代码到RAM空间

设置好栈

跳转到第二阶段代码入口

(2). 第二阶段的功能

初始化本阶段使用的硬件设备

检测系统内存映射

将内核从Flash读取到RAM中

为内核设置启动参数

调用内核

3. 第一阶段代码搬移分析

本文学习的是u-boot启动的第一阶段。主要涉及到两个文件 cpu/arm920t/start.S 和board/samsung/mini2440/lowlevel_init.S  硬件初始化工作都是寄存器的操作,这里重点分析u-boot将SDRAM初始化之后将自身搬移到内存中的代码。下面是u-boot从NOR flash将自身搬移到内存的代码。

relocate:                /* relocate U-Boot to RAM        */
    adr    r0, _start        /* r0 <- current position of code   */
    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
    cmp    r0, r1            /* don‘t reloc during debug         */
    beq    stack_setup

    ldr    r2, _armboot_start
    ldr    r3, _bss_start
    sub    r2, r3, r2        /* r2 <- size of armboot            */
    add    r2, r0, r2        /* r2 <- source end address         */

copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop

要理解上面的代码先对几个地址要搞清楚。

.globl _start

_start:

  b       start_code

_start为u-boot执行的开始标号。它的地址取决于当前u-boot在哪里执行。

_TEXT_BASE:

.word        TEXT_BASE

那么去哪里找 TEXT_BASE 呢?它是在./board/samsung/mini2440/config.mk 定义的。如下:

所以如果此时 u-boot 是在内存中运行的话,adr r0, _start 读入的值为程序起始地址即 TEXT_BASE,如果不是在内存中运行,_start 为0,不等于 TEXT_BASE。由此判断当前u-boot是否在内存中,如果在跳转到stack_setup,否则继续往下运行。

.globl _armboot_start

_armboot_start:

.word _start

_armboot_start 与 _start 的值是一致的。

.globl _bss_start

_bss_start:

.word __bss_start

__bss_start 是在链接脚本 u-boot.lds 中定义的。是u-boot的BSS段的起始地址。

由于u-boot不在内存中,_start为0,_armboot也为0。_bss_start为BSS段的起始地址。那么它们两者之间的差值正好等于u-boot程序的大小(BSS段不会被编译到u-boot中)。那么接下来就可以进行拷贝了。

copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop

拷贝函数通过 ldmia stmia 完成u-boot代码从nor flash到SDRAM的拷贝。

ldr pc, _start_armboot

_start_armboot: .word start_armboot

此后将pc指针指向start_armboot。也就到了u-boot的第二启动阶段。这个下篇文章继续分析。

时间: 2024-11-08 22:00:54

u-boot 第一启动阶段简要分析的相关文章

u-boot启动第二阶段简要分析

u-boot第一启动阶段的最后跳转到 start_armboot 函数.这个函数在 lib_arm/board.c 中定义.下面就来看看这个函数做了哪些工作.本文的分析过程比较肤浅.只能说是大致流程.更细的流程还需要仔细的钻研. 下面是两个整个u-boot所使用的最重要的两个全局变量结构体.u-boot的第二阶段也是围绕这两个结构体展开的. typedef unsigned long long phys_size_t; typedef struct bd_info { unsigned long

Android --- Zygote和System进程启动过程简要分析

Android --- Zygote和System进程启动过程简要分析 在看过<Android情景源代码>的Zygote启动章节后,作如下简要总结.Zygote进程在init进程启动过程中被以service服务的形式启动: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root syste

linux系统的启动过程简要分析

接触linux系统运维已经好几年了,常常被问到linux系统启动流程问题,刚好今天有空来梳理下这个过程:一般来说,所有的操作系统的启动流程基本就是: 总的来说,linux系统启动流程可以简单总结为以下几步:1)开机BIOS自检,加载硬盘.2)读取MBR,进行MBR引导.3)grub引导菜单(Boot Loader).4)加载内核kernel.5)启动init进程,依据inittab文件设定运行级别6)init进程,执行rc.sysinit文件.7)启动内核模块,执行不同级别的脚本程序.8)执行/

tiny4412 串口驱动分析七 --- log打印的几个阶段之内核启动阶段(earlyprintk)

作者:彭东林 邮箱:[email protected] 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 下面要分析的是内核Log打印的几个阶段 自解压阶段 内核启动阶段 内核启动完全以后 shell终端下 在这个阶段内核log打印可以调用printk和printascii,同

uboot第一阶段详细分析

原文:uboot第一阶段详细分析 作者:程老师,华清远见嵌入式学院讲师. uboot的第一阶段设计的非常巧妙,几乎都是用汇编语言实现的,下面我们一起来看看它的精妙之处吧! 首先我们来看一下它的链接脚本,通过它我们可以知道它整个程序的各个段是怎么存放的. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")        OUTPUT_ARCH(arm)    

U-BOOT第一阶段程序分析(1)

分析移植之前先介绍下我的软硬件环境: 开发板:JZ2440v2板 CPU   :ARM920T SOC   :S3C2440 晶振freq:12MHz NorFlash:2MB => Am29LV160DB NandFlash:256MB => K9F2G08U0A SDRAM:32MB X 2pieces => K4S561632H-T(U)C(16M X 16bit) U-BOOT版本:u-boot-1.1.6.tar.bz2 我移植的uboot是基于nand启动的,所以代码的分析过

spring boot应用启动原理分析

spring boot quick start 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启动的,不需要另外配置一个Web Server. 如果之前没有使用过spring boot可以通过下面的demo来感受下. 下面以这个工程为例,演示如何启动Spring boot项目: git clone [email protected]:hengyunabc/spring-boot-demo.git mvn spring-b

spring boot启动原理步骤分析

spring boot最重要的三个文件:1.启动类 2.pom.xml 3.application.yml配置文件 一.启动类->main方法 1.spring boot通过fat jar方式用jdk命令java -jar jarname.jar启动的. fat jar就是包含被引用jar包的jar,因为会包含很多jar包,所以称为fat,肥胖. 2.spring  boot通过static void main方法启动,main方法是java程序总是最先运行的地方,这个是由jvm虚拟机决定的.任

Android应用程序启动过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程序的Activity的启动过程.在Android系统中,应用程序是由Activity组成的,因此,应用程 序的启动过程实际上就是应用程序中的默认Activity的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程. 在上一篇文章Android应用程序的Activit