执行完 board_init_f 后,重新跳转回 _main 中执行。

10.1 relloc_code 前

10.1.1 gd 设置

  在调用board_init_f()完成板卡与全局结构体变量 gd 的初始化后将其拷贝到在代码段下重新分配的全局结构体中。接下来进行sp的重新设置,将r9指向重新分配的全局变量gd,然后进行代码的重定位。

    /* 将 sp 指针指向全局gd的gd->start_addr_sp,即栈底 */
ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic r0, r0, # /* 8-byte alignment for ABI compliance */
mov sp, r0
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */

10.1.2 relocate_vectors

  当执行未 GD 的设置后,跳转到 relocate_vectors 中去执行向量初始化

 adr    lr, here
 here:
/*
* now relocate vectors
*/ bl relocate_vectors

  relocate_vectors 主要是进行异常向量表的重定位,将异常向量表拷贝到正确的地址中去,relocate.S (arch\arm\lib)

 ENTRY(relocate_vectors)
/*
* Copy the relocated exception vectors to the
* correct address
* CP15 c1 V bit gives us the location of the vectors:
* 0x00000000 or 0xFFFF0000.
*/
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
mrc p15, , r2, c1, c0, /* V bit (bit[13]) in CP15 c1 */
ands r2, r2, #( << )
ldreq r1, =0x00000000 /* If V=0 */
ldrne r1, =0xFFFF0000 /* If V=1 */
ldmia r0!, {r2-r8,r10}
stmia r1!, {r2-r8,r10}
ldmia r0!, {r2-r8,r10}
stmia r1!, {r2-r8,r10}
bx lr ENDPROC(relocate_vectors)

10.1.3  relocate_code

  紧接着设置重定位的开始和结束地址。设置完成后跳转到 relocate_code(relocate.S) 中执行

     ldr    r0, [r9, #GD_RELOC_OFF]        /* r0 = gd->reloc_off */
add lr, lr, r0
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
b relocate_code

  拷贝代码段和动态连接段

 ENTRY(relocate_code)
ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */
subs r4, r0, r1 /* r4 <- relocation offset */
beq relocate_done /* skip relocation */
ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */ /* 拷贝代码到 SDRAM 中去,.__image_copy_start = 0; */
copy_loop:
ldmia r1!, {r10-r11} /* copy from source address [r1] */
stmia r0!, {r10-r11} /* copy to target address [r0] */
cmp r1, r2 /* until source end address [r2] */
blo copy_loop /*
* fix .rel.dyn relocations
* 重定位 .rel.dyn 段
*/
ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */
ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */
fixloop:
ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */
and r1, r1, #0xff
cmp r1, #R_ARM_RELATIVE
bne fixnext /* relative fix: increase location by offset */
add r0, r0, r4
ldr r1, [r0]
add r1, r1, r4
str r1, [r0]
fixnext:
cmp r2, r3
blo fixloop relocate_done: /* ARMv4- don't know bx lr but the assembler fails to see that */ #ifdef __ARM_ARCH_4__
mov pc, lr
#else
bx lr
#endif ENDPROC(relocate_code)

10.1.4 relocate_code 后

  运行C环境,清理 BSS,执行点灯等操作,然后跳转到 board_init_r 中执行第二阶段初始化

 /* Set up final (full) environment */

     bl    c_runtime_cpu_setup    /* we still call old routine here */
#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
ldr r0, =__bss_start /* this is auto-relocated! */ /* 清理 BSS */
#ifdef CONFIG_USE_ARCH_MEMSET
ldr r3, =__bss_end /* this is auto-relocated! */
mov r1, #0x00000000 /* prepare zero to clear BSS */ subs r2, r3, r0 /* r2 = memset len */
bl memset
#endif #if ! defined(CONFIG_SPL_BUILD)
bl coloured_LED_init
bl red_led_on
#endif
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */
/* we should not return here. */
#endif

九、uboot 代码流程分析---relloc_code的更多相关文章

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

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

  2. 十、uboot 代码流程分析---run_main_loop

    调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr void board_init_r(gd_t *new_gd, ulong dest_ ...

  3. 八、uboot 代码流程分析---board_init_f

    接着上一节,板子开始做前期初始化工作. 8.1 board_init_f Board_f.c (common) /* 板子初次初始化.boot_flags = 0 */ void board_init ...

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

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

  5. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  6. [国嵌笔记][030][U-Boot工作流程分析]

    uboot工作流程分析 程序入口 1.打开顶层目录的Makefile,找到目标smdk2440_config的命令中的第三项(smdk2440) 2.进入目录board/samsung/smdk244 ...

  7. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  8. Uboot启动流程分析(三)

    1.前言 在前面的文章Uboot启动流程分析(二)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12002764.html 已经对_main函数的整个大体调用流程 ...

  9. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...

随机推荐

  1. centos7搭建ELK Cluster集群日志分析平台(一):Elasticsearch

    应用场景: ELK实际上是三个工具的集合,ElasticSearch + Logstash + Kibana,这三个工具组合形成了一套实用.易用的监控架构, 很多公司利用它来搭建可视化的海量日志分析平 ...

  2. Kafka学习之路

    一直在思考写一些什么东西作为2017年开篇博客.突然看到一篇<Kafka学习之路>的博文,觉得十分应景,于是决定搬来这“他山之石”.虽然对于Kafka博客我一向坚持原创,不过这篇来自Con ...

  3. HTML5新特性:FileReader 和 FormData

    连接在这里: HTML5新特性:FileReader 和 FormData

  4. C# Winform窗体基础属性

    窗口样式: Inco:改图标样式: MaxmizeBox:true:显示右上角最大化按钮: MinmizeBox:true:显示右上角最小化按钮: ShowInco:true:显示左上角小图标: Sh ...

  5. 洛谷P1712 区间

    题意:给你n个区间,从中选择m个,使得它们有交,且最长与最短区间的差值最小. 解:这道题我想了好多的,nlog²n错的,nlogn错的,最后终于想出nlogn的了...... 把区间按照长度排序,然后 ...

  6. redis设置最大内存

  7. Day013--Python--内置函数一

    一.作用域相关(2) 1. globals()  查看全局空间作用域中的内容. 函数会以字典的类型返回全部全局变量. 2. locals()  查看当前空间作用域中的内容. 函数以字典的类型返回当前位 ...

  8. Good Bye 2018 A. New Year and the Christmas Ornament

    传送门 https://www.cnblogs.com/violet-acmer/p/10201535.html 题解: 这题没什么好说的,读懂题意就会了. 比赛代码: #include<ios ...

  9. echarts柱状图鼠标移动在柱状图上显示数据给数据添加单位

    解决问题: 关键代码如下: tooltip : { trigger: 'axis', formatter:function(params){ return params[0].name+"& ...

  10. jmeter-实用插件

    1.官网下载插件管理工具 https://jmeter-plugins.org/downloads/all/ 2.将jar包放在jmeter的 lib/ext文件夹下 3.重启jmeter 4.点击“ ...