16.U-boot的工作流程分析-2440

发布者:CelestialMagic最新更新时间:2024-10-30 来源: cnblogs关键字:U-boot  工作流程 手机看文章 扫描二维码
随时随地手机看文章

分析的流程:

  1. 程序入口

  2. 第一阶段程序分析

  3. 第二阶段程序分析

2440开发板

1.uboot的入口:

要看uboot工程的入口,首先打开顶层目录的Makefile:

Uboot所支持的开发板,在顶层的Makefile中都会有一个配置选项。比如2440,在Makefile中的配置选项是smdk2440_config:在vim的命令模式按下/,然后输入smdk6410_config回车会定位到这里:

这是Makefile里的一个目标。这是来配置2440开发板的。看到上图第二行的smdk2440,这个参数决定了开发板的名称。这个名称是有作用的。接下来看看他的作用。

首先是找一下目录:

可以看到这里有很多smdk的子目录,也包括smdk2440,这两个是对应的。该目录存放的就是2440开发板相关的文件。里面有一个叫uboot.lds的文件,前面知道lds文件是连接器脚本。Uboot的整个过程的链接,是通过该脚本来链接控制的。打开该链接器脚本:

OUTPUT_FORMAT('elf32-littlearm', 'elf32-littlearm', 'elf32-littlearm')

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

    . = 0x00000000;

    . = ALIGN(4);

    .text :

    {

     cpu/s3c24xx/start.o    (.text) //1可以看到位于代码段前端的文件是start.o,对应的是一个汇编文件。这个汇编文件会最先被运行。但是这个汇编代码里最先执行的代码是哪些呢?

     cpu/s3c24xx/s3c2440/cpu_init.o    (.text)

     *(.text)

    }

    . = ALIGN(4);

    .rodata : { *(.rodata) }

    . = ALIGN(4);

    .data : { *(.data) }

    . = ALIGN(4);

    .got : { *(.got) }

 

    . = .;

    __u_boot_cmd_start = .;

    .u_boot_cmd : { *(.u_boot_cmd) }

    __u_boot_cmd_end = .;

 

    . = ALIGN(4);

    .mmudata : { *(.mmudata) }

 

    . = ALIGN(4);

    __bss_start = .;

    .bss : { *(.bss) }

    _end = .;

}

首先是找到该文件:

上面u-boot-lds文件里,在sections的标识之上,有一行:ENTRY(_start)是整个程序的入口。所以就找找start.S文件里有没_start这个标识呢?一搜会马上看到该标号:

到这里,看到这个_start才是整个uboot工程的入口。

 

接下来是第一阶段的代码:

在Linux里,打开上一节创建好的,Source Insight里的uboot工程:

然后找到smdk2440的start.S:

接下来看uboot做了什么事,主要是通过注释来分析:

开发板一上电,它会跳转到start.S的中断向量表的开始处执行:

从它的注释:

所以1,:知道上电后是跳到中断向量表来执行。执行的第一条指令是b start_code。

Start_code的实在start.S的下面定义的:

从注释知道,这是actual start code。进入之后,set the cpu to svc32 mode,设置cpu为SVC模式。

接着执行的代码是:

3.刷新I/D caches。

4.然后是关闭MMU和cache:

后加

关闭系统时钟,在lowlevel _init函数里bl system_clock_init函数。进入该函数:

可以看到2440是在初始化系统时钟里关闭看门狗

下面还有屏蔽中断的操作:

 

后加

5.接着是运行的是一个函数:看看是定义在那个文件的。

点击:,然后在Symbol里输入:lowlevel_init:

会看到出现很多,然后在下面可以看到它们各自的目录。其实每一个开发板都对应一个lowlevel_init.S:

进入该文件:

5看到系统进入该文件做的第一件事是:初始化系统时钟:

6.接着初始化串口:

7.对nand进行简单初始化:

8.接下来的代码很重要:

由前面的学习知道,当我们开发一个uboot在开发阶段,就是在调试uboot的时候,不用烧到NandFlash去运行,可以下载到内存里面去调试运行。这时候就不需要代码搬移bl0,bl1,bl2的过程。就不需要进行拷贝工作了。所以上面的代码就是判断,判断uboot代码是在内存运行,还是在NandFlash运行。如果没有运行在内存当中,就是从NandFlash启动。就需要对内存进行初始化,就是跳转到mem_con_init处执行,进行内存初始化。执行完内存初始化之后就要返回了。

返回到:

接着往下执行:

9.判断是NandFlash启动还是Nor Flash启动:

如果是NandFlash启动这是执行下面的:把代码从NandFlash拷贝到内存去。

NorFlash这执行下面,把代码从NorFlash拷贝到内存。

这里讲NandFlash启动,所以跳转到nand_copy:

 

10,接着是设置堆栈:

 

11.接着清除BSS段:

 

到这里第二阶段的代码就执行完了。

