【发布时间】:2013-01-22 08:01:27
【问题描述】:
我正在开发一个嵌入式程序,其中有一个自定义链接器脚本。该程序可以运行,但我注意到链接器在内存中放置几个部分的方式可能有问题。
以下是链接描述文件的相关部分:
MEMORY {
ROM (rx) : ORIGIN = 0x00100000, LENGTH = 16k
RAM (rwx) : ORIGIN = 0x00200000, LENGTH = 4k
}
SECTIONS {
/* Other sections go here. */
.data : {
...
} >RAM AT>ROM
.bss : {
...
} >RAM
.stack : {
...
} >RAM
...
}
这是 MAP 文件的相关部分:
.data 0x00200040 0x0 load address 0x001003d4
0x001003d4 __data_load = LOADADDR (.data)
0x00200040 __data_start = .
*(.data)
*(.data*)
0x00200040 . = ALIGN (0x4)
0x00200040 _edata = .
.igot.plt 0x00200040 0x0 load address 0x001003d4
.igot.plt 0x00000000 0x0 ./debug/sam7s_startup.o
.bss 0x00200040 0x0 load address 0x001003d4
0x00200040 __bss_start__ = .
*(.bss)
*(.bss*)
*(COMMON)
0x00200040 . = ALIGN (0x4)
0x00200040 _ebss = .
0x00200040 __bss_end__ = .
0x00200040 PROVIDE (end, _ebss)
0x00200040 PROVIDE (_end, _ebss)
0x00200040 PROVIDE (__end__, _ebss)
.stack 0x00200040 0x200 load address 0x001003d4
0x00200040 __stack_start__ = .
所以从映射文件来看,我认为 .bss 和 .stack 部分正在 ROM 中获取加载地址。我认为这是因为这两行:
.bss 0x00200040 0x0 load address 0x001003d4.stack 0x00200040 0x200 load address 0x001003d4
这不好,因为它们占用 ROM 中的空间是没有意义的。 .bss 部分虽然现在为空,但将包含未初始化的全局变量,这些变量将在代码中设置为零。堆栈也只是将在代码中初始化的 RAM 的一部分。所以这两个部分都没有必要占用 ROM 中的空间。
所以我的问题是,阻止 .bss 和 .stack 加载到 ROM 中的正确方法是什么?我是否必须将 .bss 和 .stack 部分的末尾从 >RAM 更改为 >RAM AT>RAM?这似乎有点多余。
在测试了一些东西后,我发现了以下内容:
(1) 使用(NOLOAD) 属性(例如,将.stack : 替换为.stack (NOLOAD) :)仍会导致映射文件显示.stack 和.bss 部分的ROM 加载地址。
(2) 如上所述,指定 RAM AT>RAM 确实会阻止映射输出显示 .stack 和 .bss 部分的 ROM 加载地址。
(3) 当映射文件显示 .bss 和 .stack 部分的加载地址时,看起来它们实际上并没有占用 ROM 中的空间。 .stack 部分虽然有 0x200 字节长,但似乎并没有真正占用 ROM 中的空间,即使我为它指定填充值并在链接描述文件中在它之后放置一个部分。链接描述文件中跟随它的部分不会随着不同的堆栈大小移动。
所以也许映射文件输出并不意味着我认为的意思,并且 .stack 和 .bss 部分实际上根本没有在 ROM 中获得加载地址。在尝试了一些东西之后,它肯定会出现这种方式。知道为什么映射输出使它看起来好像这些部分被赋予了 ROM 加载地址仍然会很有趣,尤其是在使用 (NOLOAD) 时。这可能只是 LD 生成地图输出文件的一个错误吗?
另请参阅:Understanding the Location Counter of GNU Linker Scripts
【问题讨论】:
-
总结一下: - 来自 YAGARTO 工具链的 binutils 版本 2.23.1 - 使用
NOLOAD对地图文件没有任何影响。我使用NOLOAD,只需在链接器脚本中将.bss :替换为.bss (NOLOAD) :并将.stack :替换为.stack (NOLOAD) :。 - 你在堆栈之后放置一个部分是正确的。我将 .text 部分移到那里,堆栈没有占用任何加载空间。 - 是的,整个问题都是关于地图输出的。它向我表明链接器正试图在 ROM 中为 .bss 和 .stack 提供一个加载地址(尽管我们刚刚发现这实际上并没有发生)。 -
我也尝试过整理问题