|
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) 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
example.tar.gz
Description: application/gzip
OpenPGP_signature
Description: OpenPGP digital signature
[Prev in Thread] | Current Thread | [Next in Thread] |