三:

执行完上面,程序跳转到_start_armboot处执行:

上面的代码,通过伪指令ldr把_start_armboot的值装入pc指针,程序就会跳转到_start_armboot处执行。而此处的地址是start_armboot的地址。就是,程序会跳转到start_armboot函数处执行。就是把我们的pc指针跳转到内存去执行了。

下面看看start_armboot的地址是不是在内存中。

配置uboot:make smdk2440_config,然后执行make。

然后看到生成的文件:

 

其中,u-boot是elf文件,u-boot.bin是二进制文件。

接下来对u-boot的elf文件,进行反汇编,看看start_armboot函数的地址:

arm-linux-objdump -D -S u-boot >dump

查看:

看到函数的其实地址30009100的地址是在内存里的。所以start.S里的:

实现了从垫脚石跳转到内存。但是,此时会发现在这里的起始地址被变为了30008000:

在第一阶段里,不是说启动地址是在0吗?为什么这里是30008000呢?还有就是为什么是这个地址。

 

前面的学习知道,当去链接一个程序的时候,程序由多个文件构成,起始地址是由链接器脚本决定的。在/home/samba/uboot/Uboot/2440/uboot/board/samsung/smdk2440里的u-boot.lds:

起始地址是0:

这里是0,为什么那里会是30008000呢?我们回到uboot的顶层目录,打开config.mk:

搜索text_base:

找到:

在这里-T $(LDSCRIPT)就是定义使用链接器脚本。后面的-Ttext 是制定代码段的基地址的。$(TEXT_BASE)。这里有两个起始地址,然而程序运行的时候以后面的TEXT_BASE的地址为准。它会覆盖掉LDSCRIPT这个地址。

 

TEXT_BASE是在board/Samsung/smdk2440/config.mk里定义的。最后一行:

 

接下来就是测试验证一下,把他修改为30005000。然后程序编译:

Make smdk2440_config->make:

反汇编:

arm-linux-objdump -D -S u-boot >dump

上面的起始地址变了,刚才制定的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

那起始地址为什么不是0呢?下图:

从上图可以看到,ldr PC,=start_armboot的跳转,把地址从垫脚石跳转到内存里。在前面的代码里,有用到b reset等跳转指令,为什么这不会跳转到内存去执行,而是还在垫脚石里呢?

例如:

上面的跳转,bl lowlevel_init的跳转地址:

为什么PC指针还是在垫脚石中呢?

 

这就得讲两个词了。绝对跳转和相对跳转。

B和bl是相对跳转。

 

 

 

 

 

Ldr伪指令是绝对跳转:

 

第三阶段:

是从此函数Start_armboot进入的。主要完成的硬件和软件的初始化,只是一些基础的初始化。

该函数里有一个for循环:

在for里首先是让一个指针数组,把里面的函数指针依次调用一次,if里的判断语句就是函数指针。那么指针数组里有哪些函数指针呢。

 

指针数组:

可以看到里面都是函数指针。这里软件的初始化就不看了,我们只看硬件的初始化。在这些函数指针里,硬件初始化的有串口初始化。Serial_init。接着是lcd的初始化:

初始化网卡:

初始化led:

接着进入一个主循环:

执行用户输入的命令。例如tftp命令。这里是一个死循环。老是等待执行用户继续输入命令。在第一个阶段,每个开发板可能有不同的地方,但是在这个地方都是一样的。就是,在第二阶段都是跳到start_armboot处执行代码。2440的第一阶段是在start.S的b reset开始。


关键字:U-boot  工作流程 引用地址:16.U-boot的工作流程分析-2440

上一篇:17.U-boot的工作流程分析-6410
下一篇:15.ARM处理器的启动流程

推荐阅读最新更新时间:2026-03-25 06:09

