Skip to content

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

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#13
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 (STM32CubeIDE)/IAR (EWARM)/Keil (MDK-ARM) linker scripts against each other, following the same methodology already used for STM32CubeG0, STM32CubeG4, STM32CubeH5, STM32CubeH7, STM32CubeL0, STM32CubeL4, STM32CubeU5, STM32CubeWB, STM32CubeWBA, STM32CubeWL, STM32CubeF0, STM32CubeF1, STM32CubeF4, and STM32CubeF7 in this repo family.

1. Applications/FreeRTOS/FreeRTOS_MPU (NUCLEO-L552ZE-Q and STM32L552E-EV, STM32L552ZE/QE, 512K flash) - Keil declares a chip 4x too big

Keil's scatter file declared a 2MB (0x00200000) privileged code load region starting at 0x08000000 - 1.5MB past the chip's real flash end. GCC's .ld (512K) and IAR's .icf (ROM_end = 0x0807FFFF, also 512K) both agree on the real capacity. Fixed Keil's LR_APP size to 0x00080000 (512K) on both boards.

2. Examples/PWR/PWR_LPRUN_SRAM1 (NUCLEO-L552ZE-Q) - Keil never got updated for the SRAM-execution design; GCC's own MEMORY block also drifted from its own comment

This demo intentionally executes from SRAM1 in Low-Power Run mode - GCC and IAR both correctly place code/data inside the SRAM address range (0x20000000+) instead of flash, which is by design and not a bug in itself. But Keil's scatter file was never updated to match: it still used ordinary flash-based addresses (LR_IROM1 0x08000000, 512K) with a RAM region sized for normal full-SRAM use (RW_IRAM1 0x20000000, 192K) - i.e. it doesn't exercise the SRAM-execution behavior the demo exists to demonstrate at all. IAR's .icf cleanly splits the 192K of SRAM1 into a 128K code region (0x20000000-0x2001FFFF) and a 64K data region (0x20020000-0x2002FFFF). Fixed Keil to the same split.

Separately, GCC's own .ld already targets the correct SRAM address range, but its MEMORY block declared a 125K/65K split (an odd 3K offset from IAR's clean 128K/64K boundary, leaving a gap between the two regions) while its own header comment said "128Kbytes ROM / 65Kbytes RAM" - already internally inconsistent. Fixed GCC's actual MEMORY LENGTH values to 128K/64K to match IAR and the corrected Keil.

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: IAR's clean symbolic region boundaries, GCC's own header comments, and this board's own Templates project.

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 (STM32CubeIDE)/IAR (EWARM)/
Keil (MDK-ARM) linker scripts against each other, following the same
audit already done for STM32CubeG0/G4/H5/H7/L0/L4/U5/WB/WBA/WL/F0/F1/
F4/F7 in this repo family.

1. Applications/FreeRTOS/FreeRTOS_MPU (NUCLEO-L552ZE-Q and
   STM32L552E-EV, STM32L552ZE/QE, 512K flash): Keil's scatter file
   declared a 2MB (0x00200000) privileged code region starting at
   0x08000000, running 1.5MB past the chip's real flash end. GCC's
   .ld (512K) and IAR's .icf (ROM_end 0x0807FFFF, also 512K) both
   agree on the real 512K. Fixed Keil's LR_APP size to 0x00080000
   (512K) on both boards.

2. Examples/PWR/PWR_LPRUN_SRAM1 (NUCLEO-L552ZE-Q): this demo
   intentionally executes from SRAM1 in Low-Power Run mode, so GCC
   and IAR both correctly place code/data inside the SRAM address
   range (0x20000000+) rather than flash - this part is by design,
   not a bug. But Keil's scatter file was never updated to match:
   it still used flash-based addresses (LR_IROM1 0x08000000, 512K)
   and a RAM region sized for normal full-SRAM use (RW_IRAM1
   0x20000000, 192K), i.e. it doesn't exercise the SRAM-execution
   design the demo is supposed to demonstrate at all. IAR's .icf
   cleanly splits the 192K SRAM1 into a 128K code region
   (0x20000000-0x2001FFFF) and 64K data region
   (0x20020000-0x2002FFFF). Fixed Keil to the same split. GCC's own
   .ld also targets the SRAM range correctly, but its MEMORY block
   declared a 125K/65K split (an odd 3K offset from IAR's clean
   128K/64K boundary, with a gap between the regions) while its own
   header comment already said "128Kbytes ROM / 65Kbytes RAM" -
   fixed GCC's actual MEMORY LENGTH values to 128K/64K to match IAR
   and the corrected Keil, resolving the comment/code mismatch.

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 (IAR's clean symbolic region boundaries,
GCC's own header comments, and this board's own Templates project).

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
@ALABSTM ALABSTM assigned ALABSTM and unassigned MKISTM 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