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 file: Mark memory area behind code for usage?

Genius 5820 points

I'm developing a bare-metal application using starterware. There no malloc()/calloc() exists, thus I have no other possibility to allocate a large memory buffer by defining a large global array (e.g. an unsigned char array).

The big disadvantage: using such an array the resulting .bin-file is blown up to a really huge size. So my next idea: I do not use a global array but parts of the really huge memory by pointing to an address in RAM that is unused. I know that my program is loaded to 0x80000000 but I do not know its size, so that I'm not sure at which memory address I can start with my buffer.

So is there a possibility to modify the linker command file in a way so that it writes the total size of my program into a variable that is accessible from within my program? Or is there any other way to evaluate the resulting binaries size without compiling it twice (once for checking the size and once with a modified constant that incorporates the size in order to use it out of the program)?

Thanks!

  • Hans M��ller said:
    There no malloc()/calloc() exists

    The compiler RTS library includes an implementation of malloc and calloc.  I presume this doesn't work for you for some reason.  I'm curious to know why.

    Hans M��ller said:
    The big disadvantage: using such an array the resulting .bin-file is blown up to a really huge size

    This problem can probably be fixed.  Please post your linker command file and I'll show you the adjustments you need.  At a conceptual level, the idea is to place all the uninitialized sections after all the initialized sections.  The size of the bin file is highest address for an initialized section - lowest address for an initialized section.  If any uninitialized sections get into the middle of that range, it gets bigger.

    Hans M��ller said:
    So is there a possibility to modify the linker command file in a way so that it writes the total size of my program into a variable

    I doubt we need to go to this point, so I won't respond to this for now.

    Thanks and regards,

    -George

  • Hm, according to Starterware documentation malloc()/calloc does not work...I'd guess because there is no memory range defined these functions could use: http://processors.wiki.ti.com/index.php/StarterWare_02.00.00.07_Release_Notes#What_is_Not_Supported (OK, this link explains it a bit better: no heap is initialised)

    That's my current .cmd-file:

    -stack  0x0008                             /* SOFTWARE STACK SIZE           */
    -heap   0x2000                             /* HEAP AREA SIZE                */
    -e Entry
    --diag_suppress=10063
    
    MEMORY
    {
            DDR_MEM        : org = 0x80000000  len = 0x7FFFFFF           /* RAM */
           IRAM_MEM        : org = 0x40300000  len = 0x000FFFF           /* RAM */
    }
    
    SECTIONS
    {
        .text:Entry : load > 0x80000000
    
        GROUP
        {
             IRAM_CODE : { }
             IRAM_DATA : { }
        }load=DDR_MEM, run=IRAM_MEM, START(iram_start), SIZE(iram_size), RUN_START(relocstart)
    
        .text    : load > DDR_MEM              /* CODE                          */
        .data    : load > DDR_MEM              /* INITIALIZED GLOBAL AND STATIC VARIABLES */
        .bss     : load > DDR_MEM              /* UNINITIALIZED OR ZERO INITIALIZED */
                                               /* GLOBAL & STATIC VARIABLES */
                        RUN_START(bss_start)
                        RUN_END(bss_end)
        .const   : load > DDR_MEM              /* GLOBAL CONSTANTS              */
        .stack   : load > 0x87FFFFF0           /* SOFTWARE SYSTEM STACK         */
    }
    
  • Hans M��ller said:
    Hm, according to Starterware documentation malloc()/calloc does not work

    I think we should defer to the Starterware experts on that.  In fact, after looking at your link command file, I think it makes sense to work this issue with the Starterware forum, and not this compiler forum.  I'll move this thread over.

    Thanks and regards,

    -George

  • Hans M��ller said:
    Hm, according to Starterware documentation malloc()/calloc does not work...I'd guess because there is no memory range defined these functions could use: http://processors.wiki.ti.com/index.php/StarterWare_02.00.00.07_Release_Notes#What_is_Not_Supported

    The release notes for a later version of StarterWare removed the note which said that malloc/calloc isn't supported. See the thread malloc() with beaglebone (StarterWare), which also explains how to set the heap size.

    Add the following to the SECTIONS in the linker command file to allocate space for the malloc heap:

      .sysmem : load > DDR_MEM

  • Beside

        .sysmem : load > DDR_MEM

    which is placed at the end of my CMD-file I added a statement

        -heap   0x02000000

    to specify the available heap size (should fit without problems since there is 1 GByte DDR RAM).

    Amazingly this blows up the size of my .bin-file to 34091596 bytes.

    Any ideas how this can be avoided?

  • Hans M��ller said:
    Amazingly this blows up the size of my .bin-file to 34091596 bytes.

    Any ideas how this can be avoided?

    From looking at an example the uninitialized .bss and .sysmem sections were being mixed in memory among the initialized .text, .data and .const sections by the linker. The generated .bin file only needs initialized sections, but "holes" between the initialized sections cause the size of the .bin file to increase.

    The solution appears to change the SECTIONS in the linker command file to group the initialized sections into one contiguous area of memory. e.g. used the following:

    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
            DDR_MEM        : org = 0x80000000  len = 0x10000000           /* RAM */
    }
    
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
        GROUP: load = 0x80000000
        {
            .text:Entry :
            .text    :                             /* CODE                          */
            .data    :                             /* INITIALIZED GLOBAL AND STATIC VARIABLES */
            .const   :                             /* GLOBAL CONSTANTS              */
        }
        .bss:    load > DDR_MEM                    /* UNINITIALIZED OR ZERO INITIALIZED */
                 RUN_START(bss_start)
                 RUN_END(bss_end)
        .sysmem: load > DDR_MEM
        .stack   : load > 0x8FFFFFF0           /* SOFTWARE SYSTEM STACK         */
    }
    

    This excluded the .sysmem (heap) and .bss sections from the size of the .bin file. The output linker map file looks valid, but I haven't had a chance to boot the resulting .bin file to test that it still runs.

  • It works - great, thanks!