This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

order of linker sections in output file

I would like to place a new linker section and have it placed as the last section of the flash object (not the last byte of the flash memory).  I added the new linker section (named .version) as the last section for FLASH in the linker command file, but the linker actually placed the .cinit section last.  How can I force my new section to be the last section of a flash image?

I am using CCS version 5.2.1.00018 and targeting the Stellaris family.

See my failed attempt below…

~~~~~~~~~~~~~~~~~~~~~~~~~~~ command linker file ~~~~~~~~~~~~~~~~~~~~~~~~~~~

SECTIONS
{
    .intvecs :   > 0x00000000   /* INTERRUPT VECTORS              */
    .text    :   > FLASH        /* CODE                           */
    .const   :   > FLASH        /* CONSTANT DATA                  */
    .cinit   :   > FLASH        /* INITIALIZATION TABLES          */
    .pinit   :   > FLASH        /* TEMPLATE INITIALIZATION TABLES */
    .version :   > FLASH

    .vtable  :   > 0x20000000   /* INTERRUPT VECTORS              */
    .data    :   > SRAM
    .bss     :   > SRAM         /* GLOBAL & STATIC VARS           */
    .sysmem  :   > SRAM         /* DYNAMIC MEMORY ALLOCATION AREA */
    .stack   :   > SRAM         /* SOFTWARE SYSTEM STACK          */
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~ output map file ~~~~~~~~~~~~~~~~~~~~~~~~~~~

SEGMENT ALLOCATION MAP

run origin  load origin   length   init length attrs members
----------  ----------- ---------- ----------- ----- -------
00000000    00000000    0000eb68   0000eb68    r-x
  00000000    00000000    0000011c   0000011c    r-- .intvecs
  0000011c    0000011c    0000e61c   0000e61c    r-x .text
  0000e738    0000e738    0000033a   0000033a    r-- .const
  0000ea74    0000ea74    00000010   00000010    r-- .version
  0000ea88    0000ea88    000000e0   000000e0    r-- .cinit
20000000    20000000    0000f074   00000000    rw-
  20000000    20000000    0000e872   00000000    rw- .bss
  2000e874    2000e874    00000800   00000000    rw- .stack
2000f078    2000f078    00000259   00000259    rw-
  2000f078    2000f078    00000259   00000259    rw- .data

 

 

 

  • An option would be to use the HIGH location specifier in the .version sections statement.  By default, the linker allocates sections from low to high addresses.  The HIGH specifier will instruct the linker to allocate from high to low addresses.  This may not be exactly what you want, but please review the below user's guide for more options.

    .version : > FLASH (HIGH)

    The ARM assembly language tools user's guide describes the attributes of the HIGH specifier in Section 7.5.4.2.3.

     

  • Based on your suggestion, I read the documentation for the HIGH specifier, and concluded that it won’t accomplish our goal.  I tested the option too and, as expected, it inflates the binary output file to max size of the flash memory.

  • For some necessary background, please see this wiki article.

    To have an output section be allocated last, then you need to GROUP all the output sections for that memory range, placing the special section last of all.  This is a bit of overkill.  You don't care about the ordering of the other output sections, as long as .version goes last.  But GROUP is the only way to do it.

    Thanks and regards,

    -George

  • Alright, so I implemented the concept of the wiki article and I got mixed results.  My new section was placed last, however, the compression didn't work and the output binary nearly doubled in size.

    Here is the output from the build:

    warning #10229-D: output section ".data" refers to load symbol "_nop" and hence
       cannot be compressed; compression "rle" is ignored

    Here is my new linker command file:

    SECTIONS
    {
        GROUP
        {
            .intvecs :   > 0x00000000   /* INTERRUPT VECTORS              */
            .text    :   > FLASH        /* CODE                           */
            .const   :   > FLASH        /* CONSTANT DATA                  */
            .cinit   :   > FLASH        /* INITIALIZATION TABLES          */
            .pinit   :   > FLASH        /* TEMPLATE INITIALIZATION TABLES */
            .version :   > FLASH
        }

        .vtable  :   > 0x20000000   /* INTERRUPT VECTORS              */
        .data    :   > SRAM
        .bss     :   > SRAM         /* GLOBAL & STATIC VARS           */
        .sysmem  :   > SRAM         /* DYNAMIC MEMORY ALLOCATION AREA */
        .stack   :   > SRAM         /* SOFTWARE SYSTEM STACK          */
    }

  • First some minor corrections to your GROUP syntax ...

        GROUP
        {
            .text    :   /* CODE                           */
            .const   :   /* CONSTANT DATA                  */
            .cinit   :   /* INITIALIZATION TABLES          */
            .pinit   :   /* TEMPLATE INITIALIZATION TABLES */
            .version :
        } > FLASH

       .intvecs :   > 0x00000000   /* INTERRUPT VECTORS              */ 

    Do not allocate members of a GROUP.  Instead, allocate the entire GROUP at once.  The .intvecs section, since it is allocated to specific address, should not be in the GROUP at all.  

    It is possible that making these changes will avoid that warning and the size doubling, but I don't think so.

    I have another idea to suggest.  I don't really like it.  I wanted to discuss it with one of our linker experts, but couldn't reach him today.  So, I might make a better suggestion later.

    I suggest you split the FLASH memory range into two parts.  Call them FLASH1 and FLASH2.  FLASH1 will be just big enough to hold all the sections except .version.  Allocate all those sections into FLASH1.  Allocate .version into FLASH2.  Do not GROUP anything.  I don't like this because it is difficult to maintain.  You may have to change the definitions of  FLASH1 and FLASH2 as the sizes of your sections change.  That's not very nice.  But it is the best idea I have right now.

    Thanks and regards,

    -George