uboot学习之三-----uboot启动第一阶段--start.S之一

摘要:
Uboot分为两个阶段:start S是Uboot的第一阶段。② 由于uboot涉及组装阶段,因此无法直接找到main。c、 所以当分析开始时。S、 考虑configs/x210_sd.h这个宏将在我们的程序中调用。在uboot启动期间,串行端口打印uboot的版本号。版本号信息来自此处。考虑:为什么要开始。S不直接包含asm-arm/proc-armv/domain。h、 但使用asm/proc/domain。嗯?例如,如果我想将uboot迁移到mips体系结构,那么开始时所有的头文件。应修改S源代码。在C110-EVT1-mkbl1.c中:这里与恒星有关。S

uboot分为两个阶段:start.S是uboot的第一阶段。

  一:引入start.S

    u-boot.s找到start.S的入口

      ①首先在C语言中整个项目的入口就是main函数(这是C语言规定的),所以如果要去了解C语言的项目,从main函数开始,这样才能分析,如果随便拿一个文件就开始看,最后看得一头雾水,对自己没有信心。怎么来找呢?可以使用souceinsight的搜索功能来查找。

      ②在uboot中因为有汇编阶段参与,因此不能直接找main.c。整个程序的入口取决于连接脚本中ENTRY声明的地方。ENTRY(_start)因此 _start符号是整个程序的入口,_start所在的代码就是整个程序的起始代码。

  二:分析start.S

    1、头文件包含

      ①#include <config.h> config.h是在include文件下,这个文件不是源码中的文件,是配置时自动生成的文件。详见mkconfig脚本,在mkcofig脚本最后 发现 

      uboot学习之三-----uboot启动第一阶段--start.S之一第1张

      包含了一个#include <configs/x210_sd.h>

      最后分析发现,最终包含的是/include/configs/x210_sd.h,这个文件是整个uboot移植时的配置文件,里面有很多宏。这样就将两个文件关联了起来。所以分析start.S时,要考虑configs/x210_sd.h。

       ②#include <version.h>

        /include/version.h中包含了#include "version_autogenerated.h"这个头文件是编译时自动生成的,这里面定义的宏define U_BOOT_VERSION "U-Boot1.3.4Joran"来自于makefile的配置值。这个宏在我们的程序中会被调用,在我们uboot启动过程中串口打印出uboot的版本号,那个版本号信息就来自于这          里。
       ③#if defined(CONFIG_ENABLE_MMU)
        #include <asm/proc/domain.h>
        #endif

        asm目录不是uboot中的原生目录,uboot中本来是没有这个目录的。asm目录是配置时创建的一个符号链接,实际指向的是就是asm-arm(详解上一章节分析mkconfig脚本时).经过分析后发现,实际文件是:include/asm-arm/proc-armv/domain.h从这里可以看出之前配置时创建的符号链接的作用,如果没有这些符号链接则编译时根本通不过,因为找不到头文件。(所以uboot不能在windows的共享文件夹下配置编译,因为windows中没有符号链接)
        

        思考为什么start.S不直接包含asm-arm/proc-armv/domain.h,而要用asm/proc/domain.h?这样的设计主要是为了可移植性。因为如果直接包含,则start.S文件和CPU架构(和硬件)有关了,可移植性就差了。譬如我要把uboot移植到mips架构下,则start.S源代码中所有的头文件包含全部要修改。我们用了符号链接之后,则start.S中源代码不用改,只需要在具体的硬件移植时配置不同,创建的符号链接指向的不同,则可以具有可移植性。

        ④启动代码的16字节头部

        uboot学习之三-----uboot启动第一阶段--start.S之一第2张

从代码读出:如果定义了CONFIG_EVT1并且没有定义CONFIG_FUSED,那么就定义4个4字节的空间。从sourceinsight部分可以看出红色是已经定义的,黑色是未定义的,所以条件满足,定义出16字节的空间,并且填充起来。

裸机中讲过,从SD卡和nand启动是需要16字节校验头(mkv210image.c就是为了计算这个校验头),以前做裸机实验时,dnw下载方式不需要校验头,做SD卡启动,mkv210image.c会给原镜像210.bin加上16字节的校验头。

