一、代码执行总体流程图

1.1 代码路径 

  • U-boot.lds (arch\arm\cpu)

  • vectors.S (arch\arm\lib)

  • start.S (arch\arm\cpu\arm920t)

  • lowlevel_init.S (board\samsung\jz2440)

  • crt0.S (arch\arm\lib)

  • relocate.S (arch\arm\lib)

  • Board_init.c (common\init)

  • Board_f.c (common)

  • Jz2440.h (include\configs)

  • Generic-asm-offsets.h (include\generated)

1.2 启动代码流程图

  

二、链接文件

  目录:u-boot-2017.03/arch/arm/cpu

  文件:u-boot.lds

  编写好的 .lds 文件,在用 arm-Linux-ld 连接命令时带 -Tfilename 来调用执行,如:arm-linux-ld-Tnand.lds x.o y.o -o xy.o

  也用-Ttext参数直接指定连接地址,如 arm-linux-ld-Ttext 0x30000000 x.o y.o -oxy.o

  既然程序有了两种地址,就涉及到一些跳转指令的区别。 
  ARM汇编中,常有两种跳转方法:b跳转指令、ldr指令向PC赋值。 
  要特别注意这两条指令的意思: 
  1> b step:b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该指令本身的bit[23:0]算出来的,这使得使用b指令的程序不依赖于要跳到的代码的位置,只看指令本身。 
  2> ldr pc, =board_init_r :该指令是一个伪指令编译后会生成以下代码:ldr pc, [pc, #8]

    从内存中的某个位置读出数据并赋给PC,同样依赖当前PC的值,所以可以用它实现从Flash到RAM的程序跳转。

  2种方式指明程序地址,这里分析下第二种方式,在根目录 Makefile文件有如下一行:

  

  在文件 include/configs/jz2440.h 有定义:

  

  我们在这里可以用下面的命令生成 u-boot.dis文件(注意交叉编译器的名字):

  arm-2440-linux-gnueabi-objdump -D -m arm u-boot > u-boot.dis

  

  在0 地址执行的是 _start.S文件,然后跳转到reset执行,接着定义异常向量表:

  

  在u-boot.lds 脚本中并没有指定基地址, 根目录下的 u-boot 脚本是由 arch/arm/cpu/u-boot.lds 在编译的时候生成的,所以如果要修改u-boot.lds 需要找到正确的地方。

  u-boot.lds 分析:  1 #include <config.h>

 /* 指定输出可执行文件是elf格式,32位ARM指令,小端模式  */
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm) /* 指定输出文件的的平台体系为ARM */
ENTRY(_start) /* 指定可执行映像文件的起始段的段名是 _start,这里跳转到vector.S执行 */
SECTIONS
{
/DISCARD/ : { *(.rel._secure*) }
/* 指定可执行的 image 文件的全局入口点,通常这个地址都发给你法rom(flash)0x0位置。
* 必须使编译器知道这个地址,一般不修改此处,而是修改其它地方的宏定义*/
. = 0x00000000;
. = ALIGN();
.text :
{
/* 映像文件赋值起始地址,它在文件 arch/arm/lib/sections.c 中定义:
* char __image_copy_start[0] __attribute__((section(".__image_copy_start")));*/
*(.__image_copy_start)
/* arch/arm/lib/vectors.S 里有一句:.section ".vectors" */
/* 这里的 vectors 是让vector.S 链接的二进制文件的开头部分 */
*(.vectors)
CPUDIR/start.o (.text*) /* 执行 start.S */
*(.text*) /* 其他代码 */
} . = ALIGN();
/* 只读数据段,所有的只读数据段都放在这个位置 */
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } . = ALIGN();
/* 可读写数据段,所有的可读写数据段都放在这个位置 */
.data : {
*(.data*)
} . = ALIGN(); . = .; . = ALIGN();
    /* U-BOOT命令段 */
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
} . = ALIGN(); .image_copy_end :
{
*(.__image_copy_end)
}

    /* 相对动态信息段 */
.rel_dyn_start :
{
*(.__rel_dyn_start)
} .rel.dyn : {
*(.rel*)
} .rel_dyn_end :
{
*(.__rel_dyn_end)
} .end :
{
*(.__end)
} _image_binary_end = .; /*
* Deprecated: this MMU section is used by pxa at present but
* should not be used by new boards/CPUs.
*/
. = ALIGN();
.mmutable : {
*(.mmutable)
} /*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)

     * bss段,里面放置的是初始值为0的全局变量和静态变量,这些变量不会保存在
        * 二进制文件中

  */

     .bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
} .bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN();
__bss_limit = .;
} .bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
} .dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu.hash : { *(.gnu.hash) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}

  链接执行,首先是进入到arch/arm/vector.S 中执行,在其中执行 _start.S ,_start.S 的首行就跳转到 start.S 中的 reset 中去执行了。

  这里没有执行SPL,若要加上SPL,则还需要加上 nandflash

  链接脚本暂时的流程为:

  

  跳转A处,A代码在Vector.S中,执行_start.S代码,下一节看 _start.S的代码,并分析其过程。

