fix(linker): correct several cross-toolchain memory map inconsistencies#113
Open
94xhn wants to merge 1 commit into
Open
fix(linker): correct several cross-toolchain memory map inconsistencies#11394xhn wants to merge 1 commit into
94xhn wants to merge 1 commit into
Conversation
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 STM32CubeG4/WB/WL/U5/F7/F4 in this repo family. 1. IAP_Binary_Template (STM32L476G-EVAL): Keil's `.uvprojx` correctly offsets the app's flash start address to 0x08008000 to leave room for the bootloader, but never shrinks the length to compensate - OCR_RVCT4 still declares 1MB as if starting from 0x08000000, running 32K past the chip's actual end of flash. IAR/GCC in the same project both correctly use 992K. Fixed Keil's OCR_RVCT4 Size to 0xF8000 (992K). 2. IAP_Main (STM32L476G-EVAL, the bootloader itself): Keil's `.uvprojx` OCR_RVCT4 declares the full 1MB flash instead of the 32K bootloader budget that IAR/GCC both correctly use. If the bootloader's own build ever grows close to or past 32K, Keil wouldn't catch it linking straight into the application region it's supposed to hand off to. 3. PWR_RUN_SMPS (NUCLEO-L4R5ZI-P, STM32L4R5, 2MB flash): GCC's `.ld` copies the reserved 6K `ROM_While1` region (used by `whileloop1()` in `main.c`, explicitly placed there via `#pragma`/`section` attributes in all three toolchains) at `0x080FE800` - the correct address for a 1MB-flash board, not this 2MB one - and never shrinks the main FLASH region to make room, so the two regions overlap. IAR's `.icf` correctly places the same reserved region at `0x081FE800` (near the true end of 2MB flash) with FLASH shrunk to 2042K. Cross-checked against three sibling "-P" boards (L433RC-P, L452RE-P, L496ZG-P) that all correctly compute this reserved region's address relative to their own flash size - only NUCLEO-L4R5ZI-P copied the wrong constant. Fixed GCC's `ROM_While1` origin to `0x081FE800` and FLASH length to 2042K. 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 each project's own IAR/GCC files and, for finding 3, sibling boards' equivalent examples. Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 STM32CubeG4, STM32CubeWB, STM32CubeWL, STM32CubeU5, STM32CubeF7, and STM32CubeF4 in this repo family.
1.
IAP_Binary_Template(STM32L476G-EVAL) - Keil offsets the start but forgets to shrink the lengthKeil's
.uvprojxcorrectly offsets the app's flash start address to0x08008000to leave room for the bootloader, but never shrinks the length to compensate -OCR_RVCT4still declares 1MB as if starting from0x08000000, running 32K past the chip's actual end of flash. IAR and GCC in the same project both correctly use 992K. Fixed Keil'sOCR_RVCT4Sizeto0xF8000(992K).2.
IAP_Main(STM32L476G-EVAL, the bootloader itself)Keil's
.uvprojxOCR_RVCT4declares the full 1MB flash instead of the 32K bootloader budget that IAR/GCC both correctly use. If the bootloader's own build ever grows close to or past 32K, Keil wouldn't catch it linking straight into the application region it's supposed to hand off to. Fixed to0x8000(32K).3.
PWR_RUN_SMPS(NUCLEO-L4R5ZI-P, STM32L4R5, 2MB flash) - reserved region copied from the wrong boardGCC's
.ldplaces the reserved 6KROM_While1region (used bywhileloop1()inmain.c, explicitly placed there via#pragma/sectionattributes in all three toolchains) at0x080FE800- the correct address for a 1MB-flash board, not this 2MB one - and never shrinks the mainFLASHregion to make room, so the two regions overlap in address space.IAR's
.icfcorrectly places the same reserved region at0x081FE800(near the true end of 2MB flash) withFLASHshrunk to 2042K. I cross-checked against three sibling "-P" boards (NUCLEO-L433RC-P, NUCLEO-L452RE-P, NUCLEO-L496ZG-P) that all correctly compute this reserved region's address relative to their own flash size - only NUCLEO-L4R5ZI-P copied the wrong constant, most likely from a 1MB-flash board's version of this same example.Fixed GCC's
ROM_While1origin to0x081FE800andFLASHlength to 2042K.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 each project's own IAR/GCC files and, for finding 3, sibling boards' equivalent examples.
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.