GNU linker ld —— Basic Linker Script Concepts

GNU linker ld (GNU Binutils) version 2.42 —— Linker Scripts:Basic Linker Script Concepts

个人笔记,仅供参考!!

链接器负责将输入文件合并成一个单一的输出文件。输出文件和每个输入文件都采用一种特定的数据格式,称为对象文件格式。每个文件被称为一个对象文件

每个文件被称为一个对象文件。输出文件一般被称为可执行文件,但这里也将其称为对象文件。

每个对象文件都包含有一个段(section)列表。这里将输入文件中的一个段称为输入段;类似地,输出文件中的一个段称为输出段。可以通过objdump -h来查看对象文件中的段。

对象文件中的每个段有名称和大小。大多数段通常有一个相关的数据块,称为段内容。一个段可能被标记为可加载的(loadable),这意味着当输出文件运行时,内容应该被加载到内存中。一个没有内容的段可能是可分配的(allocatable),这意味着应该在内存中预留一个区域,但不特别加载任何内容(在某些情况下,这部分内存必须被清零)。既不可加载也不可分配的部分通常包含某种调试信息。

每个可加载或可分配的输出段都有两个地址。第一个是VMA,即虚拟内存地址。这是输出文件运行时该部分将拥有的地址。第二个是LMA,即加载内存地址,这是该部分将被加载的地址。

每个对象文件还有一个符号列。一个符号可能是已定义的或未定义的。每个符号都有一个名称,每个已定义的符号除了其他信息外,还有一个地址。在C/C++中,每个已定义的函数和全局/静态变量就是一个已定义的符号。输入文件中引用的每个未定义的函数或全局变量将成为一个未定义的符号。 可以通过nm工具来查看对象文件中的符号表。

关于LMA 和 VMA,对嵌入式C程序,一般有:
程序代码(存储在Flash中):

  • LMA:代码存储在Flash中的物理地址。
  • VMA:当程序运行时,代码应该在内存中的地址。如果代码直接在Flash中执行,那么LMA和VMA是相同的。

从Flash拷贝到RAM中执行的代码:

  • LMA:代码在Flash中的物理存储地址。
  • VMA:代码在RAM中执行时的地址。在这种情况下,LMA是Flash地址,VMA是RAM地址。

有初始值的数据(初始化的全局变量):

  • LMA:数据在Flash中的物理存储地址,因为它们有初始值,通常会存储在程序的只读段中。
  • VMA:数据在程序运行时应该出现在RAM中的地址。在启动时,这些数据会从Flash复制到RAM。

没有初始值的数据(未初始化的全局变量):

  • LMA:通常不适用,因为这些数据不会占用Flash存储空间。
  • VMA:这些数据在RAM中分配的地址。在程序启动时,这部分RAM通常会被清零。

参考连接:

【1】https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html