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?
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
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 */
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.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.