u-boot移植(二)---修改前工作:代码流程分析1
一、代码执行总体流程图
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的更多相关文章
- 关于calendar修改前的代码和修改后的代码
Java编写的日历,输入年月,输出这个月的日期与星期 修改前的代码: import java.io.BufferedReader; import java.io.IOException; import ...
- nova start 虚机的代码流程分析
nova start 虚机的代码流程分析,以ocata版本为分析基础1.nova api服务接受用户下发的 nova start启动虚机请求其对应的http restfull api接口为post / ...
- u-boot移植(三)---修改前工作:代码流程分析2
一.vectors.S 1.1 代码地址 vectors.S (arch\arm\lib) 1.2 流程跳转 跳转符号 B 为 start.S 中的 reset 执行代码,暂且先不看,先看看 vect ...
- u-boot移植(四)---修改前工作:代码流程分析3---代码重定位
一.重定位 1.以前版本的重定位 2.新版本 我们的程序不只涉及一个变量和函数,我们若想访问程序里面的地址,则必须使用SDRAM处的新地址,即我们的程序里面的变量和函数必须修改地址.我们要修改地址,则 ...
- ok6410 u-boot-2012.04.01移植二修改源码支持单板
继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟.串口.NAND.DDR等初始化.这些工作在以前的裸板程序都写了,直接拿来用.我觉得先写裸板程 ...
- 以太网驱动的流程浅析(二)-Ifconfig的详细代码流程【原创】
以太网驱动流程浅析(二)-ifconfig的详细代码流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<L ...
- 七、uboot 代码流程分析---C环境建立
7.1 start.S 修改 在上一节中的流程中,发现初始化的过程并没由设置看门狗,也未进行中断屏蔽 如果看门狗不禁用,会导致系统反复重启,因此需要在初始化的时候禁用看门狗:中断屏蔽保证启动过程中不出 ...
- springmvc 源码分析(二)-- DiapartcherServlet核心调用流程分析
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git 项目结构代码如下: 一: cont ...
- 六、uboot 代码流程分析---start.S
6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...
随机推荐
- Bootstrap 引入文件顺序及IE兼容性js
<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...
- WebService概述
一.WebService介绍 什么是WebService? 一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 所谓跨编程语言和跨操作平台,就是说服务端程序采用java编 ...
- linux bin & sbin different
linux bin & sbin different flutter & $PATH http://blog.taylormcgann.com/2014/04/11/differenc ...
- Database testing test scenarios
1 check if correct data is getting saved is database upon successful page submit2 check values for c ...
- override overload reintroduce的区别(delphi)
1.override overload reintroduce的中文叫法是什么? override:覆盖:overload:重载:Reintroduce:重定义 2.在子类中override或ov ...
- scrapy 简单爬虫实验
利用python的模块requests来爬取百度搜索出来的url 使用环境为python3 #!/use/bin/env python # -*- coding:utf-8 -*- import re ...
- Django-website 程序案例系列-10 cookie 和 session的应用
cookie: 现在所有网站基本都要开启cookie 客户端浏览器上的一个文件 例如: {‘key’: 'sefwefqefwefw'} 是一个键值对 简单实现cookie认证: user_in ...
- poj2965 【枚举】
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to op ...
- hud 1312
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A ...
- BZOJ 2929: [Poi1999]洞穴攀行
2929: [Poi1999]洞穴攀行 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 351 Solved: 195[Submit][Status][ ...