fix(linker): correct cross-toolchain memory map inconsistencies#21
Open
94xhn wants to merge 1 commit into
Open
fix(linker): correct cross-toolchain memory map inconsistencies#2194xhn wants to merge 1 commit into
94xhn wants to merge 1 commit into
Conversation
…M32N6 GCC linker scripts Cross-checked the GCC (STM32CubeIDE .ld), IAR (EWARM .icf) and Keil (MDK-ARM .sct, the real scatter file referenced by <ScatterFile> in .uvprojx, not the stale OCR_RVCT placeholders) linker descriptions of the same physical memory for every Projects/* example and found four GCC-only drifts, all confirmed by both other toolchains agreeing with each other and disagreeing with GCC: 1. PWR_STANDBY / PWR_STANDBY_RTC (STM32N6570-DK, Appli role): the GCC RAM region started at 0x34020000 while ROM (511K @ 0x34000400) ends at 0x3407FFFF, so RAM overlapped the last 384 KB of ROM. IAR and Keil both start RAM at 0x34080000 (immediately after ROM). Moved the GCC RAM origin to 0x34080000 to remove the overlap. 2. CORTEX_InterruptSwitch_TrustZone (NUCLEO-N657X0-Q, AppliNonSecure role): GCC declared only 256 KB of non-secure RAM (0x241A0000- 0x241DFFFF) while IAR (ROM_region + RAM_region) and Keil (ROM_SIZE + RAM_SIZE) both cover the full 384 KB non-secure window up to 0x241FFFFF, which is also the well-established top of that AXISRAM2 bank used consistently across the rest of the repository (secure alias 0x341FFFFF). Widened GCC's RAM LENGTH from 256K to 384K to match. 3. VENC_RTSP_Server / VENC_SDCard / VENC_SDCard_ThreadX / VENC_USB (STM32N6570-DK, FSBL role): GCC declared the FSBL RAM region as 255K instead of 256K (looks like the adjacent ROM line's 255K was copy-pasted into the RAM line). Both IAR (__ICFEDIT_region_RAM_end__ = 0x341FFFFF) and Keil (__RAM_SIZE = 0x00040000) agree the region is the full 256K. Fixed GCC RAM LENGTH from 255K to 256K in all four FSBL linker scripts. 4. VENC_SDCard (STM32N6570-DK, Appli role): the same project's ROM region was declared as a round 256K, one KB larger than IAR (__ICFEDIT_region_ROM_end__ = 0x3403FFFF -> 255K) and Keil (__ROM_SIZE = 0x0003FC00 -> 255K), inconsistent with the repo-wide convention that a ROM window starting at a +0x400 header offset is sized (bank - 1K). Fixed GCC ROM LENGTH from 256K to 255K. No local ARM toolchain available; verified purely via address arithmetic (region overlap / boundary matching) cross-referenced against the independently-authored IAR and Keil files for the same example. Several other automated mismatches were investigated and excluded as false positives, e.g. GCC merging ROM+RAM into a single named region where IAR/Keil split them (same total physical span, just a different MEMORY block style), and NetXDuo examples where GCC uses an absolute- address sub-section for the packet pool while IAR carves out a separate named region at the same address (same physical layout, different linker-script idiom). 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.
Summary
I cross-checked the GCC (
STM32CubeIDE/*.ld), IAR (EWARM/*.icf) and Keil (MDK-ARM/*.uvprojx-> real.sctscatter file, not the staleOCR_RVCT*XML placeholders) linker descriptions of the same physical memory for every example underProjects/, and found 4 GCC-only drifts across 8 linker scripts, each confirmed by IAR and Keil independently agreeing with each other and disagreeing with GCC.1. RAM/ROM overlap —
PWR_STANDBY/PWR_STANDBY_RTC(STM32N6570-DK,Applirole)Projects/STM32N6570-DK/Examples/PWR/PWR_STANDBY/STM32CubeIDE/Appli/STM32N657X0HXQ_LRUN.ldand the_RTCsibling declared:RAMstarts at0x34020000, which is 384 KB beforeROMends (0x3407FFFF), so the two regions overlap by 384 KB — code/rodata placed near the end ofROMwould share physical bytes with.data/.bss.Both
EWARM/Appli/stm32n657xx_LRUN.icf(__ICFEDIT_region_RAM_start__ = 0x34080000) andMDK-ARM/Appli/stm32n657xx_LRUN.sct(__RAM_BASE 0x34080000) start RAM immediately after ROM ends, with no overlap. Fixed GCC'sRAMorigin to0x34080000in both examples.2. RAM under-allocated by 128 KB —
CORTEX_InterruptSwitch_TrustZone(NUCLEO-N657X0-Q,AppliNonSecurerole)Projects/NUCLEO-N657X0-Q/Examples/CORTEX/CORTEX_InterruptSwitch_TrustZone/STM32CubeIDE/AppliNonSecure/STM32N657X0HXQ_FLASH.lddeclared a single mergedRAM (xrw): ORIGIN = 0x241a0000, LENGTH = 256K(0x241a0000-0x241DFFFF).EWARM/AppliNonSecure/stm32n657xx_fsbl_ns.icfdefinesROM_region(0x241A0000-0x241BFFFF, 128K) +RAM_region(0x241C0000-0x241FFFFF, 256K) = 384K total, andMDK-ARM/AppliNonSecure/stm32n657xx_ns.sctagrees (__ROM_SIZE 0x20000+__RAM_SIZE 0x40000= 384K). Both independently authored toolchain files put the usable non-secure window's top at0x241FFFFF, which also matches the well-established top of the same physical AXISRAM2 bank used identically (secure alias0x341FFFFF) across dozens of other examples in the repo. GCC's file stopped 128 KB short of that boundary with nothing else claiming the missing space. Widened GCC'sRAMLENGTHfrom256Kto384K(origin unchanged) to reclaim the missing 128 KB and match both other toolchains.3. FSBL RAM off-by-1KB —
VENC_RTSP_Server/VENC_SDCard/VENC_SDCard_ThreadX/VENC_USB(STM32N6570-DK,FSBLrole)All four
STM32CubeIDE/FSBL/STM32N657XX_AXISRAM2_fsbl.ldfiles declared:RAMatLENGTH = 255Klooks like theROMline's255Kwas copy-pasted down. BothEWARM/FSBL/stm32n657xx_axisram2_fsbl.icf(__ICFEDIT_region_RAM_end__ = 0x341FFFFF, i.e. 256K) andMDK-ARM/FSBL/stm32n657xx_axisram2_fsbl.sct(__RAM_SIZE 0x00040000= 256K) agree the region is a full 256K. Fixed all four toLENGTH = 256K.4. Appli ROM off-by-1KB —
VENC_SDCard(STM32N6570-DK,Applirole)Projects/STM32N6570-DK/Applications/VENC/VENC_SDCard/STM32CubeIDE/Appli/STM32N657XX_LRUN.lddeclaredROM (xr) : ORIGIN = 0x34000400, LENGTH = 256K, one KB larger thanEWARM/Appli/stm32n657xx_LRUN.icf(__ICFEDIT_region_ROM_end__ = 0x3403FFFF-> 255K) andMDK-ARM/Appli/stm32n657xx_LRUN.sct(__ROM_SIZE 0x0003FC00-> 255K). This is inconsistent with the convention used everywhere else in the repo, where a ROM window starting at a+0x400header offset is sized(bank − 1K). Fixed GCC'sROMLENGTHfrom256Kto255K.Notes on false positives excluded
While auditing I found several automated size mismatches that turned out not to be bugs after reading the actual
SECTIONS/scatter placement, and excluded them:NetXDuo(Nx_*) FSBL examples: GCC keeps one monolithicRAMregion and places the NetX packet pool at an absolute address inside it, while IAR carves out a separate named region (NXApp_region) at the exact same address — same physical layout, different linker-script idiom.Template_FSBL_LRUN/Template_Isolation_LRUN/_XIPFSBL/Appliroles: GCC mergesROM+RAMinto one named region whose size equals the split IAR/Keil totals exactly — again a stylistic difference, not a drift.ITCM128K vs 64K in severalVENC_*AppliGCC scripts: theITCMMEMORYentry is declared but never referenced inSECTIONS, so it's dead/unused and carries no functional risk; left untouched.RAMinCORTEX_InterruptSwitch_TrustZone'sFSBLrole, secure side) where GCC and Keil agree with each other and only IAR differs by 4x — inconclusive without a datasheet cross-check, so left unchanged rather than guess.Test plan
No local ARM toolchain (armclang/armcc/IAR) available, so verification was done purely via address arithmetic:
ORIGIN/LENGTH-> end-address for every changed region and confirmed no more overlap with sibling regions in the same file (issue 1).EWARM/*.icfandMDK-ARM/*.sctfor the same example/role (issues 1-4).0x241FFFFF/0x341FFFFF) used consistently across the rest ofProjects/(issue 2).Disclosure
This audit and patch were prepared with Claude (Anthropic) assistance — automated cross-toolchain diffing to surface candidate mismatches, with every flagged case then manually re-verified by hand (reading the actual
SECTIONS/scatter-file placement, computing region boundaries, and cross-referencing all three toolchains) before deciding whether to fix it. All changes have been reviewed by me before submission.