Skip to content

fix(linker): correct cross-toolchain memory map inconsistencies#24

Open
94xhn wants to merge 1 commit into
STMicroelectronics:masterfrom
94xhn:fix/linker-cross-toolchain-audit
Open

fix(linker): correct cross-toolchain memory map inconsistencies#24
94xhn wants to merge 1 commit into
STMicroelectronics:masterfrom
94xhn:fix/linker-cross-toolchain-audit

Conversation

@94xhn

@94xhn 94xhn commented Jul 11, 2026

Copy link
Copy Markdown

Summary

This PR cross-references the memory-map declarations across the three toolchains shipped with each Projects/<board>/<project> folder — GCC (SW4STM32), IAR (EWARM/*.icf), and Keil (MDK-ARM/*.uvprojx) — against each other and against the board's own Templates project (or ST's documented flash-partition figures where applicable). It fixes five independent, verified inconsistencies. No source/HAL code is touched; only linker-related memory-map fields in .ld, .icf, and .uvprojx files.

1. STM32303E_EVAL — Applications/IAP/IAP_Binary_Template

IAP_Main documents the intended flash partition explicitly in its readme.txt:

The user application ... will be programmed starting from address 0x08004000.
The maximum size of the image to be loaded is: 496 Kbytes

The GCC linker script (SW4STM32/.../STM32F303VETx_FLASH.ld) already implements this correctly: FLASH ORIGIN = 0x08004000, LENGTH = 496K.

But:

  • EWARM/stm32f303xe_flash.icf: __ICFEDIT_region_ROM_start__ was still 0x08000000 (the full flash, including the 16K reserved for IAP_Main), while ROM_end stayed at 0x0807FFFF. This lets IAR place readonly sections anywhere from 0x08000000, overlapping the bootloader's own code.
  • MDK-ARM/Project.uvprojx: OCR_RVCT4 (IROM1, the region actually used by armlink since Ir1Chk=1 and <ScatterFile> is empty) kept Size=0x80000 (512K) with StartAddress=0x08004000, i.e. 0x08004000 + 0x80000 = 0x08084000 — 16K past the physical end of flash (0x08080000). Note the informational <IROM> field in the same file was already correct (0x7c000), only the active OCR_RVCT4 field was stale.

Fixed both to 0x08004000-based / 0x7C000 (496K), matching GCC and the documented figure.

2. STM32373C_EVAL — Applications/IAP/IAP_Binary_Template

Same bootloader-reserved-area pattern, but here it was reproduced by all three toolchains (this is why plain "majority vote across toolchains" isn't reliable — see the audit methodology note below). IAP_Main/readme.txt documents:

The maximum size of the image to be loaded is: 240 Kbytes

(STM32F373VC has 256K flash; 256K − 16K reserved = 240K.)

  • SW4STM32/.../STM32F373VCTx_FLASH.ld: FLASH ORIGIN = 0x08004000, LENGTH = 256K → end 0x08044000, 16K past the real flash end 0x08040000.
  • EWARM/stm32f373xc_flash.icf: ROM_start__ = 0x08000000 (should track intvec_start__ = 0x08004000).
  • MDK-ARM/Project.uvprojx: OCR_RVCT4 Size=0x40000 (256K) → overruns by the same 16K.

Fixed to LENGTH = 240K / ROM_start = 0x08004000 / Size = 0x3C000.

3. STM32F302R8-Nucleo — Examples/ADC/{ADC_AnalogWatchdog,ADC_Sequencer}

EWARM/stm32f302x8_flash.icf in both examples declared:

ROM: 0x08000000 - 0x0803FFFF   (256K)
RAM: 0x20000000 - 0x20009FFF   (40K)
+ a CCMRAM region 0x10000000 - 0x10001FFF (8K)

STM32F302R8 physically has 64K flash / 16K RAM and no CCM RAM at all — confirmed by the correctly-configured GCC (FLASH LENGTH = 64K, RAM LENGTH = 16K, no CCMRAM) and Keil (IROM 0x10000, IRAM 0x4000, no IRAM2) files in the very same two example directories, and by grepping every other .icf file on this board (31 files, including this board's own Templates and Templates_LL) — all 31 correctly use ROM_end = 0x0800FFFF, RAM_end = 0x20003FFF, no CCMRAM. Only these two ADC examples' .icf files carried a memory map that looks copy-pasted from a much bigger F3 part.

Fixed both files to match the other 31 (and to match their own GCC/Keil siblings): ROM_end = 0x0800FFFF, RAM_end = 0x20003FFF, CCMRAM region definitions removed.

4. STM32F3348-Discovery — Templates_LL (MDK-ARM only)

MDK-ARM/Project.uvprojx declared, in both the informational <IRAM>/<IROM> fields and the active OCR_RVCT4/OCR_RVCT9 fields (Ir1Chk=1, Im1Chk=1):

IROM (OCR_RVCT4): 0x08000000, size 0x8000   (32K)
IRAM (OCR_RVCT9): 0x20000000, size 0x30000  (192K)

STM32F334C8 has 64K flash / 12K RAM — confirmed by this same project's own GCC ld (FLASH 64K, RAM 12K) and IAR icf (ROM 64K, RAM 12K), and by the sibling Templates (non-LL) project's Keil configuration for the identical part (IROM 0x10000, IRAM 0x3000). This file is the only .uvprojx in the whole repository containing <Size>0x30000</Size> or <Size>0x8000</Size> for this device (checked via grep across all boards), confirming it's an isolated, uncorrected leftover — likely from an initial wrong/default device-memory selection when the project was created.

Fixed <IRAM>, <IROM>, OCR_RVCT4, OCR_RVCT9 to 0x3000/0x10000 respectively, matching GCC, IAR, and the sibling Keil Templates project (two independent toolchains plus a sibling project corroborate the larger ROM figure, satisfying the higher evidence bar this kind of "enlarge a declared region" fix requires).

5. STM32F3348-Discovery — Examples/HRTIM/{HRTIM_LLC_HalfBridge,HRTIM_Multiphase}

EWARM/stm32f334x8_flash.icf in both examples declared RAM_end = 0x20003FFF (16K), 4K past the physical 12K SRAM on STM32F334C8. Both the GCC linker script (RAM LENGTH = 12K) and Keil's <Cpu> tag (IRAM(0x20000000-0x20002FFF)) in the same two projects correctly use 0x20002FFF (12K).

Fixed RAM_end to 0x20002FFF in both files.

Excluded false positives (not fixed, with reasoning)

  • STM32303E_EVAL/Applications/USB_Device/{DFU_Standalone,MSC_Standalone}: both GCC ld and IAR icf declare CCMRAM LENGTH = 8K vs. the board's Templates project's 16K. However GCC and IAR agree with each other inside each of these two projects, and this would be an "enlarge a declared region" fix without two independent toolchains inside the same project corroborating a larger number — the sibling HID_Standalone app on the same board does use 16K, but that's a different project, not corroboration within DFU/MSC themselves. Left unchanged as plausibly an intentional, more conservative CCM reservation for these two USB apps.
  • STM32F303ZE-Nucleo: ~24 Examples/Applications/Demonstrations GCC linker scripts don't declare a CCMRAM memory region at all, while the board's Templates project does. Verified none of these examples reference a .ccmram output section, so omitting the region has zero functional effect (it's simply unused, optional bonus memory, not a partition error) — not a bug.

Test plan

No local ARM toolchain (arm-none-eabi-gcc / IAR / Keil) is available in this environment, so verification was done purely through address arithmetic and cross-file consistency:

  • For the IAP examples, the fixed numbers were checked against IAP_Main/readme.txt's explicitly documented "maximum size of the image to be loaded" figures (496K / 240K) and against the already-correct sibling toolchain file in the same project.
  • For the ADC/HRTIM/Templates_LL fixes, the corrected values were checked against (a) the same project's other toolchain files, (b) the board's own Templates project for the identical MCU part, and (c) a repo-wide grep confirming the wrong values were isolated outliers (2-of-33, 1-of-1) rather than a repo-wide convention.
  • Confirmed git diff only touches the specific numeric fields identified above — no other formatting, whitespace, or unrelated lines changed.

Disclosure

This audit and fix were carried out with the assistance of Claude (Anthropic AI), which parsed and cross-referenced the .ld / .icf / .uvprojx files across all 13 boards in this repository, identified candidate mismatches, and verified each one manually against ST's own documentation and sibling toolchain files before applying any fix. All findings and diffs were reviewed by me before submission.

Cross-referenced the GCC (SW4STM32/STM32CubeIDE), IAR (EWARM), and Keil
(MDK-ARM) memory-map declarations against each other and against the
Templates project (or ST's own documented flash partition figures) for
every project under Projects/. Found and fixed five independent,
verifiable inconsistencies:

- STM32303E_EVAL/Applications/IAP/IAP_Binary_Template: IAR ROM_region
  and Keil OCR_RVCT4 (IROM1) both started the readonly region at
  0x08000000/kept its full 512K size, instead of 0x08004000/496K as
  documented in IAP_Main/readme.txt ("maximum size of the image to be
  loaded is: 496 Kbytes") and already correctly implemented by the
  GCC linker script.

- STM32373C_EVAL/Applications/IAP/IAP_Binary_Template: same bootloader
  reserved-area bug, this time reproduced in all three toolchains
  (GCC LENGTH, IAR ROM_region, Keil OCR_RVCT4 all kept the full 256K
  instead of shrinking to 240K), contradicting the 240 Kbytes figure
  documented in IAP_Main/readme.txt.

- STM32F302R8-Nucleo/Examples/ADC/{ADC_AnalogWatchdog,ADC_Sequencer}:
  IAR .icf files declared ROM 0x08000000-0x0803FFFF (256K) and RAM
  0x20000000-0x20009FFF (40K) plus a bogus CCMRAM region, while the
  actual part (STM32F302R8) only has 64K flash / 16K RAM and no CCM
  RAM at all, as correctly reflected by the GCC/Keil files in the same
  two example directories and by all 31 other .icf files under this
  board (confirmed by grep across the whole board).

- STM32F3348-Discovery/Templates_LL (MDK-ARM only): IROM/IRAM device
  fields and the active OCR_RVCT4/OCR_RVCT9 linker regions declared
  32K ROM / 192K RAM, versus the correct 64K ROM / 12K RAM already
  used by this project's own GCC ld and IAR icf files, and by the
  sibling Templates (non-LL) project's Keil configuration for the
  identical STM32F334C8 part.

- STM32F3348-Discovery/Examples/HRTIM/{HRTIM_LLC_HalfBridge,
  HRTIM_Multiphase}: IAR RAM_end was 0x20003FFF (16K), 4K past the
  physical 12K SRAM on STM32F334C8, while both the GCC ld and the
  Keil Cpu/IRAM fields in the same two projects correctly declare
  0x20002FFF (12K).

Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant