.data LMA перекрывает .data адреса VMA - PullRequest
0 голосов
/ 27 июня 2011

Я совершенно новичок в концепциях линкерных скриптов. Я столкнулся с некоторыми странными проблемами.

разделы, похоже, не имеют правильных адресов для VMA.

Например, если мы посмотрим на разделы .data VMA, который был предоставлен внутри размера LMA +. (это означает, что при запуске, когда я копирую данные из LMA в VMA, последние байты адресов LMA будут перезаписаны)

Вот так выглядит результат, посмотрите .data, и вы поймете, что я имею в виду:

    Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .rcw          00000008  20000000  20000000  00010000  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .init         00000628  20000008  20000008  00010008  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .text         000177f8  20000630  20000630  00010630  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .flash_data   00000010  20017e28  20017e28  00027e28  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .rodata       00000ec0  20017e38  20017e38  00027e38  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .xcptn        000008e8  20019000  20019000  00029000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  6 .extram       00002080  2001a000  200198e8  0002a000  2**13
                  CONTENTS, ALLOC, LOAD, DATA
  7 .data         000008f0  2001c080  2001b968  0002c080  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  8 .got          00000010  2001c970  2001c258  0002c970  2**2
                  CONTENTS, ALLOC, LOAD, CODE
  9 .got2         00000220  2001c980  2001c268  0002c980  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 10 .sdata        00000038  2001cba0  2001c488  0002cba0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 11 .sbss         00000088  2001cbd8  2001c4c0  0002cbd8  2**2
                  ALLOC
 12 .bss          0000bbbc  2001cc60  2001c548  0002cbd8  2**2
                  ALLOC
 13 .isrvectbl    00000d88  2002881c  20028104  0002cbd8  2**2
                  ALLOC
 14 .debug_aranges 00001618  00000000  00000000  0002cbd8  2**3
                  CONTENTS, READONLY, DEBUGGING
 15 .debug_pubnames 00002843  00000000  00000000  0002e1f0  2**0
                  CONTENTS, READONLY, DEBUGGING
 16 .debug_info   0003f23a  00000000  00000000  00030a33  2**0
                  CONTENTS, READONLY, DEBUGGING
 17 .debug_abbrev 00009c89  00000000  00000000  0006fc6d  2**0
                  CONTENTS, READONLY, DEBUGGING
 18 .debug_line   0000ae64  00000000  00000000  000798f6  2**0
                  CONTENTS, READONLY, DEBUGGING
 19 .debug_frame  00003bb8  00000000  00000000  0008475c  2**2
                  CONTENTS, READONLY, DEBUGGING
 20 .debug_str    00007b24  00000000  00000000  00088314  2**0
                  CONTENTS, READONLY, DEBUGGING
 21 .debug_loc    00015465  00000000  00000000  0008fe38  2**0
                  CONTENTS, READONLY, DEBUGGING
 22 .debug_ranges 00001768  00000000  00000000  000a52a0  2**3
                  CONTENTS, READONLY, DEBUGGING
 23 .comment      00000750  00000000  00000000  000a6a08  2**0
                  CONTENTS, READONLY
 24 .gnu.attributes 00000012  00000000  00000000  000a7158  2**0
                  CONTENTS, READONLY

мне предоставлен следующий ld-скрипт:

    ENTRY(__start) 
/* 
 *****************************************************************
 * PE_MPC5554_rom.ld                                           
 * GNU powerpc-eabispe Linker Script for the MPC5554                                  
 * By default, this application runs in internal flash, SRAM, and cache
 * c. 2005, P&E Microcomputer Systems, Inc.
 * REV      AUTHOR       DATE       DESCRIPTION OF CHANGE
 * ---   -----------   ----------   ---------------------
 * 0.1   C.Baker FSL   19/Jul/06    Changed memory layout, stack
 *                                  variables, and filename.
 * 0.2   C.Baker FSL   21/Sep/06    Changed stack in cache address.
 *****************************************************************
 */                


MEMORY
{
/* 32M External SRAM */
        ext_ram   : org = 0x20000000, len = 0x02000000  /* 32M on the G3 board */

/* Internal Flash RCW */
/* MPC5567 2M Internal Flash, but subtract two 128K blocks for use by emulated eeprom. */ 
/* but subtract one 128K block for use by BAM. */

/* MPC5567 80K Internal SRAM */

        flash_rcw : org = 0x00000000, len = 0x8
        int_flash : org = 0x00000008, len = 0x001BFFF8
        int_sram  : org = 0x40000000, len = 0x14000
/* e4_flash is reserved for emulated eeprom in partition 9 of the High Address Space. */ 
        e4_flash  : org = 0x001C0000, len = 0x40000

}

/* The performance of applications can, potentially, be improved by locking */
/* the stack into the cache. However, as this complicates debugging (e.g.,  */
/* function parameters are not visible from GDB) it is only advisable for   */
/* production code, not during development. Set STACK_IN_CACHE to 1 in the  */
/* application's "config.inc" to lock the stack into cache. Otherwise, set  */
/* STACK_IN_CACHE to 0, and the stack will be placed at the top of the      */
/* internal RAM.                                                            */

/* Stack Address Parameters */
/* __SP_END     = DEFINED( STACK_IN_CACHE ) ? 0x40040000 : 0x40013000; */
__SP_END     = 0x40013000;
__STACK_SIZE = 0x1000;
__SP_INIT    = __SP_END + __STACK_SIZE;

/*
Optionally define this variable with the address of heap
__heap_start   =  __SP_END;
*/



/****************************************************************/

SECTIONS
{

  .rcw :
  {
    KEEP( *(.rcw) )
  } > ext_ram

  /* CRT0 startup code */
  .pecrt0 ALIGN(8) : 
  { 
    *(.pecrt0)
    PEFILL = .;
      . = ALIGN(8);
  } > ext_ram

  .interp ALIGN(8)  :
  {
   *(.interp) 
   . = ALIGN(8);
  } > ext_ram

  .hash ALIGN(8) : 
  { 
  *(.hash) 
      . = ALIGN(8);
  } > ext_ram

  .dynsym ALIGN(8) : 
  {
  *(.dynsym) 
      . = ALIGN(8);
  } > ext_ram

  .dynstr ALIGN(8) : 
  { 
  *(.dynstr) 
      . = ALIGN(8);
  } > ext_ram

  .rela.dyn ALIGN(8)       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
      *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
      *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
      *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
    . = ALIGN(8);
    }                                                                    > ext_ram

  .init ALIGN(8) :  
  {     
    PROVIDE (__init = .);
    KEEP( *(.init) )
    . = ALIGN(8);
  } > ext_ram

  .text ALIGN(8) :
  {
    *(.text)
    *(.text.*)
    *(.gnu.warning)
    *(.gnu.linkonce.t*)
    __eabi = (.); /*PE*/
    LONG(0x4E800020); 
    . = ALIGN(8);
  } > ext_ram 

  .fini ALIGN(8) :  
  { 
    /*PROVIDE (__fini = .);*/
    KEEP( *(.fini) )
    . = ALIGN(8);
  } > ext_ram   

  .flash_data ALIGN(8) :
  {
    KEEP( *(.flash_data))
    . = ALIGN(8);
  } > ext_ram

  .rodata ALIGN(8) :
  {
    . = ALIGN(8);
    *(.rodata)
    *(.rodata.*)
    *(.gnu.linkonce.r*)
    . = ALIGN(8);
  } > ext_ram 

  .rodata1 ALIGN(8) :
  {
    *(.rodata1)
    . = ALIGN(8);
  } > ext_ram

  .PPC.EMB.apuinfo ALIGN(8) :
  {
    *(.PPC.EMB.apuinfo)
    . = ALIGN(8);
  } > ext_ram AT > ext_ram

  /* ISR table for software vector mode */
  .isrvectbl ALIGN(0x800) : ONLY_IF_RO
  {
    KEEP( *(.isrvectbl) )
  } > ext_ram

  PROVIDE (__EXCEPT_START__ = .); 

  /* IVOR4Handler */
  .xcptn ALIGN(8) : 
  {
    KEEP( *(.xcptn) )
    . = ALIGN(8);
  } > ext_ram

  PROVIDE (__EXCEPT_END__ = .); 

  etext = .;
  _etext = .;  
  __etext = .;   

  /******************************************************************/
  NEXT_LOAD_ADDR = .;
  __EXTDATA_ROM = .;

  .extram : AT (NEXT_LOAD_ADDR)
  {
    *(.extram)
    . = ALIGN(4);
  } > ext_ram

  /******************************************************************/ 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.extram);
  /*NEXT_LOAD_ADDR = .;
  __DATA_ROM = .;*/
  __DATA_ROM = NEXT_LOAD_ADDR;

