linker scripts - Embedded

This is a discussion on linker scripts - Embedded ; 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 ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: linker scripts

  1. linker scripts

    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


  2. Re: linker scripts

    KBG wrote:
    > 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



    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

  3. Re: linker scripts

    On Mon, 25 Sep 2006 19:20:43 GMT, Tauno Voipio
    wrote:


    >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);
    > }
    >


    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.

  4. Re: linker scripts

    Steve Calfee wrote:
    > On Mon, 25 Sep 2006 19:20:43 GMT, Tauno Voipio
    > wrote:
    >
    >
    >
    >>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);
    >> }
    >>

    >
    >
    > 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 << 8) @ separate data?
    ldrne r12,[r12,#dsbas-aifh] @ yes - get data section base
    addeq r12,r12,r0 @ no - add r/o size

    add r12,r12,r1 @ add data section size

    mov r0,#0 @ get zero data
    cmp r3,#0 @ count done?

    clrlp: movle pc,lr @ done - exit

    str r0,[r12],#4 @ clear a word - bump pointer
    subs r3,r3,#4 @ bump count
    b clrlp @ loop till done


    @ Startup
    @ -------

    .section .text

    _start: ldr sp,=__ram_top__ @ initialize stack
    ldr r0,=0 @ no arguments
    ldr r1,=main @ -> 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 */

    ---

    HTH

    --

    Tauno Voipio
    tauno voipio (at) iki fi


  5. Re: linker scripts

    On Wed, 27 Sep 2006 06:20:41 GMT, Tauno Voipio
    wrote:


    >>>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 */
    >>> }

    snip

    >>>

    >>
    >>
    >> 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):
    >>



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

    asm snipped
    >
    >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 */
    >
    >---
    >
    >HTH


    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.

  6. Re: linker scripts

    Steve Calfee wrote:
    > On Wed, 27 Sep 2006 06:20:41 GMT, Tauno Voipio
    > wrote:
    >
    > Hey thanks,


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

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


    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'.

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


    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.

+ Reply to Thread