non*_*kle 16 c c++ memory linker linker-scripts
我已经广泛搜索了如何做到这一点并且未能得出答案.
我的内存布局如下:
Fake Address | Section
0 | text
7 | relocate
15 | bss
23 | stack
Run Code Online (Sandbox Code Playgroud)
在堆栈的末尾我放置堆.它正在成长,堆栈是我正在使用的ARM芯片的完全下降堆栈.
现在,我想要做的是将一个部分(让我们称之为.persist)放入我的ram内存中.我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中.但是,此.persist部分的大小不是由我定义的,而是由编译器根据它包含的符号计算的.
到目前为止,我还没有想出一个好办法.因为我知道RAM起始地址和SIZE,如果我知道部分大小,那么计算部分需要去的位置是微不足道的.但是,根据GNU链接器文档(第74页),似乎:
SIZEOF(section)如果已分配该节,则返回指定节的大小(以字节为单位).如果在评估此部分时尚未分配该部分,则链接器将报告错误.
所以我无法计算链接器脚本中部分的大小(因为我想在放置它/分配之前计算大小).
有谁知道这样做的好方法?
小智 5
通过连接两个步骤,我能够完成类似的事情.首先,我将有问题的部分编译为自己的目标文件.在我的例子中,我有一个从汇编文件生成的元数据部分.gcc -c将源编译为目标文件,但不链接它们.
gcc -c metadata.s -o metadata.o
Run Code Online (Sandbox Code Playgroud)
您也可以构建整个程序,然后只提取相关部分objcopy.
gcc -c main.cc -o main.o
objcopy --only-section=.metadata main.o metadata.o
Run Code Online (Sandbox Code Playgroud)
现在我构建并链接程序的其余部分,并在链接器的输入中包含目标文件.
gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld
Run Code Online (Sandbox Code Playgroud)
链接器.metadata从目标文件中读取该部分,我可以在链接描述文件中引用它的大小.
小智 5
我设法通过使用链接器命令:size 计算代码的大小来解决这个问题。在我的 Makefile 中,我将 SIZE 设置为代码的大小。然后,我调用 cpp(预处理器)来计算所有绝对地址(使用 c 语法)。然后我使用生成的链接文件进行链接:tmp.ld
%.elf: %.o
$(eval SIZE := $(shell arm-none-eabi-size -B $< | tail -n 1 | awk -F ' ' '{print $$1}'))
$(CC) -DSEG_SIZE=$(SIZE) -P -E -x c link.ld -o tmp.ld
$(CC) -o $@ $< $(LDFLAGS)
Run Code Online (Sandbox Code Playgroud)
在 link.ld 文件中,我可以进行各种计算(因为 SEG_SIZE 是一个常量):
#define SEG_LAST_ADDR 1234
#define MY_SEG (SEG_LAST_ADDR - SEG_SIZE)
MEMORY
{
bootloader (rx) : ORIGIN = MY_SEG, LENGTH = SEG_SIZE
...
}
Run Code Online (Sandbox Code Playgroud)
我终于链接到 tmp.ld 文件。