我对链接器脚本概念很陌生。 我遇到了一些奇怪的问题。
这些部分似乎没有适合VMA的地址。
例如,如果我们查看.data部分中已在LMA +大小内提供的VMA。 (意思是在启动期间,一旦我将数据从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。
答案 0 :(得分:1)
似乎您的链接器skript尝试压缩图像以便在闪存中存储。 在运行期间,您的图像可能因MMU对齐限制而被复制到其他地址。
链接器是否发出错误消息,或者仅仅是您的代码在运行时没有正常运行?
如果您将这些部分“向后”复制,则可以轻松绕过您提到的复制问题。
将.data部分的最后一项复制到其运行时地址,然后将倒数第二项复制到其运行时地址...