参考自:https://www.cnblogs.com/Cqlismy/p/12152400.html
必看。这个老哥写的uboot启动的博客非常棒,感谢。
还有https://blog.csdn.net/luciferful/article/details/9371891
还有正点原子uboot相关内容。

自己总结心得如下:
以前看过的老版本的UBOOT(包括2440和朱老师的S5PV210)是没有这样的,而是遵循裸机规矩:运行地址必须等于链接地址。
可是最近看的imx6ull的uboot中,代码原本已经被内部rom根据SD卡启动时的头部信息给复制到sdram中了,为什么还要再有一次代码搬移呢???而且代码是从链接地址搬移到一个别的地址去了,运行地址就不等于链接地址了,为什么呢?

我们关注两点就行了:目的和实现手法。

目的据说是,把uboot移动到更高地址的内存中去,靠近sdram的顶端,为kernel腾出空间,防止kernel解压覆盖UBOOT。
可是引导内核后uboot不就没用了吗???为什么怕干扰??

怎么实现的呢?
怎么做到运行地址和链接地址不同就仍然可以正常运行??
(而且还是用的位置相关的代码,用到了全局变量等等。)
关键有两点:
一、就在于在使用 ld 进行链接的时候使用选项“-pie”生成位置无关的可执行文件。在文件
arch/arm/config.mk 下有如下代码: LDFLAGS_u-boot += -pie。
编译时就可以看到下面这样的动作信息:

而且在编译脚本中也加入了新的段 .rel.dyn 作为配合。

一旦用了这种手段之后,生成的汇编代码中就可以看到:就不是直接去一个很远的地址取需要的内容了,而是代码哪里用到了绝对地址,就在就近处(pc+8,pc+12)存个地址值,也就是有个中间层,中间层是PC的相对地址得到,那后得到的值是一个绝对地址,再访问这个地址就能得到想要的变量。
不过中间的这个地址的值,以及这个值为地址的真正的变量值是我们要修改的。

二、在代码搬运的代码后面要对.rel.dyn 段的内容进行处理,相关内容统一加上一个offset。然后把原变量的值写到新的地址去就好了。
最后效果就是寻址的地址都是在高处的那部分了。
“PC近处”的地址存的是变量的地址,这个“近处的地址”由原地址(也就是.rel段得到)加上补偿差值就有了,然后这个“近处的地址”里面的内容也要加上这个补偿值,就是重定位之后的变量的地址了。
代码不用变,仍然是通过“近处的地址”(也就是个PC的相对地址)里面的值(是个绝对地址值,不过我们已经变过其的值了),去到其对应的远处的地址就能得到原来的变量的值了。

补充:
.text :
{
*(.__image_copy_start) #这是什么意思呢??一个不占用空间的东西
(.vectors)
arch/arm/cpu/armv7/start.o (.text
)
(.text)
}

char __image_copy_start[0] attribute((section(".__image_copy_start")));
不占内存空间,可在u-boot镜像开始位置生成标签__image_copy_start。
在汇编中就可以直接用__image_copy_start这个标签了,其实和.vector开始的__start这个标签的值是一样的。

或者下面这里我估计也是类似的:
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
(.rel)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}

