【发布时间】:2016-11-15 09:55:12
【问题描述】:
根据ld手册on the special symbol ., i.e.the Location Counter。
注意:.实际上是指从开头的字节偏移量 当前包含对象。通常这是 SECTIONS 语句, 其起始地址为 0,因此 .可以用作绝对地址。 如果 。然而,在章节描述中使用,它指的是 从该部分开始的字节偏移量,而不是绝对地址。 因此在这样的脚本中:
SECTIONS { . = 0x100 .text: { *(.text) . = 0x200 } . = 0x500 .data: { *(.data) . += 0x600 } }“.text”部分将被分配一个 0x100 的起始地址和一个 大小正好为 0x200 字节,即使数据中没有足够的数据 `.text' 输入部分来填充这个区域。
ld 手册也提到了output section's VMA and LMA:
每个可加载或可分配的输出节都有两个地址。这 首先是 VMA,即虚拟内存地址。这是地址 部分将在输出文件运行时具有。第二个是LMA, 或加载内存地址。这是该部分的地址 被加载。在大多数情况下,这两个地址是相同的。一个 它们何时可能不同的示例是数据部分何时 加载到ROM中,然后在程序启动时复制到RAM中 (这种技术通常用于初始化 ROM 中的全局变量 基于系统)。在这种情况下,ROM 地址将是 LMA,而 RAM 地址将是 VMA。
所以我的问题是:
如果输出节指定了不同的 VMA 和 LMA,那么字节偏移量. 的基地址是什么?
在下面的示例中,.data 部分具有不同的 VMA 和 LMA。我的理解是PLACE 1 指定LMA 在ROM2 中,而PLACE 2 指定VMA 在RAM 中?那么.data 部分中. 符号的基地址是什么?
SECTIONS
{
.text :
{
*(.text)
} > REGION_TEXT
.rodata :
{
*(.rodata)
rodata_end = .;
} > REGION_RODATA
.data : AT (rodata_end) <=========== PLACE 1
{
data_start = .;
*(.data)
} > REGION_DATA <=========== PLACE 2
data_size = SIZEOF(.data);
data_load_start = LOADADDR(.data);
.bss :
{
*(.bss)
} > REGION_BSS
}
内存布局如下:
MEMORY
{
ROM : ORIGIN = 0, LENGTH = 2M /*0M ~ 2M*/
ROM2 : ORIGIN = 0x10000000, LENGTH = 1M /*256M ~ 257M*/
RAM : ORIGIN = 0x20000000, LENGTH = 1M /*512M ~ 513M*/
}
REGION_ALIAS("REGION_TEXT", ROM); /*0M ~ 2M*/
REGION_ALIAS("REGION_RODATA", ROM2); /*256M ~ 257M*/
REGION_ALIAS("REGION_DATA", RAM); /*512M ~ 513M*/
REGION_ALIAS("REGION_BSS", RAM); /*512M ~ 513M*/
【问题讨论】: