Skip to content

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

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#39
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, STM32CubeH7, and STM32CubeF1 in this repo family.

1. Demonstrations (32L0538DISCOVERY, STM32L053C8, 64K flash) - GCC contradicts its own doc comment

GCC's .ld declares FLASH LENGTH=192K - directly contradicting its own doc-comment header two lines above, which correctly says 64Kbytes FLASH. IAR's .icf and Keil's <Device>STM32L053C8Tx</Device>/OCR_RVCT4 both correctly use 64K, matching this board's Templates project. Fixed GCC's .ld to 64K.

2. Applications/IAP/IAP_Binary_Template (STM32L073Z-EVAL, STM32L073VZ, 192K flash) - GCC and Keil both offset the start but forget to shrink the length

Both GCC's .ld and Keil's .uvprojx correctly offset the app's flash start address to 0x08005000 to leave room for the bootloader, but neither shrinks the length to compensate - both still declare 192K as if starting from 0x08000000, running 20K past the chip's actual end of flash. IAR's .icf correctly uses 172K (0x08005000-0x0802FFFF).

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/F7/F4/H7/F1. Fixed GCC's .ld and Keil's OCR_RVCT4 Size to 172K (0x2B000), matching IAR.

Scope note

Two further candidates on the same board (Examples/FIREWALL/FIREWALL_VolatileData_Executable and FIREWALL_VolatileData_Shared) were investigated but are not included here: each demo uses a genuinely different, hand-tuned memory partition per toolchain to exercise the STM32L0 FIREWALL peripheral's protected-segment feature (e.g. IAR's "ROM"/"RAM" region names refer to small SRAM-resident protected zones in one variant, and a mix of small flash regions plus a separate protected sub-region in the other). This isn't the toolchain-drift pattern the fixes above address, and verifying what the "correct" partition should be would need deeper FIREWALL peripheral domain knowledge than I have confidence in, so I left them alone rather than guess.

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> tag naming 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/F1 in this repo family.

1. Demonstrations (32L0538DISCOVERY, STM32L053C8, 64K flash): GCC's
   .ld declares FLASH LENGTH=192K - directly contradicting its own
   doc-comment header two lines above, which correctly says "64Kbytes
   FLASH". IAR's .icf and Keil's <Device>STM32L053C8Tx</Device>/OCR
   both correctly use 64K, matching this board's Templates project.
   Fixed GCC's .ld to 64K.

2. Applications/IAP/IAP_Binary_Template (STM32L073Z-EVAL, STM32L073VZ,
   192K flash): both GCC's .ld and Keil's .uvprojx correctly offset
   the app's flash start address to 0x08005000 to leave room for the
   bootloader, but neither shrinks the length to compensate - both
   still declare 192K as if starting from 0x08000000, running 20K
   past the chip's actual end of flash. IAR's .icf correctly uses
   172K (0x08005000-0x0802FFFF). 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/F7/F4/H7/F1. Fixed GCC's .ld and Keil's OCR_RVCT4 Size
   to 172K (0x2B000), matching IAR.

Two further candidates (Examples/FIREWALL/FIREWALL_VolatileData_Executable
and FIREWALL_VolatileData_Shared, same board) were investigated but not
included here: each demo uses a genuinely different, hand-tuned memory
partition per toolchain to exercise the STM32L0 FIREWALL peripheral's
protected-segment feature (e.g. IAR's "ROM"/"RAM" region names refer to
small SRAM-resident protected zones in one variant, and a mix of small
flash regions plus a separate protected sub-region in the other) -
this isn't the toolchain-drift pattern the other fixes address, and
verifying the "correct" partition would require deeper FIREWALL
peripheral domain knowledge than I have confidence in, so I left them
alone rather than guess.

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> tag naming the
actual target chip).

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