AnsweredAssumed Answered

K60DN512Z MQX 4.0.1 gcc c++ Linker File

Question asked by Tobias Bystricky on Jul 24, 2013
Latest reply on Jul 29, 2013 by rickli

Hello,

ich have ported a MQX-Project from freescale compiler to gcc. After a lot of work I'm nearly finished. But now I have Problems with the linkerfile given from freescale.

Original file (.ld):

/*
*****************************************************************************
**
**  File        : K60DN512Z_flash.ld
**
**  Default linker command file for Flash targets
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(__thumb_startup)


/* Highest address of the user mode stack */
_estack = 0x20000000;    /* end of lower SRAM */
__SP_INIT = _estack;


/* Generate a link error if heap and stack don't fit into RAM */
__heap_size = 0x800; /* required amount of heap  */
__stack_size = 0x800; /* required amount of stack */


/* Specify the memory areas */
MEMORY
{
  m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0x1E0
  m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
  m_text (rx) : ORIGIN = 0x00000800, LENGTH = 512K - 0x800
  m_data   (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 64K /* Lower SRAM */
  m_data2   (rwx) : ORIGIN = 0x20000000, LENGTH = 64K /* Upper SRAM */
}



/* Define output sections */
SECTIONS
{
  /* The startup code goes first into Flash */
  .interrupts :
  {
  __vector_table = .;
    . = ALIGN(4);
    KEEP(*(.vectortable)) /* Startup code */
    . = ALIGN(4);
  } > m_interrupts

  .cfmprotect :
  {
    . = ALIGN(4);
  KEEP(*(.cfmconfig)) /* Flash Configuration Field (FCF) */
  . = ALIGN(4);
  } > m_cfmprotrom


  /* The program code and other data goes into Flash */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)


    KEEP (*(.init))
    KEEP (*(.fini))


    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } > m_text


  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text
  .ARM : {
    __exidx_start = .;
      *(.ARM.exidx*)
      __exidx_end = .;
  } > m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    /* We don't want to include the .ctor section from
       from the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } > m_text 
  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } > m_text 


  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } > m_text
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } > m_text
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);

  ___ROM_AT = .;
  } > m_text


  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : AT(___ROM_AT)
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */


    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } > m_data

  ___data_size = _edata - _sdata;

  ___m_data2_ROMStart = ___ROM_AT + SIZEOF(.data);
  .user_data2 : AT(___m_data2_ROMStart)
  {
     . = ALIGN(4);
     ___m_data2_RAMStart = .;
     *(.data2) /* This is an User defined section */
     ___m_data2_RAMEnd = .;
     . = ALIGN(4);
  } > m_data2
  ___m_data2_ROMSize = ___m_data2_RAMEnd - ___m_data2_RAMStart;


  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    __START_BSS = .;
  PROVIDE ( __bss_start__ = __START_BSS );
    *(.bss)
    *(.bss*)
    *(COMMON)


    . = ALIGN(4);
    __END_BSS = .;
  PROVIDE ( __bss_end__ = __END_BSS );
  } > m_data


  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
  __heap_addr = .;
    . = . + __heap_size;
    . = . + __stack_size;
    . = ALIGN(4);
  } > m_data

  _romp_at = ___ROM_AT + SIZEOF(.data) + SIZEOF(.user_data2);
  .romp : AT(_romp_at)
  {
  __S_romp = _romp_at;
    LONG(___ROM_AT);
    LONG(_sdata);
    LONG(___data_size);
    LONG(___m_data2_ROMStart);
    LONG(___m_data2_RAMStart);
    LONG(___m_data2_ROMSize);
    LONG(0);
    LONG(0);
    LONG(0);
  } > m_data2

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

And if I compare the freescale compiler linker file (.lcf) I see that there are a lot of symbols needed by MQX:

