MDK之程序的编译与链接

MDK之程序的编译与链接

1. 基本概念

  1. 文件
    1. 目标文件:编译后产生的文件称为目标文件,简称ELF(Executable Link-able Format)格式。其包含两个部分:指令代码;编译信息。
    2. 映像文件:目标文件经过链接器生成的文件称为映射文件。这个文件中的程序代码是实际存储后的代码的一个“映射”。
  2. 程序的段
    • 概述

      程序的最基本组成单位是。段分为代码段和数据段等,代码段中可以包含数据,但数据段中不能包含代码。数据分为初始化的数据和未初始化的数据。

      段的属性有3种,只读段RO,可读/写段RW,初始化为0段ZI。

      代码段:只读(READONLU);

      数据段:只读(READONLY),读/写(READWRITE),初始化为0(ZI)。

    • 定义段和定义段的属性

      使用下列语句定义段:

      AREA SECTION-NAME, CODE(或DATA),段属性

      段属性的位置定义段的属性:

        READONLY:只读段,在程序执行中不可改写,可以防止存储区的代码错误改写和丢失。
        READWRITE:读/写段,可以改写,适用于数据存储。
      
    • 输入段和输出段

      输入到链接器的目标文件中的段称为输入段,从链接器输出的到映像文件的段称为输出段
      输入段包含3中属性:RO、RW和ZI,链接器对输入段进行连接处理,把相同属性的段排序连接在一起生成输出段。因此,也有3种属性的输出段,每个输出段包含一个或多个相同属性的输入段。

      如下图所示,输入段经过链接器连接后,生成的输出段最多可有3个,每个属性的输出段只有一个。

      输出段按照规则排列,分配地址后映射到一个物理存储器空间,一般把这个存储器空间称为一个(region)。
      在这里插入图片描述

2. 链接器的基本功能

ARM链接器armlink的基本功能如下:指定映像结构、进行节布局、使用命令行选项创建简单映像。

  1. 指定映像结构

    映像文件是由组成的,一个映射文件可以包含一个或多个域,如下图所示。域由3种输出段组成,每种输出段都是由一个或多个同一属性的输入段组成。输出段是链接器组织连接的基本单位。对于源文件来说,一个源文件中至少包含一个输出段。

    • 输出段的属性共有3种:RO、RW和ZI。链接器把这个3种属性的输出按照RO在前、RW在中间、ZI在后这样的顺序排列组成一个域,这个域内所有段的地址和实际地址一一对应。

    • 加载域和执行域

      映像文件中各段(☞那种段??)的地址有两种:一种是存储器中的地址,这种地址称为加载地址,加载地址就是存储地址,映像文件在存储空间称为加载域;另一种是实际运行时的地址,这种地址称为执行地址,映像文件在执行时的存储空间称为执行域。简单系统而言,加载域和执行域是同一地址。

    • 映像文件入口

      映像文件有两种入口,这些入口是程序运行的起点。一种入口称为初始化入口(initial entry point),这个入口是映像文件最初执行的起始点。一个映像文件的初始点必须是唯一的。

      另一种入口是普通入口(entry point),一般程序员可以不关心普通入口的地址,不为其赋值,普通入口的地址是由链接器自动定义的。

  2. 节点布局

    链接器根据属性在区内排序所有节点。具有相同属性的输入节在区内形成相邻快。每个输入节的基址由链接器定义的排序顺序确定,并且在包含它的输出节正确对齐。生成映像时,链接器按照以下顺序排序输入节:

    • 按属性。
    • 按输入节名称。
    • 按其在输入列表中的位置,除非被FIRST或LAST选项覆盖。
    1. 按属性对输入节排序

      映像部分集合在一起,形成最小数量的相邻区。armlink按以下属性排列输入节:

      1. 只读代码;
      2. 只读数据;
      3. 读/写代码;
      4. 读/写数据;
      5. 初始化数据;

      具有相同属性的输入节按名称排序。名称是区分大小写的,并且使用ASCII字符排序按字母顺序进行比较。属性和名称相同的输入节根据它们在输入列表中的相对位置排序。

    2. 对齐节

      排序输入节之后和修正基址之前,armlink根据需要插入填充,以强制每个输入节的开始地址是输入节对齐的数倍。ARM链接器允许ELF程序头和输出节以4字节为边界对齐,而不管输入节最大队列量。

3. 分散加载描述文件

要构建映射的存储器映射,链接器必须有描述输入节如何分组成区的分组信息以及描述映射区在存储器映射中的放置地址的放置信息。

分散载入机制运行用户为链接器指定映像存储器映射。分散载入提供对映射组件分组和布局的全面控制,能够描述由载入时和执行时分散在存储器映射中的多个区组成的复杂映像映射。

使用场景

  • 复杂的存储器映射:代码和数据需要放在多个不同存储器区域的,必须详细指明将那个存储器空间。
  • 不同存储器类型:许多系统包含闪存存储器、ROM、SDRAM和快速SRAM。分散载入描述可以将代码和数据放置在最合适的存储器类型中。例如,中断代码可以放在快速SRAM中,以改进中断响应时间,而不频繁使用配置信息可能放在较慢的闪存存储器中。
  • 存储器映射I/O:分散载入描述可以将数据节放在存储器映射中的精确地址,便于访问。
  • 位于固定位置的函数:可以将函数放在存储器中的同一个位置,即使周围的应用已经被修改并重新编译。
  • 使用符号识别堆/栈:可以为堆和栈的位置定义符号,链接应用程序时可以指定该封闭模块的位置。

4. 映像文件转换器ELF

fromELF实用程序将ARM链接器生成的可执行可链接格式(ELF)映像文件转换为合适于ROM工具和直接载入存储器的其他格式,还可以使用fromELF显示或打印指定的文本格式的各种信息,或生成包含该信息的文本文件。

fromELF输出以下映像格式:纯二进制格式、Motorla 32S 记录格式、Intel HEX-32格式、面向字节(Verlog存储器模型)十六进制。

fromELF语法格式如下:

fromELF [options] input_file
其中,[options]包含的选项及详细描述如下:
1. --help:显示帮助信息
2. --text:显示文本信息
3. --vsn:显示版本信息	
4. -v:打印详细信息
5. --output file:输出文件(默认的输出文件为文本格式)
6. -a:打印数据地址(针对带调试信息的映像)
7. --nodebug:在生成的映像中不包含调试信息
8. --d:打印数据段的内容
9. --nolinkview:在生成的映像中不包含段信息
10. -e:打印表达式表
11. --bin:生成Plain Binary格式的文件
12. -f:打印消除虚函数的信息
13. --m32:生成Motorola 32位十六进制格式的文件
14. --i32:生成Intel 32位十六进制格式的文件
15. Intel:32
16. --base addr:设置m32、i32格式文件的基地址
17. -g:打印测试表
18. -r:打印重定位信息
19. -t:打印字符串表
20. -y:打印动态段的内容
21. -z:打印代码和数据大小的信息
例子:$K\ARM\ARMCC\bin\fromelf.exe --bin --output=Bin\@L.bin !L?
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值