I have searched far and wide for how to do this and have failed to come up with an answer.
我已经广泛搜索了如何做到这一点并未能得出答案。
My memory layout is as follows:
我的内存布局如下:
Fake Address | Section
0 | text
7 | relocate
15 | bss
23 | stack
At the end of the Stack I place the Heap. Which grows up and the stack is a full descending stack for the ARM chip I am using.
在堆栈的末尾我放置堆。它正在成长,堆栈是我正在使用的ARM芯片的完全下降堆栈。
Now, what I want to do is place a single section, let's call it .persist
, into my ram memory. I want it to reside at the very end of RAM and I want to program this into my linker script. However, this .persist
section's size is not defined by me but is computed by the compiler from the symbols that it contains.
现在,我想要做的是放置一个部分,让我们称之为.persist,进入我的ram内存。我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中。但是,此.persist部分的大小不是由我定义的,而是由编译器根据它包含的符号计算的。
So far I've not come up with a good way to do it. Since I know the RAM start address and SIZE it would be trivial to calculate where the section needs to go if I knew the section size. However, according to the GNU linker documentation (pg 74) it seems that:
到目前为止,我还没有想出一个好办法。因为我知道RAM起始地址和SIZE,如果我知道部分大小,那么计算部分需要去的位置是微不足道的。但是,根据GNU链接器文档(第74页),它似乎是:
SIZEOF(section) Returns the size in bytes of the named section, if that section has been allocated. If the section has not been allocated when this is evaluated, the linker will report an error.
SIZEOF(section)如果已分配该部分,则返回指定部分的大小(以字节为单位)。如果在评估此部分时尚未分配该部分,则链接器将报告错误。
so I can't work out the size of the section in the linker script (since I want to calculate the size BEFORE I place it/allocate it).
所以我无法计算出链接器脚本中该部分的大小(因为我想在放置它/分配之前计算大小)。
Does anyone know a good way to do this?
有谁知道这样做的好方法?
4 个解决方案
#1
5
I was able to accomplish something similar by making linking a two-step process. First I compile the section in question to its own object file. In my case I had a metadata section generated from an assembly file. gcc -c
will compile the source into object files, but not link them.
通过连接两个步骤,我能够完成类似的事情。首先,我将有问题的部分编译为自己的目标文件。在我的例子中,我有一个从汇编文件生成的元数据部分。 gcc -c会将源代码编译为目标文件,但不会链接它们。
gcc -c metadata.s -o metadata.o
You could also build your whole program, then extract just the section in question with objcopy
.
您还可以构建整个程序,然后使用objcopy仅提取相关部分。
gcc -c main.cc -o main.o
objcopy --only-section=.metadata main.o metadata.o
Now I build and link the rest of the program, and include the object file among the linker's input.
现在我构建并链接程序的其余部分,并在链接器的输入中包含目标文件。
gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld
The linker reads the section .metadata
from the object file, and I can reference its size in the linker script.
链接器从目标文件中读取.metadata部分,我可以在链接描述文件中引用它的大小。
#2
1
I had a similar problem I did it this way
我有类似的问题,我这样做了
/* heap section */
.heap (NOLOAD):
{
. = ALIGN(8);
_sheap = .;
. = . + HEAP_SIZE;
. = ALIGN(8);
_eheap = .;
} > ram
_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
_stack_size = _ram_end_ - _eheap ;
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + _stack_size;
. = ALIGN(8);
_estack = .;
} > ram
.LastSection (NOLOAD): /* for test in dump file */
{
. = ALIGN(8);
} > ram
#3
0
what I want to do is place a single section, let's call it .persist, into my ram memory. I want it to reside at the very end of RAM and I want to program this into my linker script.
我想要做的是放置一个部分,让我们称之为.persist,进入我的ram记忆。我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中。
Linker script has special variable called Location Counter which allows to modify the current address, and as such the size or address of a section or symbol, by creating gaps or holes in the address space.
链接器脚本具有称为位置计数器的特殊变量,它允许通过在地址空间中创建间隙或孔来修改当前地址,以及部分或符号的大小或地址。
#4
0
You can force sections at specific locations.
您可以在特定位置强制执行部分。
For example in this Red Hat GNU Linker documentation page, you can define the .data section to start at address 0x8000000:
例如,在此Red Hat GNU Linker文档页面中,您可以将.data部分定义为从地址0x8000000开始:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
#1
5
I was able to accomplish something similar by making linking a two-step process. First I compile the section in question to its own object file. In my case I had a metadata section generated from an assembly file. gcc -c
will compile the source into object files, but not link them.
通过连接两个步骤,我能够完成类似的事情。首先,我将有问题的部分编译为自己的目标文件。在我的例子中,我有一个从汇编文件生成的元数据部分。 gcc -c会将源代码编译为目标文件,但不会链接它们。
gcc -c metadata.s -o metadata.o
You could also build your whole program, then extract just the section in question with objcopy
.
您还可以构建整个程序,然后使用objcopy仅提取相关部分。
gcc -c main.cc -o main.o
objcopy --only-section=.metadata main.o metadata.o
Now I build and link the rest of the program, and include the object file among the linker's input.
现在我构建并链接程序的其余部分,并在链接器的输入中包含目标文件。
gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld
The linker reads the section .metadata
from the object file, and I can reference its size in the linker script.
链接器从目标文件中读取.metadata部分,我可以在链接描述文件中引用它的大小。
#2
1
I had a similar problem I did it this way
我有类似的问题,我这样做了
/* heap section */
.heap (NOLOAD):
{
. = ALIGN(8);
_sheap = .;
. = . + HEAP_SIZE;
. = ALIGN(8);
_eheap = .;
} > ram
_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
_stack_size = _ram_end_ - _eheap ;
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + _stack_size;
. = ALIGN(8);
_estack = .;
} > ram
.LastSection (NOLOAD): /* for test in dump file */
{
. = ALIGN(8);
} > ram
#3
0
what I want to do is place a single section, let's call it .persist, into my ram memory. I want it to reside at the very end of RAM and I want to program this into my linker script.
我想要做的是放置一个部分,让我们称之为.persist,进入我的ram记忆。我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中。
Linker script has special variable called Location Counter which allows to modify the current address, and as such the size or address of a section or symbol, by creating gaps or holes in the address space.
链接器脚本具有称为位置计数器的特殊变量,它允许通过在地址空间中创建间隙或孔来修改当前地址,以及部分或符号的大小或地址。
#4
0
You can force sections at specific locations.
您可以在特定位置强制执行部分。
For example in this Red Hat GNU Linker documentation page, you can define the .data section to start at address 0x8000000:
例如,在此Red Hat GNU Linker文档页面中,您可以将.data部分定义为从地址0x8000000开始:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}