arm-linux-ld指令详解_第1页
arm-linux-ld指令详解_第2页
arm-linux-ld指令详解_第3页
arm-linux-ld指令详解_第4页
arm-linux-ld指令详解_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

arm linux ld 指令详解 arm linux ld 指令详解 我们对每个 c 或者汇编文件进行单独编译 但是不去连接 生成很多 o 的文件 这些 o 文件首先是分散的 我们首先 要考虑的如何组合起来 其次 这些 o 文件存在相互调用 的关系 再者 我们最后生成的 bin 文件是要在硬件中运行 的 每一部分放在什么地址都要有仔细的说明 我觉得在 写 makefile 的时候 最为重要的就是 ld 的理解 下面说说 我的经验 首先 要确定我们的程序用没有用到标准的 c 库 或者一些 系统的库文件 这些一般是在操作系统之上开发要注意的 问题 这里并不多说 熟悉在 Linux 编程的人 基本上都会 用 ld 命令 这里 我们从头开始 直接进行汇编语言的连接 我们写一个汇编程序 控制 GPIO 从而控制外接的 LED 代码如下 text global start start LDR R0 0 x56000010 GPBCON 寄存器 MOV R1 0 x00000400 str R1 R0 LDR R0 0 x56000014 MOV R1 0 x00000000 STR R1 R0 MAIN LOOP B MAIN LOOP 代码很简单 就是一个对 io 口进行设置然后写数据 我们 看它是如何编译的 注意我们这里使用的不是 arm linux gcc 而是 arm elf gcc 二者之间没有什么比较大的区别 arm linux gcc 可能包含更多的库文件 在命令行的编译上面是 没有区别 我们来看是如何编译的 arm elf gcc g c o led On o led On s 首先纯编译 不连接 arm elf ld Ttext 0 x00000000 g led On o o led on elf 用 Ttext 指明我们程序存储的地方 这里生成的是 elf 文件 还不是我们真正的 bin 但是可以借助一些工具可 以进行调试 然后 arm elf objcopy O binary S led on elf led on bin 生成 bin 文件 T 选项是 ld 命令中比较重要的一个选项 可以用它直接指 明代码的代码段 数据段 博士生 段 对于复杂的连接 可以专门写一个脚本来告诉编译器 如何连接 Ttext addr Tdata addr Tbss addr arm elf ld Ttext 0 x00000000 g led On o o led on elf 运行地址为 0 x00000000 由于没有指明数据段和 bss 他们 会默认的依次放在后面 相同的代码不同的 Ttext 你可以 对比一下他们之间会变的差异 ld 会自动调整跳转的地址 第二个概念 section section 可以理解成一块 例如像 c 里 面的一个子函数 就是一个 section 链接器 ld 把 object 文 件中的每个 section 都作为一个整体 为其分配运行的地址 memory layout 这个过程就是重定位 relocation 最后把 所有目标文件合并为一个目标文件 链接通过一个 linker script 来控制 这个脚本描述了输入文 件的 sections 到输出文件的映射 以及输出文件的 memory layout 因此 linker 总会使用一个 linker script 如果不特别指定 则使用默认的 script 可以使用 T 命令行选项来指定一 个 linker script 映像文件的输入段与输出段 linker 把多个输入文件合并为一个输出文件 输出文件和输 入文件都是目标文件 object file 输出文件通常被称为可执 行文件 executable 每个目标文件都有一系列 section 输入文件的 section 称为 input section 输出文件的 section 则称为 output section 一个 section 可以是 loadable 的 即输出文件运行时需要将 这样的 section 加载到 memory 类似于 RORW 段 也 可以是 allocatable 的 这样的 section 没有任何内容 某些 时候用 0 对相应的 memory 区域进行初始化 类似于 ZI 段 如果一个 section 既非 loadable 也非 allocatable 则它通常 包含的是调试信息 每个 loadable 或 allocatable 的 output section 都有两个地址 一是 VMA virtual memory address 是该 section 的运行时 域地址 二是 LMA load memory address 是该 section 的 加载时域地址 可以通过 objdump 工具附加 h 选项来查看目标文件中的 sections 简单的 Linker script 1 SECTIONS 命令 The SECTIONS command tells the linker how to map input sections into output sections and how to place the output sections in memory 命令格式如下 SECTIONS sections command sections command 其中 sections command 可以是 ENTRY 命令 符号赋值 输 出段描述 也可以是 overlay 描述 2 地址计数器 location counter 该符号只能用于 SECTIONS 命令内部 初始值为 0 可 以对该符号进行赋值 也可以使用该符号进行计算或赋值 给其他符号 它会自动根据 SECTIONS 命令内部所描述的 输出段的大小来计算当前的地址 3 输出段描述 output section description 前面提到在 SECTIONS 命令中可以作输出段描述 描述的 格式如下 section address type AT lma output section command output section command region ATlma region phdr phdr fillexp 很多附加选项是用不到的 其中的 output section command 又可以是符号赋值 输入段描述 要直接包含的数据值 或者某一特定的输出段关键字 linker script 实例 OUTPUT ARCH arm ENTRY start SECTIONS 0 xa3f00000 boot start start ALIGN 4 text start setup ALIGN 4 setup block setup setup block end text ALIGN 4 text rodata ALIGN 4 rodata data ALIGN 4 data got ALIGN 4 got boot end bss ALIGN 16 bss start bss COMMON bss end comment ALIGN 16 comment stack point boot start 0 x00100000 loader size boot end boot start setup size setup block end setup block 在 SECTIONS 命令中的类似于下面的描述结构就是输出段 描述 start ALIGN 4 text start start 为 output section name ALIGN 4 返回一个基于 location counter 的 4 字节对齐的地址值 text start 是输 入段描述 为通配符 意思是把所有被链接的 object 文件 中的 text start 段都链接进这个名为 start 的输出段 源文件中所标识的 section 及其属性实际上就是对输入段的 描述 例如 text start 输入段在源文件 start S 中的代码如下 section text start global start start b start arm elf ld Ttimer lds o timer elf header o 这里就必须存在一个 timer lds 的文件 对于 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 定义本段存储 加载 的地址 nand lds SECTIONS firtst 0 x00000000 head o init o second 0 x30000000 AT 4096 main o 以上 head o 放在 0 x00000000 地址开始处 init o 放在 head o 后面 他们的运行地址也是 0 x00000000 即连接和 存储地址相同 没有 AT 指定 main o 放在 4096 0 x1000 是 AT 指定的 存储地址 开始处 但是它 的运行地址在 0 x30000000 运行之前需要从 0 x1000 加载 处 复制到 0 x30000000 运行处 此过程也就用到了读取 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 0 x30000000 x o y o o xy o 既然程序有了两种地址 就涉及到一些跳转指令的区别 这里正好写下来 以后万一忘记了也可查看 以前不少东 西没记下来现在忘得差不多了 ARM 汇编中 常有两种跳转方法 b 跳转指令 ldr 指令向 PC 赋值 我自己经过归纳如下 b step1 b 跳转指令是相对跳转 依赖当前 PC 的值 偏移 量是通过该指令本身的 bit 23 0 算出来的 这使得使用 b 指 令的程序不依赖于要跳到的代码的位置 只看指令本身 ldr pc step1 该指令是从内存中的某个位置 step1 读 出数据并赋给 PC 同样依赖当前 PC 的值 但是偏移量是 那个位置 step1 的连接地址 运行时的地址 所以可以 用它实现从 Flash 到 RAM 的程序跳转 此外 有必要回味一下 adr 伪指令 U boot 中那段 relocate 代码就是通过 adr 实现当前程序是在 RAM 中还是 flash 中 仍然用我当时的注释 adr r0 start r0 是代码的当前位置 adr 伪指令 汇编器自动通过当前 PC 的值算出 如果执行 到 start 时 PC 的值 放到 r0 中 当此段在 flash 中执行时 r0 start 0 当此段在 RAM 中 执行时 start TEXT BASE 在 board smdk2410 config mk 中指定的值为 0 x33F80000 即 u boot 在把代码拷贝到 RAM 中去执行的代码段的开始 ldr r1 TEXT BASE 测试判断是从 Flash 启动 还是 RAM 此句执行的结果 r1 始终是 0 x33FF80000 因为此值是又 编译器指定的 ads 中设置 或 D 设置编译器参数 cmp r0 r1 比较 r0 和 r1 调试的时候不要执行重定 位 下面 结合 u boot lds 看看一个正式的连接脚本文件 这个文件的基本功能还能看明白 虽然上面分析了好多 但其中那些 GNU 风格的符号还是着实让我感到迷惑 OUTPUT FORMAT elf32shy littlearm elf32shy littlearm elf32shy littlearm 指定输出可执行文件是 elf 格式 32 位 ARM 指令 小端 OUTPUT ARCH arm 指定输出可执行文件的平台为 ARM ENTRY start 指定输出可执行文件的起始代码段为 start SECTIONS 0 x00000000 从 0 x0 位置开始 ALIGN 4 代码以 4 字节对齐 text 指定代码段 cpu arm920t start o text 代码的第一个代码部 分 text 其它代码部分 ALIGN 4 rodata rodata 指定只读数据段 ALIGN 4 data data 指定读 写数据段 ALIGN 4 got got

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论