- 1、本文档共3页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
lds文件浅析.pdf
本文由 Jacky 原创,来自 /u1/58780/showart.php?id=462971
对于.lds 文件,它定义了整个程序编译之后的连接过程,决定了一个可执行程序的各个段的
存储位置。虽然现在我还没怎么用它,但感觉还是挺重要的,有必要了解一下。
先看一下 GNU 官方网站上对.lds 文件形式的完整描述:
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
{ contents } region :phdr =fill
...
}
secname 和 contents 是必须的,其他的都是可选的。下面挑几个常用的看看: 1、secname:
段名
2、contents:决定哪些内容放在本段,可以是整个目标文件,也可以是目标文件中的某段(代
码段、数据段等)
3、start:本段连接(运行)的地址,如果没有使用 AT(ldadr),本段存储的地址也是 start。
GNU 网站上说 start 可以用任意一种描述地址的符号来描述。
4、AT(ldadr):定义本段存储(加载)的地址。
看一个简单的例子:(摘自《2410完全开发》)
/* nand.lds */
SECTIONS {
firtst 0: { head.o init.o }
second 0: AT(4096) { main.o }
}
以上, head.o 放在 0地址开始处, init.o 放在 head.o 后面,他们的运行地址也是
0,即连接和存储地址相同 (没有 AT 指定);main.o 放在 4096(0x1000 ,是 AT 指定的 ,
存储地址 )开始处 ,但是它的 运行地址 在0,运行之前需要从 0x1000(加载处 )复制到
0(运行处 ),此过程也就用到了读取 Nand flash。
这就是存储地址和连接 (运行 )地址的不同 ,称为加载时域和运行时域 ,可以在 .lds 连接脚本文
件中分别指定。
编写好的 .lds 文件,在用 arm-linux-ld 连接命令时带 -Tfilename 来调用执行,如
arm-linux-ld –Tnand.lds x.o y.o–o xy.o。也用 -Ttext 参数直接指定 连接地址 ,如
arm-linux-ld –Ttext 0x.o y.o–o xy.o。
既然程序有了两种地址 ,就涉及到一些跳转指令的区别 ,这里正好写下来 ,以后万一忘记了也可
查看,以前不少东西没记下来现在忘得差不多了 。。。
ARM 汇编中,常有两种跳转方法: b 跳转指令、 ldr 指令向 PC 赋值。
我自己经过归纳如下:
(1)
b step1: b 跳转指令是相对跳转,依赖当前 PC 的值,偏移量是通过 该指令本身 的 bit[23:0] 算出
来的,这使得使用 b 指令的程序不依赖于要跳到的代码的位置,只看指令本身。
(2)
ldr pc, =step1:该指令是从内存中的某个位置 (step1)读出数据并赋给 PC,同样依赖当前 PC 的
值,但是偏移量是那个位置( step1)的 连接地址 (运行时的地址 ),所以可以用它实现从 Flash
到 RAM 的程序跳转。
(3)
此外,有必要回味一下 adr 伪指令, U-boot 中那段 relocate 代码就是通过 adr 实现当前程序是 在
RAM 中还是 flash 中。仍然用我当时的注释:
relocate: /* 把 U-Boot 重新定位到 RAM */
adr r0, _start /* r0是代码的当前位置 */
/* adr 伪指令,汇编器自动通过当前 PC 的值算出 如果执行到_start 时 PC 的值,放到 r0中:
当 此段在 flash 中执行时 r0 = _start = 0;当此段在 RAM 中执行时_start =_TEX
文档评论(0)