GCC (NOLOAD)-指令导致错误的内存映射
GCC (NOLOAD)-directive cause wrong memory mapping
我正在使用 GCC(MIPS)。
这是我的 .ld 文件中的相关部分。
MEMORY
{
MEMORY_1 : ORIGIN = 0xB014D000, N
....
MEMORY_N : ORIGIN = 0x9C00C800, LENGTH = X*K
}
SECTIONS
{
....
.my_section ALIGN(32) (NOLOAD) : { } > MEMORY_1
....
}
在代码处定义全局缓冲区:
static U32 __attribute__((section(".my_section"))) gBuffer[size];
我希望 gBuffer[]
地址在 MEMORY_1
,然而,它的地址是 0x9c0*****
,即 MEMORY_N
。
为什么?我该如何解决?
编辑:
我发现在删除 NOLOAD
指令后,缓冲区位于 MEMORY_1
.
The (NOLOAD) directive will mark a section to not be loaded at run time. The linker will process the section normally, but will mark it so that a program loader will not load it into memory.
我需要在这里使用 (NOLOAD) 指令。对所描述行为的解释是什么?
如何在不将缓冲区移动到意外内存的情况下使用 NOLOAD?
编辑2:
ld 文件将如下所示(根据 Matthias 的建议):
_gBuffer_1 = address(MEMORY_1),
_gBuffer_2 = address(MEMORY_1) + _gBuffer_1_size,
_gbuffer_3 = address(MEMORY_1) + _gBuffer_1_size + _gBuffer_2_size.......
_gBuffer_i_size 必须在 ld 文件中定义。
我的代码和很多部分中有许多这样的缓冲区。
现在,每当有人希望添加新缓冲区或更改现有缓冲区(删除它或更改其大小......)时,他必须通过 ld 文件并重新计算地址,这就是为什么我发现建议的方法不太容易维护.
最初的方法允许定义缓冲区,轻松地将其定位在程序员希望的每个部分,并将其余工作留给添加 (NOLOAD)
指令后引起的 linker.The 问题。
您完全可以避免使用 gcc 属性。只需在链接器文件中提供符号:
_gBuffer = 0xB014D000;
然后你可以将缓冲区声明为 extern:
extern U32 gBuffer[size];
现在,链接器应该将外部声明绑定到给定的地址。
我们刚刚 运行 遇到了同样的问题。我们的解决方法是添加一个额外的间接层:
.my_section_noload ALIGN(32) (NOLOAD) :
{
*(.my_section)
} > MEMORY_1
不知道为什么直接使用它却不起作用。
我正在使用 GCC(MIPS)。 这是我的 .ld 文件中的相关部分。
MEMORY
{
MEMORY_1 : ORIGIN = 0xB014D000, N
....
MEMORY_N : ORIGIN = 0x9C00C800, LENGTH = X*K
}
SECTIONS
{
....
.my_section ALIGN(32) (NOLOAD) : { } > MEMORY_1
....
}
在代码处定义全局缓冲区:
static U32 __attribute__((section(".my_section"))) gBuffer[size];
我希望 gBuffer[]
地址在 MEMORY_1
,然而,它的地址是 0x9c0*****
,即 MEMORY_N
。
为什么?我该如何解决?
编辑:
我发现在删除 NOLOAD
指令后,缓冲区位于 MEMORY_1
.
The (NOLOAD) directive will mark a section to not be loaded at run time. The linker will process the section normally, but will mark it so that a program loader will not load it into memory.
我需要在这里使用 (NOLOAD) 指令。对所描述行为的解释是什么? 如何在不将缓冲区移动到意外内存的情况下使用 NOLOAD?
编辑2: ld 文件将如下所示(根据 Matthias 的建议):
_gBuffer_1 = address(MEMORY_1),
_gBuffer_2 = address(MEMORY_1) + _gBuffer_1_size,
_gbuffer_3 = address(MEMORY_1) + _gBuffer_1_size + _gBuffer_2_size.......
_gBuffer_i_size 必须在 ld 文件中定义。
我的代码和很多部分中有许多这样的缓冲区。
现在,每当有人希望添加新缓冲区或更改现有缓冲区(删除它或更改其大小......)时,他必须通过 ld 文件并重新计算地址,这就是为什么我发现建议的方法不太容易维护.
最初的方法允许定义缓冲区,轻松地将其定位在程序员希望的每个部分,并将其余工作留给添加 (NOLOAD)
指令后引起的 linker.The 问题。
您完全可以避免使用 gcc 属性。只需在链接器文件中提供符号:
_gBuffer = 0xB014D000;
然后你可以将缓冲区声明为 extern:
extern U32 gBuffer[size];
现在,链接器应该将外部声明绑定到给定的地址。
我们刚刚 运行 遇到了同样的问题。我们的解决方法是添加一个额外的间接层:
.my_section_noload ALIGN(32) (NOLOAD) :
{
*(.my_section)
} > MEMORY_1
不知道为什么直接使用它却不起作用。