我怎样才能把一些内存部分放在特定的内存中

How can I put some memory section in particular memory

我试图理解 GCC link 脚本并创建一个小演示来练习,但是我从 ld 得到了 "syntax error"。我感谢任何意见或建议。非常感谢!

hello.c

__attribute__((section(".testsection"))) volatile int testVariable;

hello.ld

MEMORY {
  TEST_SECTION: ORIGIN = 0x43840000 , LENGTH = 0x50    
}
SECTIONS{
.testsection: > TEST_SECTION /* Syntax error here*/
}

编译命令

gcc -T hello.ld -o hello hello.o
c:/gnu/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe:../hello.ld:20: syntax error
collect2.exe: error: ld returned 1 exit status

原版post

MEMORY {
  TEST_SECTION: ORIGIN = 0x43840000 LENGTH = 0x50    
}
SECTIONS{
.testsection: > TEST_SECTION
}

解决方案

MEMORY {
  TEST_SECTION: ORIGIN = 0x43840000, LENGTH = 0x50    
}
SECTIONS{
.testsection: { *(.testsection*) } > TEST_SECTION
}

我认为它缺少两件事。

首先是原始值和 LENGTH 之间的逗号。

第二个部分命令丢失。我不认为 GNU 链接器脚本语法允许这样做,您可能需要在其中放一些东西才能使它有用。你可以试试

.testsection: { } > TEST_SECTION

但我不尝试就猜想你不会在那个记忆中留下任何东西。

编辑

做实验后:

so.s

.text
add r0,r0,r0
add r1,r2,r3
add r1,r1,r1
add r2,r2,r2

so.ld

MEMORY
{
    bob : ORIGIN = 0x30000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .hello : { *(.text*) } > bob
    .world : { } > ted
    .text : { } > ted
}

Disassembly of section .hello:

30000000 <.hello>:
30000000:   e0800000    add r0, r0, r0
30000004:   e0821003    add r1, r2, r3
30000008:   e0811001    add r1, r1, r1
3000000c:   e0822002    add r2, r2, r2

正如我所怀疑的,首先我已经在 MEMORY 中新建了你想要的名称,正如你所看到的,RAM、ROM 等不是特殊名称,如果有的话,不能使用保留名称。我怀疑 SECTIONS 的工作方式与左边的东西相同,是您为输出创建的新名称。这个构建和链接都很好(不是一个真正的程序,显然足以让工具进行演示)。

链接器没有抱怨,但与此同时,由于 ted 中实际上没有放置任何内容,因此输出二进制文件中的内存 space 中也没有放置任何内容。 .hello 和 .text 不必匹配,一个是输出名称,一个是输入名称,通常对于简单的东西人们会让它们匹配,为什么要创建一个新名称。此处仅出于演示目的这样做,以表明在左侧使用相同的名称不会自动将输入部分包含到输出中。

我强烈建议做这样的实验,并使用 readelf 和 objdump 等工具来检查发生了什么(以及阅读脚本语言的文档)。