bug-binutils
[Top][All Lists]
Advanced

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

Binutils/ld: linker script does not work for AVR mega 0 series (avrxmega


From: Konrad Rosenbaum
Subject: Binutils/ld: linker script does not work for AVR mega 0 series (avrxmega3)
Date: Sun, 23 Oct 2022 18:45:56 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.0

Hi,

the linker fails on trying to arrange data/bss segments even with very few small variables. E.g.:

avr-g++ -Os -Wl,--gc-sections -B ~/tronic/atmel-compiler-packs/mega/gcc/dev/atmega3208 -mmcu=atmega3208 -o fw.elf dimmer.o dmx.o input.o ledout.o pwm.o
<...>/lib/gcc/avr/12.2.0/../../../../avr/bin/ld: address 0x803004 of fw.elf section `.bss' is not within region `data'
<...>/lib/gcc/avr/12.2.0/../../../../avr/bin/ld: address 0x803004 of fw.elf section `.bss' is not within region `data'

(AVR) Binutils: tested with version 2.35.1 and 2.39

(AVR) GCC/G++: tested with 12.2.0 and 11.2.0

Host: Debian GNU/Linux 11.4 x86_64, with source compiled GCC 12.2.0 and Binutils 2.39 set as standard build tools.

In addition I'm using the "Atmel Compiler Pack" for AtMega version 2.0.401, since the 0-series is still not supported by vanilla AVR-GCC.


This is a regression. It definitely works with the tools in Arduino 1.8.15 for Linux: GCC 7.3.0 and Binutils 2.26.20160125.


The source can be trivial, as long as it allocates heap, see the attached example. C or C++ does not make a difference.

To compile the example download the compiler pack and correct the AVRBASE variable in Makefile. You can switch between MCU types by setting MCUS/MCUL at the top.


I narrowed the problem down to the Linker script avrxmega3.xn - it somehow messes up the data segment in the MEMORY section at the top. I was able to get it to link by changing that line:

-  data   (rw!x) : ORIGIN = 0x802000, LENGTH = __DATA_REGION_LENGTH__
+  data   (rw!x) : ORIGIN = 0x802000, LENGTH = 0x10000

The fixed origin seems very dubious to me and I wasn't able to debug __DATA_REGION_LENGTH__. I consider my fix "an ugly hack". The linker script in Arduino looks more elegant and also works:

__DATA_REGION_ORIGIN__ = DEFINED(__DATA_REGION_ORIGIN__) ? __DATA_REGION_ORIGIN__ : 0x802000;
//...
data   (rw!x) : ORIGIN = __DATA_REGION_ORIGIN__, LENGTH = __DATA_REGION_LENGTH__

If it is safe to do so the line should be changed back. Probably also in the other script files for avrxmega3.x*.


MCUs that I tried:

AtMega 1608 (atmega1608, m1608): fails with any source even without data, real data start 0x803800, real data length 2kB

AtMega 3208 (atmega3208, m3208): fails with source that allocates heap data, real data start 0x803000, real data length 4kB

AtMega 4808 (atmega4808, m4808): did not fail during my tests, even though it is almost identical to the above, real data start 0x802800, real data length 6kB

The real data start is set in the device spec files with -Tdata... ; I could not find anywhere where the real RAM size is set.



    Konrad

Attachment: example.tar.gz
Description: application/gzip

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


reply via email to

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