u-boot分析 四 (程序入口start.S)

本文详细分析了u-boot的启动流程,重点介绍了start.S文件中的Stage1,包括入口设置、异常向量、CPU配置、内存控制器初始化、代码复制到RAM以及堆栈初始化。Stage2则在board.c的board_init_r()函数中开始,负责调用各种初始化函数,如Flash、内存分配、NAND设备、显示设备和网络设备的初始化,最终进入命令循环。
摘要由CSDN通过智能技术生成

u-boot分析 四 (程序入口start.S)


注:部分内容摘抄自网络,如有问题,请联络博主。


本文内容:了解以stars.S为开始的ARM汇编程序部分。


回顾前几篇博文,咱们见识过了u-boot的目录结构,另外简要分析了u-boot.lds脚本文件的link原理。而今天我们要来听听嵌入式程序君告诉咱们的第一句“话”。


正式开始之前,我们需要准备三样东西:

  1. u-boot source code
  2. 常用ARM指令集
  3. Source Insight(用于trace code,使用方法略过,不会问百度)
    这里写图片描述

bootloader通常stage1和stage2两步骤,u-boot也不例外。

  1. Stage1:依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在这个程序段,且可以用汇编语言来实现;
  2. stage2:通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。

具体的说,

  1. Stage1 start.S代码结构
    u-boot的stage1代码通常放在start.S文件中,用汇编语言写成,其主要代码部分如下:
    (1) 定义入口。由于一个可执行文件必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址。因此,必须通知编译器以使其知道这个入口,该工作可通过修改链接器脚本(.lds文件)来完成。
    (2) 设置异常向量(Exception Vector)。
    (3) 设置CPU的速度、时钟频率及终端控制寄存器。
    (4) 初始化内存控制器。
    (5) 将ROM中的代码复制到RAM中。
    (6) 初始化堆栈。
    (7) 转到RAM中执行,该工作可使用指令ldr pc来完成。

  2. Stage2 C语言代码部分
    ./arch/arm/lib/board.c中的board_init_r()是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:
    (1) 调用一系列的初始化函数。
    (2) 初始化Flash设备。
    (3) 初始化系统内存分配函数。
    (4) 如果目标系统拥有NAND设备,则初始化NAND设备。
    (5) 如果目标系统有显示设备,则初始化该类设备。
    (6) 初始化相关网络设备,填写IP、MAC地址等。
    (7) 进去命令循环(即整个boot的工作循环),接收用户从串口输入的命令,然后进行相应的工作。

事不宜迟,我们赶紧打开start.S:
./arch/arm/cpu/slsiap/s5p4418/start.S

/*
 * armboot - Startup Code for NXPxxxx/ARM Cortex CPU-core
 */

#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <asm/system.h>
#include <linux/linkage.h>

/*
 *************************************************************************
 *
 * Exception vectors as described in ARM reference manuals
 *
 * replace arm/lib/vectors.S
 *
 *************************************************************************
 */
    .globl  _stext  
    /*程序的全局入口,《u-boot分析 三》中u-boot.lds设置此入口地址为0x00000000*/
_stext:
    b   reset
    /*参阅《常用ARM指令集及汇编》可知,b为跳转指令,跳转到reset函数处,reset在后面*/

    /*ARM体系结构规定在上电复位后的起始位置,必须有8条连续的跳转指令,通过硬件实现。他们就是异常向量表*/
    /*ldr,用于加载32bit的立即数或一个地址值到指定寄存器*/
    ldr pc, _undefined_instruction /*未定义指令异常,0x04*/
    ldr pc, _software_interrupt    /*软中断异常,0x08*/
    ldr pc, _prefetch_abort        /*内存操作异常,0x0c*/
    ldr pc, _data_abort            /*数据异常,0x10*/
    ldr pc, _not_used              /*未使用,0x14*/
    ldr pc, _irq                   /*慢速中断异常,0x18*/
    ldr pc, _fiq                   /*快速中断异常,0x1c*/

/*.word的意思是将后边的符号所对应的32bit值赋予前面的符号*/
/*而如下的七条语句,后面的符号正好是对应的中断异常服务程序的入口地址*/
/*这七个中断服务程序位于./arch/arm/cpu/slsiap/s5p4418/vector.S*/
_undefined_instruction: .word undefined_instruction
_software_interrupt:    .word software_interrupt
_prefetch_abort:    .word prefetch_abort
_data_abort:
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值