一 section是什么?
好吧,我们需要解释一下平时编译链接生成的二进制可执行程序(比如说ELF,EXE也行),so或者dll,内核(非压缩的,参加本系列第一节内容、vmlinux),或者ko是怎么组织的。
其实,大家或多或少都知道这些二进制中包括有什么text/bss/data节(也叫section)。text节存储的是代码、data存储的是已经初始化的静态变量、bss节存储的是未初始化的什么东西...
上面的东西我就不细究了。反正一点,一个二进制,最终会包含很多section。那么,为什么section叫text/bss/data,能叫别的名字吗?
OK,可以。但是你得告诉ld,那么这些内容就通过-T选项指定一个linker script就行了。这些内容我们放到后面的实例中来介绍。
二 link script基础知识介绍
linker script中的语法是linker command language(很简单的language,大家不用害怕...)。那么LS的目的是什么呢?
  • LS描述输入文件(也就是gcc -c命令产生的.o文件即object文件)中的section最终如何对应到一个输出文件。这个其实好理解,例如一个elf由三个.o文件构成,每个.o文件都有text/data/bss段,但最终的那一个elf就会将三个输入的.o文件的段合并到一起。
好了,下面我们介绍一些基本知识:
  • ld的功能是将input文件组装成一个output文件。这些文件内部的都有特殊的组织结构,这种结构被叫做object file format。每一个文件叫做object file(这可能就是.o文件的来历吧。哈哈),输出文件也叫可执行文件(an executable),但是对于ld来说,它也是一种object文件。那么Object文件有什么特殊的地方呢?恩,它内部组织是按照section(段、或者节,以后不再区分二者)来组织的。一句话,object文件内部包含段......
  • 每个段都有名字和size。另外,段内部还包含一些数据,这些数据叫做section contents,以后称段内容。每个段有不同的属性。例如text段标志为可加载(loadable),表示该段内的contents在运行时候(当然指输出文件执行的时候)需要加载到内存中。另外一些段中没有contents,那么这些段标示为allocatable,即需要分配一些内存(有时候这些内存会被初始化成0,这里说的应该是BSS段。BSS段在二进制文件中没有占据空间,即磁盘上二进制文件的大小比较小,但是加载到内存后,需要为BSS段分配内存空间。),还有一些段属于debug的,这里包含一些debug信息。
  • 既然需要加载到内存中,那么加载到内存的地址是什么呢?loadable和allocable的段都有两个地址,VMA:虚拟地址,即程序运行时候的地址,例如把text段的VMA首地址设置为0x800000000,那么运行时候的首地址就是这个了。另外还有一个LMA,即Load memory address。这个地址是section加载时的地址。晕了吧?二者有啥区别?一般情况下,VMA=LMA。但也有例外。例如设置某数据段的LMA在ROM中(即加载的时候拷贝到ROM中),运行的时候拷贝到RAM中,这样LMA和VMA就不同了。---------》很难搞懂不是?这种方法用于初始化一些全局变量,基于那种ROM based system。(问一个问题,run的时候,怎么根据section中的VMA进行相应设置啊??以后可能需要研究下内核中关于execve实现方面的内容了)。关于VMA和LMA,大家通过objdump -h选项可以查看
三 简单例子
下面来一个简单例子,

 SECTIONS

{
       . = 0x10000;
       .text : { *(.text) }
       . = 0x8000000;
       .data : { *(.data) }
       .bss : { *(.bss) }
 }


  • SECTIONS是LS语法中的关键command,它用来描述输出文件的内存布局。例如上例中就含text/data/bss三个部分(实际上text/data/bss才是段,但是SECTIONS这个词在LS中是一个command,希望各位看官要明白)。
  • .=0x10000; 其中的.非常关键,它代表location counter(LC)。意思是.text段的开始设置在0x10000处。这个LC应该指的是LMA,但大多数情况下VMA=LMA。
  • .text:{*(.text)},这个表示输出文件的.text段内容由所有输入文件(*)的.text段组成。组成顺序就是ld命令中输入文件的顺序,例如1.obj,2.obj......
  • 此后,由来了一个.=0x800000000;。如果没有这个赋值的,那么LC应该等于0x10000+sizeof(text段),即LC如果不强制指定的话,它默认就是上一次的LC+中间section的长度。还好,这里强制指定LC=0X800000000.表明后面的.data段的开始位于这个地址。
  • .data和后面的.bss表示分别有输入文件的.data和.bss段构成。
你看,我们从这个LC文件中学到了什么?
恩,我们可以任意设置各个段的LMA值。当然,绝大部分情况,我们不需要有自己的LS来控制输出文件的内存布局。不过LK(linux kernel)可不一样了......

linkscrpit的更多相关文章

随机推荐

  1. Python的传值和传址与copy和deepcopy

    1.传值和传址 传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针).他们的区别是如果函数里面对传入的参数重新赋值,函数外的全局变量是否相应改变,用传值传入的参数是不会 ...

  2. c语言的一些基础知识

    c语言作为经典语言,这里不再多说了.咱从基础一起探讨吧! 一. 定义一个整型,如果作为局部变量,没有初始化的情况下,它是一个随机的值的,一般情况下输出会是0,但这个0是作为垃圾值的;而如果作为全局变量 ...

  3. 洛谷 P1541 乌龟棋

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  4. 25个App免费资源网站

    不少非常优秀的设计师已经在网络分享了很多出色的图标.界面 PSD 文件,再加上其他一些相关资源,设计 iOS 应用更加方便了. 模板 & PSDs  Icon Template Michael ...

  5. bug - colorWithPatternImage:

    // 在ios5之前, 再通过以下方法设置背景时, 有闪屏bug self.view.backgroundColor = [UIColor colorWithPatternImage:<#(no ...

  6. PHP漏洞全解(九)-文件上传漏洞

    本文主要介绍针对PHP网站文件上传漏洞.由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件,并能够将这些文件传递给 P ...

  7. MyBatis动态SQL语法

    [注:摘自MyBatis官网 ] 1.动态SQL的元素: if choose (when, otherwise) trim (where, set) foreach bind 2.if语句:   &l ...

  8. android 业务需求: 先干掉自己, 在重启自己

    // 重启应用 public void restartApp() { Intent intent = new Intent(); // 参数1:包名,参数2:程序入口的activity intent. ...

  9. DHTMLX 前端框架 建立你的一个应用程序 教程(八)-- 添加表单Form

    添加表单Form 我们下一步是在页面中添加一个表单,表格中的选中字段将会显示在表单中.提供一个提交按钮 可以对显示的数据进行修改提交. 添加表单到布局单元格中 1.在右侧布局中使用attachForm ...

  10. ANDROID_MARS学习笔记_S01原始版_015_Socket

    一.代码1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...