我工作的一个嵌入式程序,我有一个自定义链接脚本。 该项目工程,但我注意到,有可能是什么不对劲的连接是如何放置两节在内存中。
以下是链接描述文件的相关部分:
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
...
}
这里是映射文件的相关部分:
.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和被加载到ROM .STACK? 我一定要改变的.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如何生成的地图输出文件中的错误?
另请参见: 了解GNU链接脚本的位置计数器