uboot为什么要重定位/代码拷贝?相关推荐

  1. uboot重定位代码分析(转)

    概述 重定位(relocate)代码将BootLoader自身由Flash复制到SDRAM,以便跳转到SDRAM执行.之所以需要进行重定位是因为在Flash中执行速度比较慢,而系统复位后总是从0x00 ...

  2. Tiny6410之重定位代码到SRAM+4096

    重定位代码 两个不同的地址概念: 对于程序而言,需要理解两个地址,一个是程序当前所处的地址,即程序运行时所处的当前地址.二是程序应该位于的运行地址,即编译程序时所指定的程序的链接地址.在Tiny641 ...

  3. tiny4412 裸机程序 七、重定位代码到DRAM【转】

    本文转载自:http://blog.csdn.net/eshing/article/details/37116637 一.关于DRAM 上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有25 ...

  4. Tiny6410之重定位代码到SDRAM

    在上一章中,将代码重定位到了SRAM中,但是这样的做法作用不大.正确的做法的是将代码重定位到更大的主存中,即DRAM.Tiny6410的DRAM控制寄存器最多只能支持两个同一类型的芯片.每个芯片最多可 ...

  5. tiny4412 裸机程序 六、重定位代码到IRAM+0x8000【转】

    本文转载自:http://blog.csdn.net/eshing/article/details/37115697 一.重定向 对于程序而言,我们需要理解两个概念,一是程序当前所处的地址,即程序在运 ...

  6. tiny4412 裸机程序 六、重定位代码到IRAM+0x8000

    一.重定向 对于程序而言,我们需要理解两个概念,一是程序当前所处的地址,即程序在运行时,所处的当前地址:二是程序的链接地址,即程序运行时应该位于的运行地址.编译程序时,可以指定程序的链接地址.对于Ti ...

  7. 重定位代码Repair

    此类指令都为6个字节 大致试验结果如下: 第一个字节跟操作类型相关,第二个字节跟寄存器相关,后面四个字节为地址 第二个字节高四位必须为8,9,A,B四个中的一个,低四位必为5和D中的一个,产生8种排列 ...

  8. S5PV210体系结构与接口04:代码重定位 SDRAM初始化

    目录 1. C语言环境初始化 1.1 C语言运行所需环境 1.2 初始化栈 1.2.1 栈的概念 1.2.2 栈的作用 1.2.3 如何初始化 1.3 初始化bss段 1.3.1 bss段的作用 1. ...

  9. U-Boot的重定位实现机制

    获取当前芯片平台的相关信息 为了深入了解ARM 64位芯片架构,笔者为u-boot添加了archinfo命令,以获取CPU当前的工作状态等信息.不过在增加完整的64位ARM架构信息查看功能之前,笔者首 ...

最新文章

  1. nginx配置文件+本地测试请求转发到远程服务器+集群
  2. 初学者:如何使用虚拟PC将Windows 7安装到虚拟机
  3. Ubuntu扩展触摸屏触控错位修复
  4. git新建分支并且在切换分支开发
  5. 局部变量 和 全局变量
  6. 为增强软件供应链安全,NIST 发布《开发者软件验证最低标准指南》
  7. 图片切换ajax,jQuery AJAX全屏图文幻灯切换
  8. 费马定理中值定理_长盛不衰的法国数学|费马
  9. cmd命令行把bat或exe执行为windows服务
  10. 学3D建模需要什么基础?
  11. 离线浏览工具webdup 可下载网站页面
  12. 逻辑设计基础_第2周-布尔代数及表达式化简
  13. 全球及中国智能手机过滤器行业销售动态及投资盈利预测报告(2022-2027)
  14. 算法 洗扑克牌(乱数排列)
  15. 历年世界10大经济体及GDP列表
  16. 【C语言】求s=1+(1+2)+(1+2+3)+....+(1+2+3+....+n)值
  17. 【2020.10.29 洛谷团队赛 普及组】T2 U138014 魔法药水
  18. mysql主备方案_Mysql 主备双库方案
  19. python-OpenCV图像处理常用函数汇总(三)
  20. 人大金仓数据Windows安装教程

热门文章

  1. windows 10:安装PDFtk server后,查验时提示——‘pdftk‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
  2. OSD(On Screen Display )技术(转)
  3. chmod chown
  4. 上帝模式,,即God Mode”,或称为“完全控制面板”
  5. H3C华三S7506E系列交换机万兆IRF堆叠虚拟化
  6. iis6 php mysql 一键_一键搞定:php5 环境集成安装包 for IIS6 修正版
  7. 指尖江湖李忘生鸿蒙初开,剑网3指尖江湖李忘生PVP秘籍搭配方法
  8. Windows软件卸载不干净或异常导致无法重装的解决方案
  9. 使用zlib库解压*.zip文件
  10. 游戏开发中的多语言文本管理