linker scripts

Sep 25, 2006 5 Replies

Hi,



Does anyone have a very good link for playing around with linker scripts ? Linker scripts links that really drives me crazy !!



I have some links, but they are very normal and minimal in their speech . :) No Fun :)



Tonnes of Thx in advans, Karthik Balaguru



If you're using the GNU tools, the ld manual is the reference .

An example of a Flash/RAM setup (for an embedded ARM):

---

/* Linker script for Flash-run startup in AT91R40008 ARM */ /* version 1.10, 5.2.2004, Tauno Voipio */

ENTRY(_start)

/* Memory regions, AT91R40008 */

__ram_loc__ = 0x100; /* start of RAM (internal) */ __ram_top__ = 256K; /* just past all RAM */

MEMORY { ram : org = 0x100, len = 256K-0x100 /* RAM */

low_ram : org = 0x00300000, len = 8K /* RAM during boot */

rom : org = 0x01000000, len = 2048K /* Flash ROM at NCS0 */ enet : org = 0x02000000, len = 512K /* Ethernet at CS1 */ }

/* Section location */

SECTIONS { .text : { __text_start__ = . ; *(.boot); *(.ident); *(.init); *(.text); *(.glue_7t); *(.glue_7); *(.rodata*); *(.fini); etext = . ; . = ALIGN(4); } > rom

__data_rom__ = ADDR(.text) + SIZEOF(.text);

.data : AT(__data_rom__) { __data_start__ = . ; *(noflash); *(.data); . = ALIGN(4); } > ram

__data_length__ = SIZEOF(.data);

.bss : { __bss_start__ = . ; *(.bss); *(COMMON) . = ALIGN(4); __bss_end__ = . , } > ram

__bss_length__ = SIZEOF(.bss); }

---

HTH

--

Tauno Voipio tauno voipio (at) iki fi

I am trying to figure out how to get symbols defined in a linker script back into the program. Any time I see constants defined like (and in the same linker.ld file):

"__ram_loc__ = 0x100; /* start of RAM (internal) */" "ram : org = 0x100, len = 256K-0x100 "

I get a strong urge to make sure they are not defined elsewhere in the system. I mean, could not ram have been defined in relation to __RAM_LOC__ instead of another magic number?

I firmly believe that definitions worth making should only be done once. Way to often I see a linker script with constants and then program header files with constants refering to the same area. This makes changes to the platform hardware tricky and error prone.

I guess --defsym symbol=expression passed to the linker is an option, but now a 3rd file is involved with setting up a system (the makefile). I prefer to have some kind of config file that contains all configuration options and magic constants for a particular system.

Do you have any suggestions for getting linker symbols into the linked program?

Regards, Steve

There is no "x" in my email address.

The symbols are there as assembler .globl's or C extrn's, but remember that the tool chain handles the numbers as addresses.

Here's a piece using the symbols from above to create an ARM toolkit absolute binary header for a file type called .axf:

.psize 40,110

@ aifhdr.S - AIF format file (.axf) header @ version 0.6, 18.5.2003, Semantics Oy, Tauno Voipio

.globl start @ program start .globl main @ int main(void) #if (__GNUC__ < 3) .globl __gccmain @ dummy, called from main() #endif

.globl __ram_top__ @ end of user RAM .globl __text_start__ @ code section base .globl __text_length__ @ read only section length .globl __data_length__ @ .data area length .globl __bss_length__ @ .bss area length

@ AIF header @ ---------- .section .init @ locate at file start .code 32

start: aifh: nop @ magic: nop nop @ relocator: none bl zinit @ zero-initialiser

1: bl _start @ start up swi 0x11 @ exit: should never be executed

szhdr: .word __text_length__ @ read-only part size, bytes .word __data_length__ @ read-write data size, bytes .word 0 @ debug size: none .word __bss_length__ @ zero-init size, bytes

.word 0 @ debug type flags: no debug data .word __text_start__ @ code section base .word 0 @ workspace (unused) adrmd: .word 32 @ address mode flags: 32 bit dsbas: .word 0 @ data section base, if separate .word 0 @ byte offset to XAIF header chain .word 0 @ reserved nop @ magic: nop

#if (__GNUC__ >= 3) .section .text #endif

@ Zero-initialiser @ ----------------

zinit: add r12,lr,#szhdr-1b @ -> size block ldmia r12,{r0-r3} @ r0: r/o, r1: r/w, r2: deb, r3: z/i size sub r12,r12,#szhdr-aifh @ -> header

ldr r2,[r12,#adrmd-aifh] @ get address mode tst r2,#(1 main program bx r1 @ enter main code

.pool

#if (__GNUC__ < 3)

@ Dummy GCC startup @ -----------------

.code 16 .thumb_func

__gccmain: bx lr @ just return #endif .end

Here's how to access them from C: /* Global memory limits set by linker script */ extern uint8_t __ram_loc__; /* bottom of available RAM */ extern uint8_t __bss_end__; /* start of free RAM after program use */ extern uint8_t __ram_top__; /* top of all RAM */ /* Module data */ #define RAMLOC (uint32_t)&__ram_loc__ #define RAMTOP (uint32_t)&__ram_top__ #define BFS (uint32_t)&__bss_end__ #define MAX_SIZE (RAMTOP - BFS) /* maximum loadable program size */

snip

asm snipped

Hey thanks,

What makes a linker variable exported? Are they all exported? What about collisions with global variables in the linked system?

I guess I will have to spend some time with the manual and experimenting, but you have helped!

Regards, Steve There is no "x" in my email address.

Thank you for positive feedback - it keeps the response engine running.

The manual does not give clear information about this, but the linker variables do all live in the same symbol space as the program globals, so they are all 'exported'.

The information above is experimental - I did not have time to wade through the ld sources.

HTH

Tauno Voipio tauno voipio (at) iki fi For email, adjust the address in sig in the obvoius way, and, please, use a sensible header and sender name - others will head to the spam bin.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required