首先,记住一句话:程序的链接地址必须等于运行地址!

在学习exynos 4412的启动过程时,发现自己对链接地址的作用不是很了解,于是上网查找了资料做了基本了解,在此做个总结。

上图是exynos 4412启动时iROM、BL1和BL2在iRAM中的分布情况。由图中可以看出,BL2会被加载到0x020_3400的起始地址处(由BL1加载),照理来说,在BL2代码编译链接过程中应该将链接地址指定到0x0202_3400才是正确的,但是在实际做led实验(此处BL2的代码功能即是按键控制led亮灭)过程中发现,将链接地址指定为0x0202_0000也照常运行。以下为链接脚本的内容:

SECTIONS
{
. = 0x02020000;  #注:此处正确的链接地址应该为0x0202_3400
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data*) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}

要想明白原因,就得理解链接地址的作用。

先看链接器的作用:

  当链接器进行链接的时候,首先决定各个目标文件在最终可执行文件里的位置。然后访问所有目标文件的地址重定义表,对其中记录的地址进行重定向   (加上一个偏移量,即该编译单元在可执行文件上的起始地址)。然后遍历所有目标文件的未解决符号表,并且在所有的导出符号表里查找匹配的符号,   并在未解决符号表中所记录的位置上填写实现地址。最后把所有的目标文件的内容写在各自的位置上,再作一些另的工作,就生成一个可执行文件。

在上述链接脚本中指定的链接地址,即是告诉链接器将程序的起始地址设置为0x0202_0000,由此,链接器会根据这个设定的起始地址设定程序中位置相关代码的地址。假设链接地址是0x0202_0000,而程序的起始地址实际是在0x0202_3400,当运行位置无关代码时(即要跳转的运行地址为当前PC的值加上一个相对偏移量),CPU可以正确找到程序的存放位置,因此运行不会出错。但是如果存在位置相关代码(即链接时指定好的固定具体地址,非当前PC值加相对偏移量获得的相对地址),那么当CPU跳转到对应的运行地址处运行时,由于实际的代码存放地址运行地址(运行地址由链接时根据链接地址计算得到不同,那么运行就会出错了。

举个例子:假设当将链接地址指定为0x0202_0000,由此生成的可执行程序中有条位置相关代码是 goto 0x0202_1000 ,而实际可执行程序存放在0x0202_3400的起始地址处,那么实际 goto 0x0202_1000 对应的代码就不在0x0202_1000处了,而CPU通过执行 goto 0x0202_1000 跳转到0x0202_1000处,到那里去运行代码,却找不到对应的代码,因此程序运行就出错了。

如果链接地址与程序在内存中的实际存放起始地址不同,当没有位置相关代码时程序运行不会出错,这就是前面说的led程序可以正常运行的原因。但是如果程序中有位置相关代码,那么当运行到位置相关代码时,便会发生错误。

因此,程序的链接地址必须等于运行地址。

关于使用连接器arm-linux-ld时指定链接地址的作用的更多相关文章

  1. gcc编译时指定链接库的查找目录

    gcc编译时,如果需要链接的库的目录不在标准目录,则需要通过将保护库的目录/aa/bb/cc通过-L/aa/bb/cc 添加到搜索路径中,如: gcc -o xmltest xml_test.cpp ...

  2. linux系统启动时更改MAC地址

    vim /etc/rc.local #change the server's MAC address("00:50:56:84:5C:76" change to 00:50:56: ...

  3. linux tar 解压文件时指定文件名

      linux解压文件时指定文件夹名称   wget -O mysql-5.6.15.tar.gz  http://oss.aliyuncs.com/aliyunecs/onekey/mysql/my ...

  4. ARM Linux中断发生时内核堆栈切换

    转载注明出处:http://www.wowotech.net/forum/viewtopic.php?id=54 对ARM Linux中断非常简洁.精确的描述. 发生了中断,最重要的是保存现场,在中断 ...

  5. Linux关机时执行指定脚本

    要实现在Linux关机时执行某个脚本的具体思路 1.在文件夹 /etc/init.d/ 下创建关机时需要执行的脚本 file_name; 2.分别在文件夹 /etc/rc0.d/ 和 /etc/rc6 ...

  6. linux 运行时加载不上动态库 解决方法(转)

    1. 连接和运行时库文件搜索路径到设置     库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的.一般 Linux 系统把 /lib 和 /usr ...

  7. ARM Linux 3.x的设备树(Device Tree)

    http://blog.csdn.net/21cnbao/article/details/8457546 宋宝华 Barry Song <21cnbao@gmail.com> 1.     ...

  8. ARM Linux 3.x的设备树(Device Tree)

    1. ARM Device Tree起源 Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pai ...

  9. sqlite3移植到arm linux

    1,环境: 软件:linux:2.6.38 硬件:6410 交叉编译工具:arm-linux-gcc 也适用于其他linux平台. 2,步骤: 1>下载sqlite3源码包: http://ww ...

随机推荐

  1. 201521123033《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. answer: 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号 ...

  2. 201521123059 《Java程序设计》第十四周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 1.关系型数据库 --建立表格时表中一列中的数据类型必须一致.关系表中的行必须是唯一的,列是不可分的,某些行的某 ...

  3. java购物车系统 团队博客

    1. 团队名称.团队成员介绍(需要有照片) 团队名称:一颗LFL 团队成员:廖余俊 计算机工程学院网络工程1512 学号201521123053 方旭 计算机工程学院网络工程1512 学号201521 ...

  4. 201521123030 《Java程序设计》 第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  5. bootStrap事例代码

    最近在学bootStrap,在慕课网中有这么一个例子-.感觉以后会用到这些代码.保存起来. <!DOCTYPE html> <html lang="zh-cn"& ...

  6. 编译安装Nginx到Linux

    之前安装的H2O不知道为啥,总是崩溃,换Nginx了下载包:http://nginx.org/download/ 配置:./configure --prefix=/usr/local/nginx -- ...

  7. 关于sql语句引发的404错误

    今天分享个小问题,也是今天在项目中遇到的,希望对遇到相关问题的朋友有所帮助. 使用工具:(相关的) mybatis,spring-mvc,mysql 问题原因: 我在mybatis的mapper文件中 ...

  8. angular smart-table组件如何定制化之初步研究

    table表运用在后台管理用得频繁,一般bootstrap的class="table"就能满足样式需求以及分页需求,但是每个产品经理需求不一样,比如说分页:bootstrap分页实 ...

  9. GCD之并行串行区别

    1.用户自定义线程队列,创建时很容易创建 注意创建时的第一个参数:标记值,方便调试查看 1 2 dispatch_queue_t serialqueue=dispatch_queue_create(& ...

  10. Tensorflow之卷积神经网络(CNN)

    前馈神经网络的弊端 前一篇文章介绍过MNIST,是采用的前馈神经网络的结构,这种结构有一个很大的弊端,就是提供的样本必须面面俱到,否则就容易出现预测失败.如下图: 同样是在一个图片中找圆形,如果左边为 ...