TQ2440 学习笔记—— 27、移植U-Boot【Bootloader 作用、工作流程
一、Bootloader 简介 1、系统上电之后,需要一段程序来进行初始化:关闭WATCHDOG、改变系统时钟、初始化存储控制寄存器、将更多的代码复制到内存中等。如果它能将操作系统内核复制到内存中运行,无论从本地(比如Flash)还是从远端(比如通过网络),就称这段程序为Bootloader 。 简单的说,Bootloader 就是这么一段小程序,它在系统上电时开始执行,初始化硬件设备、准备好软件环境,最后调用操作系统内核。 2、Bootloader 的启动方式 CPU 上电后,会从某个地址开始执行。比如MIPS 结构的CPU 会从0xBFC00000取第一条指令,而ARM 结构的CPU则从地址 0x0000000
[单片机]
TQ<font color='red'>2440</font> 学习笔记—— 27、移植<font color='red'>U-Boot</font>【Bootloader 作用、<font color='red'>工作</font><font color='red'>流程</font>】
[国嵌笔记][030][U-Boot工作流程分析]
uboot工作流程分析 程序入口 1.打开顶层目录的Makefile,找到目标smdk2440_config的命令中的第三项(smdk2440) 2.进入目录board/samsung/smdk2440/,找到u-boot.lds文件。uboot的链接都是由这个链接器脚本来控制的 3.打开u-boot.lds文件,找到.text(代码段)的第一个文件cup/s3c24xx/start.o,该文件就是uboot的入口代码。链接器脚本中的ENTRY用来表明整个程序的入口,那么标号_start就是整个程序的入口 4.第一阶段入口在cup/s3c24xx/start.S文件的_start处 5.第二阶段入口在lib_arm/board.c
[单片机]
[国嵌笔记][030][<font color='red'>U-Boot</font><font color='red'>工作</font><font color='red'>流程</font>分析]
u-boot移植(二)---修改前工作:代码流程分析1
一、代码执行总体流程图 1.1 代码路径  U-boot.lds (archarmcpu) vectors.S (archarmlib) start.S (archarmcpuarm920t) lowlevel_init.S (boardsamsungjz2440) crt0.S (archarmlib) relocate.S (archarmlib) Board_init.c (commoninit) Board_f.c (common) Jz2440.h (includeconfigs) Generic-asm-offsets.h (includegenerated) 1.2 启动代码流
[单片机]
16.U-boot的工作流程分析-2440
分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makefile: Uboot所支持的开发板,在顶层的Makefile中都会有一个配置选项。比如2440,在Makefile中的配置选项是smdk2440_config:在vim的命令模式按下/,然后输入smdk6410_config回车会定位到这里: 这是Makefile里的一个目标。这是来配置2440开发板的。看到上图第二行的smdk2440,这个参数决定了开发板的名称。这个名称是有作用的。接下来看看他的作用。 首先是找一下目录: 可以看到这里有很多smdk的子目
[单片机]
16.U-boot的<font color='red'>工作</font><font color='red'>流程</font>分析-<font color='red'>2440</font>
u-boot移植到s3c2440开发板(一)--建立单板
由于没有系统的学习shell,所以Makefile大多数看不懂,一个小小的细节,把我难住了几天。现在开始分享我的操作过程 本文所有linux下的操作是root用户,如果你使用普通用户,请在命令前加上 $ sudo xxxx 所有Linux命令都是加粗,需要加入的文本是斜体 /* *  Ubuntu 16.04 *  u-boot-2016.05.tar.bz2 *  arm-linux-gcc-4.4.3.tar.gz */ 准备工作 1.下载u-boot,我是用的u-boot-2016.05.tar.bz2,可以自己去官网下载 下载地址, ftp://ftp.denx.de/pub/u-boot/ 2.下载arm-linux-g
[单片机]
<font color='red'>u-boot</font>移植到s3c<font color='red'>2440</font>开发板(一)--建立单板
u-boot-2015.04 在tq2440上的移植(使用spl引导u-boot
本次移植跟以往的不同之处是采用了spl来引导u-boot,参考了博客 http://blog.csdn.net/fulinus/article/details/42738641 下载链接: http://pan.baidu.com/s/1bnlRKgn 使用方法: 1、 编译   make tq2440_defconfig   make 2、 然后会在u-boot根目录下生成u-boot.bin,在spl目录下会生成u-boot-spl.bin,目前的分区是: u-boot-spl.bin (1M) u-boot.bin (1M) kernel (3M) rootfs (剩余) 自己可以改动,在arc
[单片机]
U-Boot在FL2440上移植(一)----修改系统时钟
一 U-boot源码结构 图片来自韦东山的《嵌入式linux应用开发完全手册》 U-boot下载地址: ftp://ftp.denx.de/pub/u-boot/ 交叉编译工具链 3.3.2 二 U-boot移植 1.新建一个fl2440开发板目录和文件 ①在board目录下新建fl2440目录,讲smdk2410目录下的文件复制到fl2440目录下,并将board/fl2440/smdk2410.c重命名为fl2440.c ②修改u-boot-1.1.6目录下Makefile文件 smdk2410_config : unconfig @$(MKCONFIG) $(@:_config
[单片机]
<font color='red'>U-Boot</font>在FL<font color='red'>2440</font>上移植(一)----修改系统时钟
U-Boot在FL2440上移植(二)----支持NOR Flash
一 选择NOR flash型号 我的开发板上的nor flash芯片是Intel的JS28F320(4MB)(1device=32blocks,1block=128MB fl2440默认是nandflash启动,norflash启动只需将跳线帽J5拔掉就可以了 1. 把开发板的配置文件fl2440.h(/include/configs/fl2440.h)中关于flash的配置部分都删掉,换成下面的配置: #define CONFIG_NR_DRAM_BANKS 1 #define PHYS_SDRAM_1 0x30000000 #define PHYS_SDRAM_1_SIZE 0x040
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved