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.

linker command for dual ROM segments and seperate load and run addresses




I will preface this by saying that I am not the initial author of this design. It was originally implemented by Eugene Kagan, which some of
you may remember. I am the one that must modify it. I appologize for the length in advance.

The basic premise is that I need two sections of ROM (APP and APP_2). There are many source files in several directories whose output
will go into APP. There is only one directory, with a couple of files, whose output will go into APP_2. I build these into a "group_2.out".

My linker.cmd looks like:

MEMORY
{

.
.

APP_2 (R) : origin=0x00100000 length=0x00000FFF
APP (R) : origin=0x00101000 length=0x000FF000

}

SECTIONS
{
.
.

.app_2:
{
Build\group_2.out(.text). = align(4);
Build\group_2.out(.const). = align(4);
/* .cinit section must load with rest of app */
} > APP_2

.app:
{
*(.text). = align(4);
*(.const). = align(4);
} > APP

.cinit:
{
*(.cinit). = align(4);
} > APP

}

This works perfectly. I can verify from the map file that each section is loaded correctly and the code works as expected.

This is where the ball gets dropped. I have another application for this code that requires the need to have different load and run addresses.
Both sections (APP and APP_2) need to have a load address that is 0x1000000 offset from the run address.
I start by linking with the above linker.cmd file except I specify the "-r" to make it relocatable.
I run some post build steps that modify the OUT file with checksum values etc.
Then I link all modules again using another linker command file that has this
configuration (no "-r"):

MEMORY
{

.
.

APP_2_RUN (R) : origin=0x00100000 length=0x00000FFF
APP_RUN (R) : origin=0x00101000 length=0x000FF000

APP_2_LOAD (R) : origin=0x01100000 length=0x00000FFF
APP_LOAD (R) : origin=0x01101000 length=0x000FF000

}

SECTIONS
{
.
.

GROUP
{
.app_2:{}
._app001: {} /* fill for that section */
} load > APP_2_LOAD run > APP_2_RUN

GROUP
{
.app:{}
._app000: {} /* fill for that section */
} load > APP_LOAD run > APP_RUN

}

I have applications that implement this 0x1000000 load address and they work perfectly. But they only
have one APP segment (only APP segment, not APP and APP_2).

When I add this second segment "APP_2", the first link works as expected. But I get an error
when doing this second linking that indicates that all of the symbols that are present in the
APP_2 segment are multiply defined in that "group_2.out" and the final OUT file that is to combine the
two segments.

It is like the second "GROUP"ing is including ".app_2" as well as ".app". In your TI documentation
(spru513d.pdf) I saw an "except" command, but I couldn't find any detail.