/*  .PPC.EMB.sdata2 0x20100000 : AT (NEXT_LOAD_ADDR)*/
  .PPC.EMB.sdata2 : AT (NEXT_LOAD_ADDR)
  {
    _SDA2_BASE_ = .;
    __SDATA2_START__ = .;
    *(.PPC.EMB.sdata2)
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sdata2);  

  .sdata2 : AT (NEXT_LOAD_ADDR) 
  { 
    *(.sdata2) 
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata2);  

  .PPC.EMB.sbss2 : AT (NEXT_LOAD_ADDR)
  {
    *(.PPC.EMB.sbss2)
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sbss2);

  .sbss2 : AT (NEXT_LOAD_ADDR)
  {
    *(.sbss2) 
    __SBSS2_END__ = .;
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sbss2);
    .data :
  {
    *(.data)
    *(.data.*) 
    *(.gnu.linkonce.d*)
    CONSTRUCTORS
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data);

  .data1 :
  {
    *(.data1) 
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data1);  

  PROVIDE (__GOT_START__ = .);

  .got :
  { 
    *(.got) 
    . = ALIGN(8);
  } > ext_ram 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got);  

  .got.plt :
  { 
    *(.got.plt) 
    . = ALIGN(8);
  } > ext_ram     

  PROVIDE (__GOT_END__ = .);

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got.plt);

  .got1 :
  {  
    *(.got1) 
    . = ALIGN(8);
  } > ext_ram 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got1);

  PROVIDE (__GOT2_START__ = .);

  .got2 :
  { 
    *(.got2) 
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got2);

  PROVIDE (__CTOR_LIST__ = .);  

  .ctors :
  {
    /*KEEP (*crtbegin.o(.ctors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))*/
    KEEP (*(.ctors))
    . = ALIGN(8);
  } > ext_ram   

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.ctors);

  PROVIDE (__CTOR_END__ = .);
  PROVIDE (__DTOR_LIST__ = .);

  .dtors : AT (NEXT_LOAD_ADDR)
  {
    /*KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))*/
    KEEP (*(.dtors))
    . = ALIGN(8);
  } > ext_ram 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dtors);

  PROVIDE (__DTOR_END__ = .);
  PROVIDE (__FIXUP_START__ = .);

  .fixup : AT (NEXT_LOAD_ADDR)
  { 
    *(.fixup) 
    . = ALIGN(8);
  } > ext_ram 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.fixup);

  PROVIDE (__FIXUP_END__ = .);
  PROVIDE (__GOT2_END__ = .);


  .dynamic : AT (NEXT_LOAD_ADDR)
  { 
    *(.dynamic)
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dynamic);  

  .plt : AT (NEXT_LOAD_ADDR)
  {
    *(.plt)
    . = ALIGN(8);
  } > ext_ram

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.plt);  

  /* We want the small data sections together, so single-instruction offsets
     can access them all, and initialized data all before uninitialized, so
     we can shorten the on-disk segment size.  */

  __SDATA_ROM = .;

  .sdata :
  { 
    __SDATA_START__ = .;
    _SDA_BASE_ = .;
    *(.sdata) 
    . = ALIGN(8);
  } > ext_ram 

  NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata);  

  .PPC.EMB.sdata0 : AT (NEXT_LOAD_ADDR)
  {
    __SDATA_END__ = .;  
    . = ALIGN(8);
  } > ext_ram

  __DATA_ROM_END = .;
  edata = .;
  _edata  =  .;  
  __edata = .;

  /******************************************************************/  

  .sbss BLOCK (4):
  {
    PROVIDE (__sbss_start = .);
    PROVIDE (___sbss_start = .);    
    *(.sbss)
    *(.scommon)
    *(.dynsbss)
  } > ext_ram

  .PPC.EMB.sbss0 BLOCK (4):
  {
    *(.PPC.EMB.sbss0)
    PROVIDE (__sbss_end = .);
    PROVIDE (___sbss_end = .);
    PROVIDE (__SBSS_END__ = .);
  } > ext_ram

  .bss BLOCK (4):
  {
   PROVIDE (__bss_start = .);
   PROVIDE (___bss_start = .);
   *(.dynbss)
   *(.bss)
   *(COMMON)
   PROVIDE (__bss_end = .);
  } > ext_ram

  .isrvectbl BLOCK (4) (NOLOAD): ONLY_IF_RW
  {
   . = ALIGN(0x800);
   KEEP( *(.isrvectbl) )
  } > ext_ram

  /* ISR table for software vector mode */


  /******************************************************************/

  /*
  Heap grows from lower to higer addresses
  Stack grows from higer to lower addresses
  */

  /* Define position of heap */
  /* Default to location contiguous with .bss section in RAM */
  _end = DEFINED (__heap_start) ? __heap_start : ALIGN(8);    
  PROVIDE(end = _end);
  PROVIDE(__end = _end);

  /******************************************************************/

  .gcc_except_table : {*(.gcc_except_table)}

  /* These are needed for ELF backends which have not yet been
     converted to the new style linker.  */
  .stab 0 : { *(.stab) }
  .stabstr 0 : { *(.stabstr) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* */
  .eh_frame        0 : { *(.eh_frame) }

  /******************************************************************/  

__SRAM_CPY_START = ADDR(.PPC.EMB.sdata2);
__IV_ADDR     = ADDR(.xcptn);
__SRAM_LOAD      = (_end);
__SRAM_LOAD_SIZE = (SIZEOF(.flash_data) / 4);

__EXTRAM_CPY_START = ADDR(.extram);
__EXTRAM_CPY_END = ADDR(.extram)+SIZEOF(.extram);

__BSS_SIZE = ((__bss_end - __bss_start) / 4);
__SBSS_SIZE = ((__sbss_end - __sbss_start) / 4);

TEMPSIZE = SIZEOF(.PPC.EMB.sdata2)+SIZEOF(.sdata2)+SIZEOF(.PPC.EMB.sbss2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.data1);
TEMPSIZE = TEMPSIZE + SIZEOF(.got)+SIZEOF(.got.plt)+SIZEOF(.got1)+SIZEOF(.got2)+SIZEOF(.ctors);
TEMPSIZE = TEMPSIZE + SIZEOF(.dtors)+SIZEOF(.fixup)+SIZEOF(.dynamic)+SIZEOF(.plt);
TEMPSIZE = TEMPSIZE + SIZEOF(.sdata)+SIZEOF(.PPC.EMB.sdata0);
__ROM_COPY_SIZE  = (TEMPSIZE);


__DATA_VMA = ADDR(.data);
__DATA_LMA = LOADADDR(.data);
__DATA_LMA_END = __DATA_LMA + SIZEOF(.data);

__GOT_VMA = ADDR(.got);
__GOT_LMA = LOADADDR(.got);
__GOT_LMA_END = __GOT_LMA + SIZEOF(.got);

__GOT2_VMA = ADDR(.got2);
__GOT2_LMA = LOADADDR(.got2);
__GOT2_LMA_END = __GOT_LMA + SIZEOF(.got2);

__SDATA_VMA = ADDR(.sdata);
__SDATA_LMA = LOADADDR(.sdata);
__SDATA_LMA_END = __SDATA_LMA + SIZEOF(.sdata);
}

EDIT1: Я не получаю ошибку / предупреждение, когда я делаю все . Предполагается, что компоновщик собирает все для внешней памяти , начиная с 0x20 000000.

1 Ответ

1 голос
/ 27 июня 2011

Кажется, ваш скрипт компоновщика пытается сжать изображение для хранения во флэш-памяти. Во время выполнения ваше изображение копируется на другие адреса, возможно из-за ограничений выравнивания MMU.

Создает ли компоновщик сообщение об ошибке или это просто ваш код работает неправильно во время выполнения?

Упомянутая вами проблема с копированием может быть легко обойдена, если вы скопируете разделы «назад».

Скопируйте последний элемент раздела .data в его адрес времени выполнения, а затем скопируйте следующий за последним элемент в его адрес времени выполнения ...

...