2011-06-27 16 views
0

私はリンカスクリプトの概念が新しくなっています。 私はいくつかの奇妙な問題に遭遇しました。.data LMA overapps .data VMAアドレス

セクションにVMAの正しいアドレスがないようです。

たとえば、LMA +サイズで提供されているVMAを.dataセクションで見ると、 (LMAからVMAにデータをコピーすると、起動時にLMAアドレスの最後のバイトが上書きされたことを意味します)

これは結果がどのように見えるかを示しています。 :

 
    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: 私はすべてのを作るエラー/警告を取得していません。 リンカーは、それがフラッシュに格納するために画像を圧縮しようとするskriptリンカ思わ0x20の000000

答えて

1

で始まると外部メモリのためにすべてを構築することとしています。 実行時に、MMUの配置制限のために画像が他のアドレスにコピーされる可能性があります。

リンカはエラーメッセージを表示するか、実行時にコードが正しく動作しないことがありますか?

上記のコピーの問題は、セクションを「後方に」コピーすると簡単に回避できます。その後、

コピー実行時のアドレスへの.dataセクションの最後の項目、その実行時のアドレスの横ツー最後の項目をコピー...

+0

多くの変更があるため、リンカスクリプトで任意のコメントを削除してくださいは、実際にコメントを更新することなく人々によって行われています。リンカは0x20000000で始まる外部メモリ用のイメージを構築する必要があります。あなたが提案しているものはうまくいくはずですが、それは汚れたハックのようです。あなたはこの不当なVMA/LMAアドレスの理由を知っていますか?私がelf/mapファイルをチェックすると、すべてがすべて0x20 xxx xxxアドレスにあることを意味するように見えます。 – theAlse

+0

あなたが構築したイメージは、何らかの種類の組み込みシステムに何らかのブートローダによって転送されていると思います。ほとんどのブートローダは、何らかのタイプのフラッシュまたはネットワーク接続を介して連続的なバイトブロックとしてイメージをリッピングします。画像のどの隙間(例えば、.xptcnと.extramは、明示的なゼロとして保存/送信されなければならないでしょう - スペース/帯域幅の浪費。)したがって、必要な空白なしでセクションを次々にタックすることによって画像は "圧縮"されます。画像自体は、最終的な実行時のアドレスにセクションをコピーする責任がある。 – wpaulus

+0

ので、逆方向にコピーすると、このような状況ではハックではありません。あなたは、彼らが連続していることがわかります画像のLMAを追加した場合。 – wpaulus