avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Linker script patch to handle __flashN


From: Erik Christiansen
Subject: Re: [avr-gcc-list] Linker script patch to handle __flashN
Date: Sat, 15 Dec 2012 15:29:50 +1100
User-agent: Mutt/1.5.20 (2009-06-14)

On 13.12.12 14:26, Georg-Johann Lay wrote:
> Here is more torture.

Thank you. That significantly speeded up trying the following use cases.

After making a list of requirements from upthread┬╣, and further
modifying the linker script to squeeze __flashN in between .lowmem and
.text, here's some sample initial test results for some of the linker
script changes. Please point out anything that does not accord with the
requirements.

Req:
Error detection on .trampolines, .progmem*, or .lowmem, overflowing 128KiB.

Test: Overflow the low 128 KiB:
$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \
  -DP0=0x20000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx

Result:
"../avr/bin/ld: Error: .lowtext (128KiB limit) overflow. Try shrinking
.progmem?"

The message is repeated, apparently once for each following empty
__flashN output section. We'll try to find a way to improve the
aesthetics.

The desired error message was also initially preceded by an "internal
error: out of range error" on each stub, as they were pushed over the
128KiB edge. So I've moved .progmem.data* to the end of the output
sction, thus cleaning up the error messages significantly.

Req: Locate .progmemN.data at 0xN0000, and flag overlaps.

Test: Overlap two __flashN:
$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \
  -DP1=0x18000 -DP2=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx

Result:
../avr/bin/ld: section .flash2 loaded at [00020000,0002ffff] overlaps
section .flash1 loaded at [00010000,00027fff]
../avr/bin/ld: flash.elf: section .flash2 vma 0x20000 overlaps previous
sections
../avr/bin/ld: flash.elf: section .hightext vma 0x30000 overlaps
previous sections

The last line seems to be like a gcc consequential error. We have to
clean up the first one before we can know it didn't cause the last one.

Test: Locate two __flashN, without overlap:
$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \
  -DP1=0x8000 -DP2=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx

Result:
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000000  00800200  00050062  00038222  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .lowtext      0000010c  00000000  00000000  000000b4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .flash1       00008000  00010000  00010000  000001c0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .flash2       00010000  00020000  00020000  000081c0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .hightext     00020062  00030000  00030000  000181c0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

The trampolines etc. in .lowtext go from 0 to 0x10c.
We see .flash1 at 00010000, and .flash2 at 00020000, as required.
The rest of .text butts up to the end of .flash2.
And the LMA of .data butts up to the end of .hightext, at
00030000 + 00020062 = 00050062
That leaves only the holes specified by the user, before each .flashN.

And if there are no __flashN, it concertinas further, as Jan told us it
should:

$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 \
  -DTEXT=0x20000 -mmcu=atmega2560 flash.sx

Sections:
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

The trampolines etc. in .lowtext go from 0 to 0x10c.
The rest of .text, i.e. .hightext,  now butts up to the end of
.lowtext, at 0x10c.
And the LMA of .data butts up to the end of .hightext, at
00020062 + 0000010c = 0002016e

Why are we checking .data LMA? Because the expression for that had to be
tweaked for the new script architecture. (And it was made simpler,
rather than yet more complicated. That needs double checking.)

Please try some other use cases, to see if any further tweaking is
needed already now. Often, more requirements come to light at this
stage. Perhaps more error detection?

The linker script patch is appended below.

Erik

┬╣ Where it did explain why it's 2^17. I've been away from AVRs for too
  long.

file: avr6.patch
--- avr6.x-2.23 2012-12-13 13:42:18.000000000 +1100
+++ avr6.x-new  2012-12-15 14:12:07.000000000 +1100
@@ -70,13 +70,12 @@
   .rel.plt       : { *(.rel.plt)               }
   .rela.plt      : { *(.rela.plt)              }
   /* Internal text space or external memory.  */
-  .text   :
+  .lowtext :
   {
     *(.vectors)
     KEEP(*(.vectors))
     /* For data that needs to reside in the lower 64k of progmem.  */
     *(.progmem.gcc*)
-    *(.progmem*)
     . = ALIGN(2);
      __trampolines_start = . ;
     /* The jump trampolines for the 16-bit limited relocs will reside here.  */
@@ -98,6 +97,25 @@
      __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
+
+   .hightext :
+   {
     /* From this point on, we don't bother about wether the insns are
        below or above the 16 bits boundary.  */
     *(.init0)  /* Start here after reset.  */
@@ -146,7 +164,8 @@
     KEEP (*(.fini0))
      _etext = . ;
   }  > text
-  .data          : AT (ADDR (.text) + SIZEOF (.text))
+
+  .data          : AT (_etext)
   {
      PROVIDE (__data_start = .) ;
     /* --gc-sections will delete empty .data. This leads to wrong start


-- 
Any project you tackle is always hardest at the beginning, like working
up a swing.                                                - P.K. Shaw




reply via email to

[Prev in Thread] Current Thread [Next in Thread]