MEMORY
{
   vectorrom   (RX): ORIGIN = 0x00000000, LENGTH = 0x00000400
   cfmprotrom  (R): ORIGIN = 0x00000400, LENGTH = 0x00000020
   rom         (RX): ORIGIN = 0x00000420, LENGTH = 0x0007FBE0  # Code + Const data  
   ram         (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000  # SRAM - RW data


   # kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap)
   end_of_kd   (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
  
   # Boot stack reused by MQX Kernel data
   bstack      (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200  # Boot stack
   end_bstack  (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000
}


KEEP_SECTION { .vectors_rom, .vectors_ram, .cfmconfig }


SECTIONS
{
   __INTERNAL_SRAM_BASE  = 0x1FFF0000;
   __INTERNAL_SRAM_SIZE  = 0x00020000;


   __INTERNAL_FLASH_BASE = 0x00000000;
   __INTERNAL_FLASH_SIZE = 0x00080000;


   __INTERNAL_FLEXNVM_BASE = 0;
   __INTERNAL_FLEXNVM_SIZE = 0;
  
   __EXTERNAL_MRAM_BASE  = 0x70000000;
   __EXTERNAL_MRAM_SIZE  = 0x00080000;
   __EXTERNAL_MRAM_ROM_BASE = 0x70000000;
   __EXTERNAL_MRAM_ROM_SIZE = 0x00000000;
   __EXTERNAL_MRAM_RAM_BASE = 0x70000000;
   __EXTERNAL_MRAM_RAM_SIZE = 0x00080000;


   __EXTERNAL_LCD_BASE = 0x60000000;
   __EXTERNAL_LCD_SIZE = 0x1FFFF;
   __EXTERNAL_LCD_DC_BASE = 0x60010000;


   # MQX link time configurations
   __DEFAULT_PROCESSOR_NUMBER = 1;
   __DEFAULT_INTERRUPT_STACK_SIZE = 1024;
   __KERNEL_DATA_VERIFY_ENABLE = 0;    # Test SDRAM read/write


   # Flashx configurations
   __FLASHX_SECT_SIZE = 0x800;


    .vectors :
    {
        __VECTOR_TABLE_ROM_START = .;        # Runtime vector table in sram
        *(.vectors_rom)
        . = ALIGN (0x4);
    } > vectorrom


    .cfmprotect :
    {
        *(.cfmconfig)
        . = ALIGN (0x4);
    } > cfmprotrom


    .main_application :
    {
        *(KERNEL)
        *(S_BOOT)
        *(IPSUM)
        *(.text)
        *(.init)
        *(.fini)
        *(.eini)
        *(.ctors)
        *(.dtors)
        . = ALIGN(0x4);
        *(.rodata)
        . = ALIGN(0x4);
        *(.rdata)
        . = ALIGN(0x4);
        *(.ARM.extab)
        . = ALIGN(0x4);
        *(.exception)
        . = ALIGN(0x4);
        __exception_table_start__ = .;
        EXCEPTION
        __exception_table_end__ = .;
        __sinit__ = .;
        STATICINIT


        . = ALIGN(0x4);
        __COPY_OF_DATA = .;
    } > rom


    .main_application_data : AT(__COPY_OF_DATA)
    {
        . = ALIGN(128);
        __VECTOR_TABLE_RAM_START = .;        # Runtime vector table in sram
        *(.vectors_ram)


        . = ALIGN(512);
        __BDT_BASE = .;
        *(.usb_bdt)
        __BDT_END = .;


        . = ALIGN(0x20);
        __USER_NO_MEMORY_START = .;
  *(.nouser)
        __USER_NO_MEMORY_END = .;


        . = ALIGN(0x20);
        __USER_RO_MEMORY_START = .;
  *(.rouser)
        __USER_RO_MEMORY_END = .;


        . = ALIGN(0x20);
        __USER_RW_MEMORY_START = .;
  *(.rwuser)
        __USER_RW_MEMORY_END = .;


        . = ALIGN(0x20);
        __USER_DEFAULT_MEMORY_START = .;
        __START_DATA = .;
        *(.data)
        __END_DATA = .;


        . = ALIGN(0x10);
        __START_SDATA = .;
        *(.sdata)
        __END_SDATA = .;


        . = ALIGN(0x10);
        __SDA_BASE  = .;
        __SDA_BASE_ = __SDA_BASE;
       
        . = ALIGN(0x20);       
    *(.kernel_data)
       
        # jlink-flasher workaround: keep the next main_application_bss section aligned
        # so the BSS does not generate RAM section in ELF which then confuses jlink
        . = ALIGN(0x10);       
    } > ram


    .main_application_bss :
    {
        . = ALIGN(0x10);
        __START_SBSS = .;
        *(.sbss)
        *(SCOMMON)
        __END_SBSS = .;


        __START_BSS = .;
        *(.bss)
        *(COMMON)
        __END_BSS = .;
        . = ALIGN(0x20);
        __USER_DEFAULT_MEMORY_END = .;


        . = ALIGN(0x10);       
    } >> ram


    .kernel_data : #AT(ADDR(.main_application_bss) + SIZEOF(.main_application_bss))
    {
        __KERNEL_DATA_START = ALIGN(0x10);
    }
    .end_of_kernel_data :
    {
        __KERNEL_DATA_END = .;
    } > end_of_kd


    .boot_stack :
    {
        _stack_end = .;
    } > bstack
  
    .end_of_boot_stack :
    {
        _stack_addr  = .;
        __SP_INIT    = .;
        __BOOT_STACK_ADDRESS = .;
    } > end_bstack


    # Locate the ROM copy table into ROM after the initialized data
    _romp_at = __COPY_OF_DATA + SIZEOF(.main_application_data);


    .romp : AT (_romp_at)
    {
        __S_romp = _romp_at;
        WRITEW(__COPY_OF_DATA);                    #ROM start address
        WRITEW(ADDR(.main_application_data));      #RAM start address
        WRITEW(SIZEOF(.main_application_data));    #size
        WRITEW(0);
        WRITEW(0);
        WRITEW(0);
    }


    _flashx_start = __COPY_OF_DATA + SIZEOF(.main_application_data) + SIZEOF(.romp);


    # flashx working area spans across the whole rest of Flash memory
    __FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;
    __FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;


}


Does anyone has a valid linkerfile for gcc containing all neccesary symbols like __KERNEL_DATA_START, __KERNEL_DATA_END, __VECTOR_TABLE_ROM_START and so on...

Thanks and best regards,

Tobias

Outcomes