linking troubles with STM32F platforms Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

linking troubles with STM32F platforms  Topic is solved

Postby _helmut_ » Thu Jun 06, 2019 9:36 am

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

User avatar
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

Postby Giovanni » Thu Jun 06, 2019 10:07 am

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

_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

Re: linking troubles with STM32F7 platforms

Postby _helmut_ » Thu Jun 06, 2019 10:23 am

Hi,

I've attached the map file.
Helmut
Attachments
ch.map.gz
(59.18 KiB) Downloaded 114 times

User avatar
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

Postby Giovanni » Sun Jun 09, 2019 6:38 am

Hi,

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

_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

Re: linking troubles with STM32F platforms

Postby _helmut_ » Tue Jun 11, 2019 9:10 am

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

_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

Re: linking troubles with STM32F platforms

Postby _helmut_ » Tue Jun 11, 2019 9:14 am

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

User avatar
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

Postby Giovanni » Tue Jun 11, 2019 10:00 am

Is there anything that is enforcing a 64bytes alignment? perhaps compiler-generated code? 0x20C->0x240 still looks as an alignment problem.

Giovanni

_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

Re: linking troubles with STM32F platforms

Postby _helmut_ » Tue Jun 11, 2019 12:13 pm

Nothing I can think of, but the program is pretty large incorporating quite a few 3rd party sources (mostly C++), like:

It uses
  • 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
As I mentioned earlier I wasn't able to create a simple test that shows the problem.
Helmut

User avatar
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

Postby Giovanni » Tue Jun 11, 2019 1:38 pm

Could you try excluding subsystems from your project and see which one triggers it?

Giovanni

_helmut_
Posts: 7
Joined: Thu Jun 06, 2019 8:50 am
Has thanked: 1 time
Been thanked: 2 times

Re: linking troubles with STM32F platforms

Postby _helmut_ » Tue Jun 11, 2019 4:46 pm

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 ...

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


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 36 guests