Skip to content

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

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#74
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

Not tied to a specific existing issue - found by systematically cross-checking each example's GCC (SW4STM32)/IAR (EWARM)/Keil (MDK-ARM) linker scripts against each other and against known-good Templates sibling projects for the same chip, following the same methodology already used for STM32CubeG4, STM32CubeWB, STM32CubeWL, STM32CubeU5, STM32CubeF7, STM32CubeF4, STM32CubeL4, and STM32CubeH7 in this repo family.

1. Examples/TIM/TIM_TimeBase (STM3210C_EVAL, STM32F107RC, 256K flash / 64K RAM) - GCC and IAR both use a different chip's memory map

GCC's .ld and IAR's .icf both use a memory map sized for a different, larger STM32F107 variant (1024K flash / 96K RAM) - the .ld's own doc-comment header even says "Linker script for STM32F107RCIx Device with 1024KByte FLASH, 96KByte RAM", which is internally inconsistent with its own filename/ORIGIN (STM32F107RCTx, the 256K "RC" density part).

Keil's <Device>STM32F107VC</Device> and <Cpu>IROM(0x8000000-0x803FFFF)</Cpu> (256K) correctly match this board's Templates project. This is a "2-of-3-toolchains-wrong" case - a naive majority vote here would have picked the wrong answer, similar to what was already found in STM32CubeWB/STM32CubeF7/STM32CubeF4/STM32CubeH7.

Fixed GCC's .ld and IAR's .icf (including the .ld's doc-comment header) to 256K flash / 64K RAM, matching Keil and Templates.

2. Applications/IAP/IAP_Binary_Template (STM3210C_EVAL and STM3210E_EVAL) - Keil offsets the start but forgets to shrink the length

Keil's .uvprojx correctly offsets the app's flash start address (0x8004000) to leave room for the bootloader, but never shrinks the length to compensate - OCR_RVCT4 still declares the region as if it started from 0x8000000, running past the chip's actual end of flash by exactly the size of the reserved bootloader region. IAR/GCC in the same projects both correctly shrink the length (240K for STM3210C_EVAL, 1008K for STM3210E_EVAL). Fixed Keil's OCR_RVCT4 Size to match on both boards.

Test plan

No local ARM toolchain (arm-none-eabi-gcc/IAR/Keil) available to compile/link-test these, so verification relied on address-arithmetic cross-referencing against multiple independent references per finding: Templates gold standards, sibling toolchain files of the same project, and the Keil <Device>/<Cpu> tags, which explicitly name the actual target chip.

Disclosure

Generative AI (Claude) was used to help investigate this (systematic cross-toolchain linker script comparison) and implement/verify the fixes. All changes were reviewed by me before submission.

Found by cross-checking each example's GCC (SW4STM32)/IAR (EWARM)/Keil
(MDK-ARM) linker scripts against each other and against known-good
Templates sibling projects, following the same audit already done for
STM32CubeG4/WB/WL/U5/F7/F4/L4/H7 in this repo family.

1. Examples/TIM/TIM_TimeBase (STM3210C_EVAL, STM32F107RC, 256K flash /
   64K RAM): GCC's .ld and IAR's .icf both use a memory map for a
   different, larger STM32F107 variant (1024K flash / 96K RAM,
   confirmed by the .ld's own doc-comment header claiming "1024KByte
   FLASH" for a "STM32F107RCIx" device - inconsistent with its own
   ORIGIN/filename, which are for the RC/256K part). Keil's
   <Device>STM32F107VC</Device> and <Cpu>IROM(0x8000000-0x803FFFF)</Cpu>
   correctly use 256K, matching this board's Templates project. This
   is a "2-of-3-toolchains-wrong" case - a naive majority vote here
   would have picked the wrong answer. Fixed GCC/IAR to 256K flash /
   64K RAM, matching Keil and Templates.

2. Applications/IAP/IAP_Binary_Template (STM3210C_EVAL and
   STM3210E_EVAL): Keil's .uvprojx correctly offsets the app's flash
   start address (0x8004000) to leave room for the bootloader, but
   never shrinks the length to compensate - OCR_RVCT4 still declares
   the region as if it started from 0x8000000, running past the
   chip's actual end of flash by exactly the size of the reserved
   bootloader region. IAR/GCC in the same projects both correctly
   shrink the length (240K for STM3210C_EVAL, 1008K for
   STM3210E_EVAL). Fixed Keil's OCR_RVCT4 Size to match on both
   boards.

No local ARM toolchain (arm-none-eabi-gcc/IAR/Keil) available to
compile/link-test these changes; verification relied on
address-arithmetic cross-referencing against multiple independent
references per finding (Templates gold standards, sibling toolchain
files of the same project, and the Keil <Device>/<Cpu> tags which
name the actual target chip).

Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
@ALABSTM ALABSTM added bug Something isn't working projects Projects-related (demos, applications, examples) issue or pull-request labels Jul 13, 2026
@KRASTM KRASTM moved this from To do to Analyzed in stm32cube-mcu-fw-dashboard Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working projects Projects-related (demos, applications, examples) issue or pull-request

Projects

Development

Successfully merging this pull request may close these issues.

3 participants