连接器的功能,是将一个可执行程序所需的目标文件和库文件最终整合为一体。一个程序通常包含传统的三个段,.test, .data, .bss段。连接器的功能就是将各个目标文件个库文件中的三个段进行合并。

重定位的概念

链接而生成的可执行程序虽然是放在文件中的,但当程序运行时需要加载到内存中。各段应该放在内存空间的声明位置是由可执行文件内的头部信息指定的。

一个程序一旦被加载到内存中,就意味着不论函数还是变量,它们都会在内存中占据一定的内存空间,而这关系到内存地址。假设foo()函数在加载到内存中后其地址刚好位于ox10000处,从处理器的角度看,当我们在c程序写下一句调用foo()函数的语句时,意味着在调用foo()函数时需要跳转到ox10000的内存地址处,那如何知道调用foo()函数时应当跳转到ox10000地址处的呢?这就是连接器所需要完成的工作。

链接脚本的功能是告诉连接器,如何将各个不同的目标文件(包括库)中的段合在一起并最终生成一个可执行程序(文件)。从链接脚本的角度来看,一方面它需要描述输出,即最终输出到可执行程序文件中的段;另一方面又要描述输入,即来自各个目标文件中的段。

/*********以下摘自:http://www.cnblogs.com/amanlikethis/p/3344519.html  *********/

1.连接顺序的问题

