Hi,
I'm using:
* arm-none-eabi-gcc (GNU MCU Eclipse ARM Embedded GCC, 64-bit) 8.2.1 20181213 (release) [gcc-8-branch revision 267074]
* ChibiOS from github stable_19.1.x branch (git hash 71a12f9) May 17, 2019
* Nucleo144 F767I board
* openOCD 20190426
and have severe problems with the created elf file, which I fixed with an intermediate patch of the used STM32F76xxI.ld file.
The original link file uses flash0 as physical and flash1 as 'virtual' (LMA) memory.
vectors are mapped to physical other text is mapped to LMA, this
works as long as no padding between the two is introduced.
But this actually happens and seems to be depending on a lot of
things in gcc 8.2.1, like LTO and optimization flags.
It directly affects the reset vector which does not not point
to the actual entry code, but somewhere else (offset is up to 50 bytes or so).
The intermediate fix is:
All LMA sections (of constant memory) are directed to flash 0
which is the ITC area, i.e. the linker does not generate addresses
in AIX. This works as OpenOCD has a virtual flash bank that redirects
flash writes to ITC into AIX.
Additional information:
- objdump only shows virtual memory, one cannot see the trouble there
- objcopy generates binaries to physical memory, the problem is apparent
- readelf shows the virtual to physical memory mapping and gaps are
visible as-well
I am unable to create a simple example that shows the effect as it almost never happens, but here is what readelf -a of my program says:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x077694 0x00237694 0x0804ca98 0x00008 0x00008 R 0x4
LOAD 0x010000 0x00200000 0x08000000 0x0020c 0x0020c RWE 0x10000
LOAD 0x010240 0x00200240 0x0800020c 0x37454 0x37454 R E 0x10000
LOAD 0x057660 0x08037660 0x08037660 0x15438 0x15438 R 0x10000
LOAD 0x077694 0x00237694 0x0804ca98 0x00008 0x00008 R 0x10000
LOAD 0x080000 0x20020000 0x0804caa0 0x00b7c 0x00b7c RW 0x10000
LOAD 0x090000 0x20000000 0x20000000 0x00000 0x03d6c RW 0x10000
LOAD 0x080b7c 0x20020b7c 0x20020b7c 0x00000 0x5f484 RW 0x10000
The mismatch in the highlighted section 0x...240 --> 0x...20c makes the CPU jump to the wrong location right after reset.
Helmut
linking troubles with STM32F platforms Topic is solved
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: linking troubles with STM32F platforms
Hi,
Thanks for the report, I will look into this. An example would help a lot... Could you post at least your map file (zipped)?
Giovanni
Thanks for the report, I will look into this. An example would help a lot... Could you post at least your map file (zipped)?
Giovanni
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: linking troubles with STM32F platforms
Hi,
Could you check if changing rules_code.ld fixes the problem?
It could be an alignment issue. Text was aligning to 16 in VMA and to 4 in LMA. The trigger was the presence of static constructors (which you don't usually have in C).
Giovanni
Could you check if changing rules_code.ld fixes the problem?
Code: Select all
.text : ALIGN(16) <---- THIS
{
__text_base = .;
*(.text)
*(.text.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
__text_end = .;
} > TEXT_FLASH AT > TEXT_FLASH_LMA
It could be an alignment issue. Text was aligning to 16 in VMA and to 4 in LMA. The trigger was the presence of static constructors (which you don't usually have in C).
Giovanni
Re: linking troubles with STM32F platforms
Hi,
yeah I've tried the very same change already, but this does not fix the issue. It aligns the text segment to 16 byte boundaries, but the reset vector offset is off by several 16 byte blocks, with your change readelf says:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x077694 0x00237694 0x0804caa0 0x00008 0x00008 R 0x4
LOAD 0x010000 0x00200000 0x08000000 0x0020c 0x0020c RWE 0x10000
LOAD 0x010240 0x00200240 0x08000210 0x37454 0x37454 R E 0x10000
LOAD 0x057668 0x08037668 0x08037668 0x15438 0x15438 R 0x10000
LOAD 0x077694 0x00237694 0x0804caa0 0x00008 0x00008 R 0x10000
LOAD 0x080000 0x20020000 0x0804caa8 0x00b7c 0x00b7c RW 0x10000
LOAD 0x090000 0x20000000 0x20000000 0x00000 0x03d6c RW 0x10000
LOAD 0x080b7c 0x20020b7c 0x20020b7c 0x00000 0x5f484 RW 0x10000
So the physical address went up from 0x800020c to 0x8000210, but it's still not at 0x8000240 which corresponds to 0x200240.
Helmut
yeah I've tried the very same change already, but this does not fix the issue. It aligns the text segment to 16 byte boundaries, but the reset vector offset is off by several 16 byte blocks, with your change readelf says:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x077694 0x00237694 0x0804caa0 0x00008 0x00008 R 0x4
LOAD 0x010000 0x00200000 0x08000000 0x0020c 0x0020c RWE 0x10000
LOAD 0x010240 0x00200240 0x08000210 0x37454 0x37454 R E 0x10000
LOAD 0x057668 0x08037668 0x08037668 0x15438 0x15438 R 0x10000
LOAD 0x077694 0x00237694 0x0804caa0 0x00008 0x00008 R 0x10000
LOAD 0x080000 0x20020000 0x0804caa8 0x00b7c 0x00b7c RW 0x10000
LOAD 0x090000 0x20000000 0x20000000 0x00000 0x03d6c RW 0x10000
LOAD 0x080b7c 0x20020b7c 0x20020b7c 0x00000 0x5f484 RW 0x10000
So the physical address went up from 0x800020c to 0x8000210, but it's still not at 0x8000240 which corresponds to 0x200240.
Helmut
Re: linking troubles with STM32F platforms
Again ...
the actual issue is IMHO: Why is the reset vector at 0x...240 as the vectors always consume 0x200 bytes. If I change certain settings
during compilation (optimization and LTO) I sometimes get elf files where reset is at 0x...200, it works then (obviously).
Helmut
the actual issue is IMHO: Why is the reset vector at 0x...240 as the vectors always consume 0x200 bytes. If I change certain settings
during compilation (optimization and LTO) I sometimes get elf files where reset is at 0x...200, it works then (obviously).
Helmut
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: linking troubles with STM32F platforms
Is there anything that is enforcing a 64bytes alignment? perhaps compiler-generated code? 0x20C->0x240 still looks as an alignment problem.
Giovanni
Giovanni
Re: linking troubles with STM32F platforms
Nothing I can think of, but the program is pretty large incorporating quite a few 3rd party sources (mostly C++), like:
Helmut
- Eigen ... http://eigen.tuxfamily.org
- tinyfsm ... https://github.com/digint/tinyfsm
- UKF ... https://github.com/sfwa/ukf
- and some more
- USE_FPU = hard
- USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv5-d16
- MCU = cortex-m7
- LD = arm-none-eabi-g++
- and my adapted C++ wrappers (viewtopic.php?t=3287) converted to ChibiOS 19.1.x
Helmut
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: linking troubles with STM32F platforms
Could you try excluding subsystems from your project and see which one triggers it?
Giovanni
Giovanni
Re: linking troubles with STM32F platforms
Ok I got something ...
I removed all but shell from my main.cpp file, but still linked all the sources in my project.
All of it (well mostly) is removed by link garbage collection, but ...
The non-empty fini-array stuff seems to force the separation in the text segments. I define
Obviously the use of _fini() is obsolete, need to investigate further ...
Helmut
I removed all but shell from my main.cpp file, but still linked all the sources in my project.
All of it (well mostly) is removed by link garbage collection, but ...
Code: Select all
------------------------------ diff of the map files if I add one CPP file or leave it away ------------------
797c797
< .xtors 0x0000000000200200 0x8 load address 0x0000000008000200
---
> .xtors 0x0000000000200200 0x0 load address 0x0000000008000200
801,803c801,802
< .init_array 0x0000000000200200 0x4 /tmp/ccR5mVq2.ltrans0.ltrans.o
< 0x0000000000200204 __init_array_end = .
< 0x0000000000200204 __fini_array_start = .
---
> 0x0000000000200200 __init_array_end = .
> 0x0000000000200200 __fini_array_start = .
805d803
< .fini_array 0x0000000000200204 0x4 /tmp/ccR5mVq2.ltrans0.ltrans.o
807c805
< 0x0000000000200208 __fini_array_end = .
---
> 0x0000000000200200 __fini_array_end = .
809,810c807,808
< .text 0x0000000000200220 0x9c48 load address 0x0000000008000208
< 0x0000000000200220 __text_base = .
---
> .text 0x0000000000200200 0x99e8 load address 0x0000000008000200
> 0x0000000000200200 __text_base = .
The non-empty fini-array stuff seems to force the separation in the text segments. I define
Code: Select all
extern "C" void _fini(void);
__attribute__((used)) void _fini(void) { }
Obviously the use of _fini() is obsolete, need to investigate further ...
Helmut
Who is online
Users browsing this forum: No registered users and 36 guests