Please help.

  • Ries Robison said:
    It was originally implemented by Eugene Kagan, which some of you may remember.

    Yes we do.  We have a lot of respect for Eugene.

    Ries Robison said:
    But I get an error when doing this second linking that indicates that all of the symbols that are present in the APP_2 segment are multiply defined

    I think this is the best place to start.  Please show the text of some of those error messages.  That will name the files where the multiple definitions are found.

    Thanks and regards,

    -George

  • In my post I used generic symbols to illustrate a point.  Specifically the APP_2 is called bb.out and APP is slave_application_gm.out.  

    Relevant portion of he first linker.cmd file:

    MEMORY                                             
    {
        APP			(R) :	origin=0x00004058 length=0x0005DAA4 fill=0xEFFFDFFF	
    APP_BB (R) : origin=0x00061AFC length=0x0000E4FC fill=0xEFFFDFFF
    }
    SECTIONS                                                
    {

    .app_bb:
    {
    .\bb\.\Build\bb.out(.text). = align(4);
    .\bb\.\Build\bb.out(.const). = align(4);

    } > APP_BB
        .app:
    {
    *(.text). = align(4);
    *(.const). = align(4);
    } > APP
    }

    The following is the output of the first linker.cmd file:

     Modules to link:

    .\Bb\.\Build\bb.out
    .\comms\.\Build\comms.out
    .\diag\.\Build\diag.out
    .\Edtr\.\Build\edtr.out
    .\fm\.\Build\fm.out
    .\io\.\Build\io.out
    .\os\.\Build\os.out
    .\..\..\Sys_Common\Calibration\Os\.\Build\os_sys_common_calibration.out
    .\sa\.\Build\sa.out
    .\sc\.\Build\sc.out
    .\Tc\.\Build\tc.out
    .\Tc_Ib\.\Build\tc_ib.out
    .\vss\.\Build\vss.out
    .\..\..\Sys_Common\Application\Vss\.\Build\vss_sys_common_application.out
    .\Ysc\.\Build\ysc.out
    .\Ysc_Ib\.\Build\ysc_ib.out
    .\tools\codegen\bist.lib
    .\tools\codegen\rtsc_16.lib

    >> warning: entry point other than _c_int00 specified

    POST-BUILD STEPS ...
    
    
    This link is successful!
    I know the first link works.  In that I can see the symbols that exist in bb.out (ex.UpdateBaseBrakePressureRequest ) getting loaded to memory location starting with 0x61AFC.  
    Also I see all other symbols from other modules getting loaded in the memory segment that starts at 0x4058.
    
    
    
    
    Now I need to re-link these to allow for a load address that has a memory offset of 0x1000000.  So I have a second linker.cmd file.
    Relevant portion of he next linker.cmd file:
    MEMORY                                             
    {
        APP_RUN		(R) :	origin=0x00004058 length=0x0005DAA4
    APP_BB_RUN (R) : origin=0x00061AFC length=0x0000E500
        APP_LOAD		(R) :	origin=0x01004058 length=0x0005DAA4
    APP_BB_LOAD (R) : origin=0x01061AFC length=0x0000E500
    }
    SECTIONS                                                
    {
        GROUP
    {
    .app_bb: {}
    /*
    Fill section for BB section from original application file.
    cinit section for BB must be in APP section or init variables do not get initialized
    */
    ._app001: {}
    } load > APP_BB_LOAD run > APP_BB_RUN

    GROUP
    {
    .app: {}
    .cinit: {}
    /*
    Fill section from original application file.
    */
    ._app000: {}
    } load > APP_LOAD run > APP_RUN
    }


    The output of the second linker is:
    ".\tools\codegen\lnk470.exe" -o ".\Build\slave_application_download.out" -m ".\Build\slave_application_download.map" ".\.\tools\Build\linker_download.cmd" .\Build\slave_application.out
    >> error: symbol $UpdateBaseBrakePressureRequest is defined multiple times:
    .\bb\.\Build\bb.out and .\Build\slave_application.out
    
    
    The first line of the output is the DOS command line used to invoke the linker.   The "linker_download.cmd" is the name of the second linker.cmd file.
    I know for sure that the"$UpdateBaseBrakePressureRequest" symbol is part of the bb.out module.  This linker error seems to indicate that the code that is in the bb.out, is 
    getting loaded to the "APP_BB_LOAD"/"APP_BB_RUN" section as well as the "APP_LOAD"/"APP_RUN" section.  I only want the bb.out to get loaded into the memory 
    segments specified with "APP_BB_LOAD"/"APP_BB_RUN" - not in the "APP_LOAD"/"APP_RUN" segment.  I believe it is getting loaded into both therefore the linker error.
    
    
    I hope this makes more sense.
    
    
    Ries
  • Ries Robison said:
    >> error: symbol $UpdateBaseBrakePressureRequest is defined multiple times:
    .\bb\.\Build\bb.out and .\Build\slave_application.out

    So, bb.out is an input to both the first link and the second link.  And slave_application.out is an output of the first link, and an input to the second link.  Is that correct?  (I wish I could put a diagram here.)  And the symbol $UpdateBaseBrakePressureRequest is defined in bb.out.  Is all of that correct?  For now, I presume so.  For me, the better question is: How did this work before?  It makes sense that it doesn't work now.  This wiki article on managing symbols with the linker may help.

    Thanks and regards,

    -George