uboot中,这里的start.S中在开头位置放了16字节的填充占位,这个占位的16字节只是保证正式的image的头部确实有16字节,但是这个16字节内容是不对的,还需要后面去计算校验和然后重新去填充的,uboot下有一个sd_fusing文件夹下C110-EVT1-mkbl1.c这个文件几乎就是我们之前的mkv210image.c。

C110-EVT1-mkbl1.c中:

uboot学习之三-----uboot启动第一阶段--start.S之一第3张

这里和star.S是相互联系的。

      ⑤异常向量表构建

uboot学习之三-----uboot启动第一阶段--start.S之一第4张

这个异常表顺序是CPU设计时决定的,是硬件决定的。这些异常应该被处理,如果不处理这些这些异常,程序会跑飞。   

  复位异常处理:复位异常的代码是 b reset ,因此在CPU复位后真正去执行的有效代码是reset处的代码,因此reset符号处,才是真正有意义代码的开始处。

    ⑥有意思的deadbeef

    .balignl 16,0xdeadbeef  .balignl 16 是以16字节对齐,如果没有对齐,用0xdeadbeef这个数字来填充,这个填充没有什么特别的意义,只是刚好组成一个有意思的英语单词----坏牛肉

 

uboot学习之三-----uboot启动第一阶段--start.S之一第5张

 

为什么要对齐呢?有时候是为了提高访问效率,有时候是硬件的要求。

    ⑦TEXT_BASE等

uboot学习之三-----uboot启动第一阶段--start.S之一第6张

第100行的TEXT_BASE在整个代码里都是被引用,它是在makefile里配置阶段时的TEXT_BASE,其实就是我们链接时,指定的程序的链接地址,它的值就是c3e00000,我们在源代码中和配置的makefile中很多变量是互相关联的,有些符号的值可以从makefile中传递到源代码中.

  ⑧CFG_PHY_UBOOT_BASE  33e00000  uboot在DDR中的物理地址。虚拟地址就是之前的ce3e00000。

uboot学习之三-----uboot启动第一阶段--start.S之一第7张

uboot学习之三-----uboot启动第一阶段--start.S之一第8张

.globl _armboot_start
_armboot_start:
    .word _start

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start
_bss_start:
    .word __bss_start

.globl _bss_end
_bss_end:
    .word _end

 armboot_start是后面重定位时用到的,bss_start这些是后面清bss段时会使用到的。

免责声明:文章转载自《uboot学习之三-----uboot启动第一阶段--start.S之一》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇vue 项目安装依赖报错解决方法「thunar」给thunar增加搜索文件功能下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

03点云文件常用格式转换(pcd,txt,ply,obj,stl)

1.  pcd转txt 1 #include <iostream> 2 #include <fstream> 3 #include <pcl/io/pcd_io.h> 4 5 int main(int argc, char *argv[]) 6 { 7 8 pcl::PointClou...

java调用dll(native方法的实现)

java 中有许多native 方法,下面简单研究下native 方法的实现以及在java 中调用native 方法。 下面以简单的操作加减乘除实现 1. 新建java 类 源码如下: packagecom.zd.bx; public classOperation { public native int add(int a, intb);} 2...

C/C++读取时间的方法

【摘要】本文介绍C/C++下获取日历时间的方法,区别于JAVA语言的方便,C/C++标准库好像并没有一次性得到具有可读性的HH:MM:SS的方法,本文介绍常用的三步法得出具有可读性的时间,并且介绍了纳秒和微秒的时间获取。 1、对于C语言,需包含的头文件: 1 #include <sys/time.h> 2、获取日期需要先获取日历时间,即1970...

assert()函数用法总结

assert()函数用法总结assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h>void assert( int expression );   assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向s...

【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boot 源码 : http://download.csdn.net/detail/han1202012/8342761 -- S3C2440 文档 : ht...

Linux 错误码对照表

errno 在 <errno.h> 中定义,错误 Exx 的宏定义在 /usr/include/asm-generic 文件夹下面的 errno-base.h 和 errno.h,分别定义了 1-34 、35-132 的错误定义。 strerror() 函数依据 errno 值返回错误描述字符串,下面程序打印对照表: #include <...