Open joelsa opened 1 year ago
I can confirm this bug for STM32G4 and SAMV71; and it's probably related to modm because programming *.elf
files produced from the stm32-rs framework work fine with the recent OpenOCD versions.
The error does not depend on the GCC version, I can reproduce it with GCC10 and GCC12 (ARM and xPack variants).
The code section in OpenOCD that emits the error has not been touched in the last 5 years: https://github.com/openocd-org/openocd/blob/b6b4f9d46a48aadc1de6bb5152ff4913661c9059/src/flash/nor/core.c#L806-L818
I assume change 7513 (_target/image: zero-initialize ELF segments up to pmemsz) in OpenOCD causes our issue.
It must be an issue with our linkerscript, I just remembered that this sounded familiar: https://github.com/modm-io/modm/discussions/922
I might have found the issue.
readelf -Wl
for SAMV71 blink example:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00400000 0x00400000 0x01148 0x01148 RWE 0x10000
LOAD 0x020c00 0x20400c00 0x00401148 0x0000c 0x0000c RW 0x10000
LOAD 0x021154 0x00401154 0x00401154 0x00044 0x00044 RW 0x10000
LOAD 0x000c0c 0x20400c0c 0x00401154 0x00000 0x00108 RW 0x10000
LOAD 0x000d14 0x20400d14 0x00401154 0x00000 0x5f2ec RW 0x10000
LOAD 0x000000 0x20400000 0x20400000 0x00000 0x00c00 RW 0x10000
NOTE 0x010168 0x00400168 0x00400168 0x00024 0x00024 R 0x4
Section to Segment mapping:
Segment Sections...
00 .text .build_id .text .rodata
01 .data .fastdata
02 .rodata
03 .bss
04 .noinit .heap_ram
05 .stack
06 .build_id
.bss
has PhysAddr
of 0x00401154
which is in flash and also the start address of .rodata
. That makes no sense. The .bss
section should be in RAM only.
The change in openocd @rleh linked removes the code that ignores sections with zero file size (like .bss
) when loading flash sections from the elf file. Now openocd tries to load .bss
into flash.
.noinit
and .heap_ram
have similar issues.
When I move the .rodata
tables section before .bss
in the generated linker script the result looks more reasonable:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00400000 0x00400000 0x01148 0x01148 RWE 0x10000
LOAD 0x020c00 0x20400c00 0x00401148 0x0000c 0x0000c RW 0x10000
LOAD 0x021154 0x00401154 0x00401154 0x00044 0x00044 RW 0x10000
LOAD 0x000000 0x20400000 0x20400000 0x00000 0x60000 RW 0x10000
NOTE 0x010168 0x00400168 0x00400168 0x00024 0x00024 R 0x4
Section to Segment mapping:
Segment Sections...
00 .text .build_id .text .rodata
01 .data .fastdata
02 .rodata
03 .stack .bss .noinit .heap_ram
04 .build_id
I have tried to fix the openocd programming issue with the development build but I suspect that the openocd development branch is currently broken. Even if all the addresses in the ELF file are correct it tries to program the NOLOAD sections which are correctly marked NOBITS
.
xPSR: 0x01000000 pc: 0x00400820 msp: 0x20400c00
** Programming Started **
Info : device id = 0xa1220e01
Info : erasing lock regions 0-0...
Info : erasing lock region 0
Warn : no flash bank found for address 0x20400000
** Programming Finished **
** Verify Started **
Error: checksum mismatch - attempting binary compare
Error: error reading data: (null)
Error: CMSIS-DAP command mismatch. Expected 0x6 received 0x5
Error: CMSIS-DAP command mismatch. Expected 0x5 received 0x6
Error: CMSIS-DAP command mismatch. Expected 0x6 received 0x5
Error: CMSIS-DAP command mismatch. Sent 0x3 received 0x6
Error: CMSIS-DAP command CMD_DISCONNECT failed.
Info : SWD DPIDR 0x0bd11477
Error: Failed to read memory at 0x20441f8c
embedded:startup.tcl:1510: Error: ** Verify Failed **
It skips programming the RAM sections with a warning because it knows there is no flash at these addresses but verification fails afterwards for the RAM sections.
EDIT: There must be something else wrong. I have found some other ELF files that work, but the one generated by the Rust toolchain also outputs Warn : no flash bank found for address 0x20000008
.
Interesting! It may be interesting to use pyelftools to write a test that actually validates the assumptions we make about our linkerscripts. Sections of certain naming schemes in the right place, alignment properties fulfilled, correct order of sections. We've had a number of these bugs already. I guess I'll put it on my TODO list…
With recent OpenOCD development builds of OpenOCD (such as https://github.com/rleh/openocd-build/releases/tag/0.12.0%2Bdev-snapshot.20230320.2313 or https://github.com/rleh/openocd-build/releases/tag/0.12.0%2Bdev-snapshot.20230307.1505)
Scons program
fails on Ubuntu 22.04 with the error:Error: Section at 0x0800XXXX overlaps section ending at 0x0800XXXX
The behavior is persistent across several machines I tested and occurs with different programmers (Tested J-Link and ST-LInk).
One example output for the Nucleo F446RE Blink Example is
Error: Section at 0x080012ac overlaps section ending at 0x080012f0
Here are some files maybe relevant for this (.elf, .map, .lss and linkerscript):
scons-release.zip
I am not sure if the problem is due to the linkerscript or due to OpenOCD incorrectly assuming the overlap, but in any case this can serve as a cautionary heads-up.