备注:后续会更新此文档

u-boot移植(二)---修改前工作:代码流程分析1的更多相关文章

  1. 关于calendar修改前的代码和修改后的代码

    Java编写的日历,输入年月,输出这个月的日期与星期 修改前的代码: import java.io.BufferedReader; import java.io.IOException; import ...

  2. nova start 虚机的代码流程分析

    nova start 虚机的代码流程分析,以ocata版本为分析基础1.nova api服务接受用户下发的 nova start启动虚机请求其对应的http restfull api接口为post / ...

  3. u-boot移植(三)---修改前工作:代码流程分析2

    一.vectors.S 1.1 代码地址 vectors.S (arch\arm\lib) 1.2 流程跳转 跳转符号 B 为 start.S 中的 reset 执行代码,暂且先不看,先看看 vect ...

  4. u-boot移植(四)---修改前工作:代码流程分析3---代码重定位

    一.重定位 1.以前版本的重定位 2.新版本 我们的程序不只涉及一个变量和函数,我们若想访问程序里面的地址,则必须使用SDRAM处的新地址,即我们的程序里面的变量和函数必须修改地址.我们要修改地址,则 ...

  5. ok6410 u-boot-2012.04.01移植二修改源码支持单板

    继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟.串口.NAND.DDR等初始化.这些工作在以前的裸板程序都写了,直接拿来用.我觉得先写裸板程 ...

  6. 以太网驱动的流程浅析(二)-Ifconfig的详细代码流程【原创】

    以太网驱动流程浅析(二)-ifconfig的详细代码流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<L ...

  7. 七、uboot 代码流程分析---C环境建立

    7.1 start.S 修改 在上一节中的流程中,发现初始化的过程并没由设置看门狗,也未进行中断屏蔽 如果看门狗不禁用,会导致系统反复重启,因此需要在初始化的时候禁用看门狗:中断屏蔽保证启动过程中不出 ...

  8. springmvc 源码分析(二)-- DiapartcherServlet核心调用流程分析

    测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git 项目结构代码如下: 一: cont ...

  9. 六、uboot 代码流程分析---start.S

    6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...

随机推荐

  1. Git 换行符检查 CRLF 与 LF

    遇到的问题 在 git 提交或是签出时,提示如下问题: [git] warning: LF will be replaced by CRLF | fatal: CRLF would be replac ...

  2. JavaScript中的Date对象在IOS中的“大坑”

    在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象. 但是在IOS5版本里面的Safari解释ne ...

  3. BZOJ1087[SCOI2005]互不侵犯——状压DP

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入 只有一行,包含两个数N,K ( ...

  4. poj2115-C Looooops -线性同余方程

    线性同余方程的模板题.和青蛙的约会一样. #include <cstdio> #include <cstring> #define LL long long using nam ...

  5. John's trip POJ - 1041(这题数据有点水)

    题意: 其实还是一个欧拉回路,但要按字典序走路: 解析: 我真是蠢啊emm... map[i][j]表示由顶点i经街道j会到达的顶点编号 然后枚举j就好了 用栈储存.. 虽然我不是这样写的 #incl ...

  6. Codeforces Round #436 (Div. 2) A,B,D

    A. Fair Game 题目链接:http://codeforces.com/contest/864/problem/A 水题 #include<iostream> #include&l ...

  7. DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)

    前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下.运算一般都要满足可减性. 比较naive就不展开了. 题目 [Todo]洛谷P2513 [HAOI2009]逆序对数列 [D ...

  8. Spark RDD操作之Map系算子

    在linux系统上安装solrCloud 1.依赖: JRE solr7.3 需要 java1.8 独立的zookeeper服务 ,zookeeper安装请参考: http://zookeeper.a ...

  9. SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

          虽然 JQuery 也能通过授权header实现跨域, 但SharePoint 提供了更简单的方法,它被实现在SP.RequestExecutor里 .它能访问跨域的服务包括REST AP ...

  10. WebLogic安装及部署

    安装(输入命令打开安装窗口) 打开命令终端,cd 到你wls1036_generic.jar存放的目录下 在终端输入:java -Dspace.detection=false -jar wls1036 ...