SECTIONS { 
  firtst   0x00000000 : {head.o init.o nand.o}
  second  x30000000 : AT(4096){ main.o}

这个规则中定义了两个大段,first和second。
first的链接顺序为head.o init.o nand.o. Second的链接顺序为main.o。

2.链接地址的问题

  先说明一下链接地址的概念,链接地址是程序实际运行的地址。通常程序中有位置无关代码和位置有关代码。位置无关代码是对于链接地址无要求,可以在不是它链接地址的地方运行;但是位置有关代码,必须在链接地址运行。也就是说当运行位置有关代码时,程序必须事先在链接地址上,如果没有在,通常需要COPY到那个位置或者利用MMU映射一下。

  下边以一个例子来说明一下链接脚本中链接地址的问题。
 SECTIONS { 
  firtst   0x00000000 : {head.o}
  second 0x00000200 : AT(300) {init.o}
  third  0x00000400 : AT(500) {nand.o}
  fourth  0x30000000 : AT(3096) { main.o}

四个部分:first、second、third、foutth,它们的链接地址分别是0x00000000、0x00000200、0x00000400、0x30000000。

3.加载地址

  加载地址指的是程序编译后的存放地址,通常存放在ROM、FLASH中,所以就是指这段程序在ROM、FLASH中的存放位置。还是以上边的连接脚本为例。

SECTIONS { 
  firtst   0x00000000 : {head.o}
  second 0x00000200 : AT(300) {init.o}
  third  0x00000400 : AT(500) {nand.o}
  fourth  0x30000000 : AT(3096) { main.o}
}

它们的存放地址分别是0、300、500、3096。

/**********摘抄完毕********/

之所以摘抄这一段园友的博客,是因为在2440上,就有这样的链接脚本:

因为之前看关于ld的介绍资料,全是data,bss,test段开头,其实段名是可以自己取得;

SECTIONS { 
firtst 0x00000000 : { head.o init.o } 
second 0x30000000 : AT(4096) { main.o } 
}

    以上,head.o放在0x00000000地址开始处,init.o放在head.o后面,他们的运行地址也是0x00000000,即连接和存储地址相同(没有AT指定);main.o放在4096(0x1000,是AT指定的,存储地址)开始处,但是它的运行地址在0x30000000,运行之前需要从0x1000(加载处)复制到0x30000000(运行处),此过程也就用到了读取Nand flash。

这就是存储地址和连接(运行)地址的不同,称为加载时域和运行时域,可以在.lds连接脚本文件中分别指定。

这里有很多选项,但常用的也就那么一点。关于链接在第六章还有其他一些介绍,但是目前只是为了学习arm板,如果以后在2440上用到了其他功能,再在这里补充。

ld,连接器的更多相关文章

  1. Linux Kernel Makefile Test

    一.本文说明 本文为linux内核Makefile整体分析的续篇,是依据Linux内核Makefile体系的主要内容编写一个简要的测试工程.Linux内核Makefile体系就好像一只“大鸟”,而这篇 ...

  2. GNU工具链学习笔记

    GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...

  3. tiny210——uboot移植Makefile文章分析

    这东西已经写,我们没有时间发布,如今,终于有时间稍微长送记录汇总uboot学习过程.具体了.以后忘了也能够再温习回来嘛有些特殊字符显示得乱掉了 Makefile追踪技巧: 技巧1:能够先从编译目标開始 ...

  4. 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

    一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...

  5. 【转】关于编译链接——gcc/g++

    添加运行时共享库目录 运行使用共享库的程序需要加载共享库(不同于G++ 编译时指定的链接库),添加共享库的步骤: 修改文件 /etc/ld.so.conf 添加共享库目录 运行 ldconfig 同步 ...

  6. ARM GNU常用汇编语言介绍

    ARM GNU常用汇编语言介绍 ARM汇编语言源程序语句,一般由指令,伪操作,宏指令和伪指令组成. ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令. 伪操作,是ARM汇编语言程序里的一些特殊 ...

  7. gcc 学习笔记(一) - 编译C程序 及 编译过程

    一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...

  8. [zhuan]arm中的汇编指令

    http://blog.csdn.net/qqliyunpeng/article/details/45116615 一. 带点的(一般都是ARM GNU伪汇编指令)   1. ".text& ...

  9. ARM中的---汇编指令

    一. 带点的(一般都是ARM GNU伪汇编指令) 1. ".text".".data".".bss" 依次表示的是"以下是代码段& ...

  10. uboot学习之uboot-spl的程序流程分析

    uboot-spl的程序流程主要包含下面的几个函数: _start->reset->save_boot_params->cpu_init_crit->lowlevel_init ...

随机推荐

  1. 〖Linux〗使用Qt5.2.0开发Android的NDK应用程序

    2013年12月11日,Qt发布了其新的Qt版本:Qt5.2.0: 利用这个新的版本,我们可以很轻松地制作出Android手机的NDK应用程序. 开发环境:Ubuntu13.10 x86_64 下载链 ...

  2. 简单的 Helper 封装 -- CookieHelper

    using System; using System.Web; namespace ConsoleApplication5 { /// <summary> /// Cookie 助手 // ...

  3. tar压缩解压

    把所有jpg文件和temp文件夹压缩到 jpg.tar.gz 压缩文件中 tar -czvf  jpg.tar.gz *.jpg  temp 把jpg.tar.gz 解压缩当前文件中 tar -xzv ...

  4. iOS 直播推流 - 搭建基于RTMP的本地Nginx服务器

    前端时间,公司要调研直播相关的内容,特地花时间进行了一番调研. 本篇将记录其中的推流篇-本地推理播放测试. 关于Nginx: 配置Nginx以支持HLS.RTMP的推流与拉流,iOS系统使用LFLiv ...

  5. ubuntu 中数据的迁移

    1.先停止mysql /etc/init.d/mysql stop

  6. .net/c# RabbitMQ 连接断开处理-断线重连(转载)

    Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,就会导致消费者或者生产者挂掉. 下图是生产者发送消息,我手 ...

  7. RHCE7 管理II-2 通过grep使用正则表达式

    grep -i:忽略大小写 -n:表示行数 找出含有root的行 # grep root /etc/passwd root:x:::root:/root:/bin/bash ::operator:/r ...

  8. 轻松搞定面试中的“虚"

    提要 今天要整理的知识点是C++中有关虚的一切. 包括:虚函数,纯虚函数,虚基类,虚继承... 1.什么是虚函数,有什么作用? 在基类用virtual声明成员函数为虚函数.这样就可以在派生类中重新定义 ...

  9. ubuntu的apt-get提示资源被锁定

    一.错误提示 E: Could not : Resource temporarily unavailable) E: Unable to lock the administration directo ...

  10. sqlserver把小数点后面多余的0去掉

    Sql中想把小数点后多余的0去掉,怎么办? select 5000/10000.0 --想变成0.5select 5500/10000.0 --想变成0.55select 5550/10000.0 - ...