On 19.12.12 17:53, Weddington, Eric wrote: > Hi Erik, > > So far, I like how you're describing it below. > > Did I miss the actual linker script that you're proposing? Do you have a > patch? > > Eric
Oops, if I left it off, here it is, attached this time, since Johann says it's easier to grab that than if I in-line it. (Some lists delete attachments, so I wasn't game to begin with.) Johann's test macros make it much quicker to test linker scripts, and the test results (also attached) use them. (And that's where objdump -h is a lot quicker for checking results, than shuffling through a big map file.) The new script architecture is standing up well to tests and unanticipated challenges, like the .bootloader commandline stuff which Johann has added to our tests. The approach is one I've successfully used in industry for a couple of decades, facing all challenges, so we should be able to make a good fist of handling all that the AVR needs. I'll add __memx in a couple of weeks, as well as anything which crops up in the interim. (I'm "heading bush" for Christmas, in a few minutes. The car is loaded. So it might be safer to send the whole linker script, just in case of patch difficulties at your end.) Johann has mentioned that some users have let .progmem.data grow very large. That would trigger the assertion we've added to warn us of overflow of the lower 128 KiB (.lowtext). If I've picked up correctly on Johann's concern, then it might be better to move .progmem.data* to the start of .hightext? The script will still locate it in the same place if there's no __flashN, and as low as practicable, if there is. And now .progmem.data* can handle the legacy use case more robustly. Is that a way to go? Merry Christmas to all, Erik
/* Default linker script, for normal executables */ OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") OUTPUT_ARCH(avr:6) MEMORY { text (rx) : ORIGIN = 0, LENGTH = 1024K data (rw!x) : ORIGIN = 0x800200, LENGTH = 0xfe00 eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K } SECTIONS { /* Read-only sections, merged into text segment: */ .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } .rel.init : { *(.rel.init) } .rela.init : { *(.rela.init) } .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } .rela.text : { *(.rela.text) *(.rela.text.*) *(.rela.gnu.linkonce.t*) } .rel.fini : { *(.rel.fini) } .rela.fini : { *(.rela.fini) } .rel.rodata : { *(.rel.rodata) *(.rel.rodata.*) *(.rel.gnu.linkonce.r*) } .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } .rela.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } .rel.ctors : { *(.rel.ctors) } .rela.ctors : { *(.rela.ctors) } .rel.dtors : { *(.rel.dtors) } .rela.dtors : { *(.rela.dtors) } .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.bss : { *(.rel.bss) } .rela.bss : { *(.rela.bss) } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } /* Internal text space or external memory. */ .lowtext : { *(.vectors) KEEP(*(.vectors)) /* For data that needs to reside in the lower 64k of progmem. */ *(.progmem.gcc*) . = ALIGN(2); __trampolines_start = . ; /* The jump trampolines for the 16-bit limited relocs will reside here. */ *(.trampolines) *(.trampolines*) __trampolines_end = . ; /* For future tablejump instruction arrays for 3 byte pc devices. We don't relax jump/call instructions within these sections. */ *(.jumptables) *(.jumptables*) /* For code that needs to reside in the lower 128k progmem. */ *(.lowtext) *(.lowtext*) __ctors_start = . ; *(.ctors) __ctors_end = . ; __dtors_start = . ; *(.dtors) __dtors_end = . ; KEEP(SORT(*)(.ctors)) KEEP(SORT(*)(.dtors)) *(.progmem.data*) /* Explicitly page 0 input sections */ _elowtext = . ; x = ASSERT (. <= 0x20000, "Error: .lowtext (128KiB limit) overflow. Try shrinking .progmem?") ; } > text .flash1 0x10000 : { *(.progmem1.data*) /* Page 1 */ } > text .flash2 0x20000 : { *(.progmem2.data*) /* Page 2 */ } > text .flash3 0x30000 : { *(.progmem3.data*) /* Page 3 */ } > text .flash4 0x40000 : { *(.progmem4.data*) /* Page 4 */ } > text .flash5 0x50000 : { *(.progmem5.data*) /* Page 5 */ } > text .hightext : { /* The following is OK to follow preceding sections at any even byte address, on any page. */ . = ALIGN(2) ; *(.init0) /* Start here after reset. */ KEEP (*(.init0)) *(.init1) KEEP (*(.init1)) *(.init2) /* Clear __zero_reg__, set up stack pointer. */ KEEP (*(.init2)) *(.init3) KEEP (*(.init3)) *(.init4) /* Initialize data and BSS. */ KEEP (*(.init4)) *(.init5) KEEP (*(.init5)) *(.init6) /* C++ constructors. */ KEEP (*(.init6)) *(.init7) KEEP (*(.init7)) *(.init8) KEEP (*(.init8)) *(.init9) /* Call main(). */ KEEP (*(.init9)) *(.text) . = ALIGN(2); *(.text.*) . = ALIGN(2); *(.fini9) /* _exit() starts here. */ KEEP (*(.fini9)) *(.fini8) KEEP (*(.fini8)) *(.fini7) KEEP (*(.fini7)) *(.fini6) /* C++ destructors. */ KEEP (*(.fini6)) *(.fini5) KEEP (*(.fini5)) *(.fini4) KEEP (*(.fini4)) *(.fini3) KEEP (*(.fini3)) *(.fini2) KEEP (*(.fini2)) *(.fini1) KEEP (*(.fini1)) *(.fini0) /* Infinite loop after program termination. */ KEEP (*(.fini0)) _etext = . ; } > text .data : AT (_etext) { PROVIDE (__data_start = .) ; /* --gc-sections will delete empty .data. This leads to wrong start addresses for subsequent sections because -Tdata= from the command line will have no effect, see PR13697. Thus, keep .data */ KEEP (*(.data)) *(.data*) *(.rodata) /* We need to include .rodata here if gcc is used */ *(.rodata*) /* with -fdata-sections. */ *(.gnu.linkonce.d*) . = ALIGN(2); _edata = . ; PROVIDE (__data_end = .) ; } > data .bss : AT (ADDR (.bss)) { PROVIDE (__bss_start = .) ; *(.bss) *(.bss*) *(COMMON) PROVIDE (__bss_end = .) ; } > data __data_load_start = LOADADDR(.data); __data_load_end = __data_load_start + SIZEOF(.data); /* Global data not cleared after reset. */ .noinit : { PROVIDE (__noinit_start = .) ; *(.noinit*) PROVIDE (__noinit_end = .) ; _end = . ; PROVIDE (__heap_start = .) ; } > data .eeprom : { *(.eeprom*) __eeprom_end = . ; } > eeprom .fuse : { KEEP(*(.fuse)) KEEP(*(.lfuse)) KEEP(*(.hfuse)) KEEP(*(.efuse)) } > fuse .lock : { KEEP(*(.lock*)) } > lock .signature : { KEEP(*(.signature*)) } > signature x = ASSERT (SIZEOF(.flash1) <= 0x10000, "Error: __flash1 (64KiB limit) overflow. Need to shrink it.") ; x = ASSERT (SIZEOF(.flash2) <= 0x10000, "Error: __flash2 (64KiB limit) overflow. Need to shrink it.") ; x = ASSERT (SIZEOF(.flash3) <= 0x10000, "Error: __flash3 (64KiB limit) overflow. Need to shrink it.") ; x = ASSERT (SIZEOF(.flash4) <= 0x10000, "Error: __flash4 (64KiB limit) overflow. Need to shrink it.") ; x = ASSERT (SIZEOF(.flash5) <= 0x10000, "Error: __flash5 (64KiB limit) overflow. Need to shrink it.") ; /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* 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) *(.gnu.linkonce.wi.*) } .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) } /* DWARF 3 */ .debug_pubtypes 0 : { *(.debug_pubtypes) } .debug_ranges 0 : { *(.debug_ranges) } /* DWARF Extension. */ .debug_macro 0 : { *(.debug_macro) } }
Message-ID: <20121217040154.GB2020@ratatosk> Tests and Expected Results -------------------------- Trampolines, etc., must be in lower 128 KiB: Just fits in: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP0=0x1f000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800200 0003f16e 0003f1e2 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .lowtext 0001f10c 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .hightext 00020062 0001f10c 0001f10c 0001f180 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE .data LMA butts up to .hightext, which butts up to .lowtext. Overflows: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP0=0x20000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Error: .lowtext (128KiB limit) overflow. Try shrinking .progmem? Locate __flashN at 0xN0000: Just fits in: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP1=0x10000 -DP3=0x87ff -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800200 00058862 00038a22 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .lowtext 0000010c 00000000 00000000 000000b4 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .flash1 00010000 00010000 00010000 000001c0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .flash3 000087ff 00030000 00030000 000101c0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .hightext 00020063 000387ff 000387ff 000189bf 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE Note: .hightext (where input section .text goes) butts up to 000387ff, using all spare .flash3. (From the next even byte address, inside .hightext.) .data in flash does the same with .hightext, at 00058862. Overflows: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP1=0x10001 -DP3=0x10001 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Error: __flash1 (64KiB limit) overflow. Need to shrink it Error: __flash3 (64KiB limit) overflow. Need to shrink it. Overlaps prior section: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP0=0x10000 -DP1=0x87ff -DTEXT=0x20000 -mmcu=atmega2560 flash.sx section .flash1 loaded at [00010000,000187fe] overlaps section .lowtext loaded at [00000000,0001010b] flash.elf: section .flash1 vma 0x10000 overlaps previous sections but ld also says this, which isn't helpful: section .hightext vma 0x187ff overlaps previous sections Overlaps following section: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DP1=0x10001 -DP2=0x87ff -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Error: __flash1 (64KiB limit) overflow. Need to shrink it. section .flash2 loaded at [00020000,000287fe] overlaps section .flash1 loaded at [00010000,00020000] flash.elf: section .flash2 vma 0x20000 overlaps previous sections and again: flash.elf: section .hightext vma 0x287ff overlaps previous sections The bulk of code (.text -> .hightext) snugs down if there are no __flashN: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \ -DTEXT=0x20000 -mmcu=atmega2560 flash.sx Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800200 0002016e 000201e2 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .lowtext 0000010c 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .hightext 00020062 0000010c 0000010c 00000180 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE .hightext now follows imediately from .lowtext.
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list