连接器的功能,是将一个可执行程序所需的目标文件和库文件最终整合为一体。一个程序通常包含传统的三个段,.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. [Done]BTrace使用小记

    项目上线,发现集群机器每隔1小时会准时进行fullgc,JMC中显示了System.gc()触发了fullgc: 代码搜了一下自然是搜不到显示调用这个代码的(谁会这么干!拍死!!!)依赖jar包中到是 ...

  2. 各种HTTPS站点的SSL证书 ,扩展SSL证书,密钥交换和身份验证机制汇总

    各种HTTPS站点的SSL证书 ,扩展SSL证书,密钥交换和身份验证机制汇总 一份常见的 HTTPS 站点使用的证书和数据加密技术列表,便于需要时比较参考,将持续加入新的 HTTP 站点,这里给出的信 ...

  3. hibernate4无法保存数据

    hibernate4无法保存数据 author: hiu 以后都发文章我都备注一下作者了,hiu就是我了 红色字体更新日期:2014-07-08 初次使用hibernate4,使用getCurrent ...

  4. 1、简单的BackGroundWorker多线程时时刷新UI界面,并显示进度

    BackGroundWorker是微软提供的封装好了的,非常实用的控件,我们可以在控件中将其拖到Winform之中,然后简单的系统生成代码式的编辑事件处理. 以下是,比较经典且简单的实用,后面的一篇较 ...

  5. java MessageFormat.format

    sql 语句中格式化,如果加入{}占位符,要替代的是整形变量,而恰好这个整形变量的位数超过4位, MessageFormat.format 会在这个整形变量中默认每隔三位加一个逗号,类似这样:1000 ...

  6. ASP.NET中UrlEncode应该用Uri.EscapeDataString()

    今天,茄子_2008反馈他博客中的“C++”标签失效.检查了一下代码,生成链接时用的是HttpUtility.UrlEncode(url),从链接地址获取标签时用的是HttpUtility.UrlDe ...

  7. 使用fork并发处理多个client的请求和对等通信p2p

    一.在前面讲过的回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现.网络服务 ...

  8. Bridge - 桥接模式

    1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度 ...

  9. asp.net2.0导出pdf文件完美解决方案【转载】

    asp.net2.0导出pdf文件完美解决方案 作者:清清月儿 PDF简介:PDF(Portable Document Format)文件格式是Adobe公司开发的电子文件格式.这种文件格式与操作系统 ...

  10. Linux数据库:MYSQL启用和查看二进制日志

    在/etc/my.cnf文件中[mysqld]下加上: server-id = 1 (在整个Mysql集群中保证唯一) log-bin = binlog  log-bin-index = binlog ...