Linker Script - Placing a section at the end of a memory region

北城余情 提交于 2019-11-30 02:02:13

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  metadata.s  -o metadata.o

You could also build your whole program, then extract just the section in question with 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.

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
Magnus Persson

I managed to solve it by calculating the size of the code by using the linker command: size. In my Makefile i set SIZE to the size of the code. I then call cpp (the preprocessor) to calculate all absolute addresses (using c-syntax). I then link using the generated linkfile: 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)

In the link.ld-file i can do all kinds of calculations (as SEG_SIZE is a constant):

#define SEG_LAST_ADDR 1234
#define MY_SEG        (SEG_LAST_ADDR - SEG_SIZE)

MEMORY
{
  bootloader     (rx)  : ORIGIN = MY_SEG,     LENGTH = SEG_SIZE
  ...
}

I finally link against the tmp.ld-file.

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:

SECTIONS
{
  . = 0x10000;
  .text : { *(.text) }
  . = 0x8000000;
  .data : { *(.data) }
  .bss : { *(.bss) }
}

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!