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.

Warnings occurred when Load and Run Addresses are specified in Linker Script

Hi All,

We are trying to run a Test RAM Application which Runs from 0x08000000 and Loads at 0x00000000.

We are using a customized below linker script 

/*----------------------------------------------------------------------------*/
/* Linker Settings */

--retain="*(.intvecs)"
/* USER CODE BEGIN (0) */
/* USER CODE END */

/*----------------------------------------------------------------------------*/
/* Memory Map */

MEMORY
{
/*
BOOT SECTION
*/
RAM_BOOT_EXV : origin = 0x08000000 length = 0x00000020
RAM_BOOT (RW) : origin = 0x08000020 length = 0x0002DFF0
STACKS (RW) : origin = 0x0802E010 length = 0x00001000

RAM_BOOT_EXV1 : origin = 0x00000000 length = 0x00000020
RAM_BOOT1 (RW) : origin = 0x00000020 length = 0x0002DFF0

NHET_RAM_0 : origin = 0xFF460000 length = 0x00020000


}

/* USER CODE BEGIN (3) */
/* USER CODE END */


/*----------------------------------------------------------------------------*/
/* Section Configuration */

SECTIONS
{.intvecs :

LOAD = RAM_BOOT_EXV, RUN = RAM_BOOT_EXV1,
{}
/*
BOOT CODE
*/
.cinit:
LOAD = RAM_BOOT, RUN = RAM_BOOT1,
{}
.text:
LOAD = RAM_BOOT, RUN = RAM_BOOT1,
{
/**(.text). = align(4);*/
}

.const:
LOAD = RAM_BOOT, RUN = RAM_BOOT1,
{
/* *(.const). = align(4);
_Code_End = .;*/
}

.bss : { _Code_End = .;} > RAM_BOOT1

.data : {} > RAM_BOOT
.HETPROG : {e_HETPROGRAM0_UN = .;} > NHET_RAM_0 /* NHET PROGRAM */
}

when we are compiling this application we are getting the below warning.

warning #10278-D: LOAD placement specified for section
".text:decompress:none:rtsv7R4_T_be_v3D16_eabi.lib<copy_decompress_none.obj>
". This section contains decompression routines required for linker
generated copy tables and C/C++ auto-initialization. Must ensure that this
section is copied to run address before the C/C++ boot code is executed or
is placed with single allocation specifier (ex. "> MEMORY").
warning #10278-D: LOAD placement specified for section
".text:rtsv7R4_T_be_v3D16_eabi.lib<memcpy_t2.obj>". This section contains
decompression routines required for linker generated copy tables and C/C++
auto-initialization. Must ensure that this section is copied to run address
before the C/C++ boot code is executed or is placed with single allocation
specifier (ex. "> MEMORY").

Can somebody please help us in resolving this warning.

Best Regards,

Priya

  • Some background is required to understand what is happening.  

    The linker allows you to allocate a section to different addresses for both load and run.  But you still have to take explicit steps so that, sometime before the code or data is used, it is copied from the load address to the run address.  

    In the case of initialized global variables, the linker does take care of many details for you.  Consider: 

    int a = 123;
    int b = 456;
    

    For this code the compiler emits something like this assembly:

    ; pseudo-assembly code
        .data         ; section is named .data
    a:  .word   123   ; init the variables
    b:  .word   456
    

    The linker compresses all the .data sections (thus saving memory) and places that compressed data into a section named  .cinit.  This .cinit section also contains initialization records, and a table of pointers to functions from the RTS library which decompress the data during system startup.  Two of the routines used during decompression are found in the RTS library object modules copy_decompress_none.obj and memcpy_t2.obj.  

    The important point: Those two decompression routines are invoked during system startup time, before main is called.   These routines must be copied from the load address to the run address before they can run.  This does not happen by default.  Your choices are:

    1. Change system startup so these routines are copied over before anything else
    2. Do not allocate these routines a load address, but only a run address.  

    While #1 is possible in theory, I don't know how to do it, and I'm not aware of anyone who has.  So I presume you will use solution #2.

     The linker command file syntax for allocating just these RTS routines to a run address is:

        for_rts_decompress {
            rtsv7R4_T_be_v3D16_eabi.lib<copy_decompress_none.obj>(.text:decompress:none)
            rtsv7R4_T_be_v3D16_eabi.lib<memcpy_t2.obj>(.text)
        } > RAM_BOOT1
    

    This creates an output section named for_rts_decompress.  The input sections are .text:decompress:none from the RTS object module copy_decompress_none.obj, and .text from the RTS object module memcpy_t2.obj.  Those input section names are developed from the previous linker error diagnostic.  Note how for_rts_decompress is allocated only a run address in the memory range RAM_BOOT1, and no load address.  These routines must be present at this run address when the startup code starts running.

    I suspect you also use the option --zero_init=off, or you would see another linker diagnostic about an RTS object module named copy_zero_init.obj.  Please do not use this option without a very clear understanding of what it does.  It causes all global variables to have an undetermined value at the start of main.  C++ code, in particular, does not work in this state.  If you remove --zero_init=off, the next change you need in the linker command file is very similar to that which I show above.

    I suspect you also should not allocate the .cinit section separate load and run addresses.  However, I'll address that in another post.

    Thanks and regards,

    -George