From a082215cae242d5126687d36915a503cb38123bb Mon Sep 17 00:00:00 2001 From: yi chen <94xhn1@gmail.com> Date: Sat, 11 Jul 2026 08:04:12 +0800 Subject: [PATCH] fix(linker): correct several cross-toolchain memory map inconsistencies Found by cross-checking each example's GCC (STM32CubeIDE)/IAR (EWARM)/ Keil (MDK-ARM) linker scripts against each other and against known-good sibling projects, following the same audit already done for STM32CubeG4/STM32CubeWB in this session. For every finding, the "which value is actually right" call was made by checking which MEMORY region the project's real SECTIONS (.data/.bss/heap+stack, and _estack) target - not just by comparing MEMORY{} declarations, since a declared-but-unused region can look like a mismatch while not actually being one (this cost some initial false positives that were caught and dropped, see below). 1. ADF_AudioSoundDetector (B-U585I-IOT02A): EWARM's .icf declared RAM at 0x28000000 (SRAM4's address, used elsewhere in this repo as a small 16K region) but sized it as 768K (the size of the *main* RAM at 0x20000000) - a copy-paste combining the wrong address with the wrong region's size. This project's own GCC .ld only declares/uses the main 0x20000000/768K RAM (no SRAM4/alias region at all), confirming EWARM's value was simply wrong. Fixed to 0x20000000/768K. (Three other files initially flagged for this same pattern - I2C_TwoBoards_ComDMA_LowPower and both SPI_FullDuplex_ComDMA_LowPower_* examples on NUCLEO-U575ZI-Q - turned out NOT to be bugs on closer inspection: their own GCC .ld files declare an `SRAM` alias region at the same 0x28000000/768K address and *actually place* .data/.bss/stack there (confirmed via the `>SRAM` section directives), so EWARM using the same address/size for those three actually matches its sibling GCC file's real behavior. Left untouched.) 2. LPTIM_IC_LSE (NUCLEO-U575ZI-Q) and DCACHE_Maintenance (STM32U575I-EV): Keil's RW_IRAM1 only reserved 192K at 0x20000000 while GCC/`_estack` both target the full 768K RAM at the same address (confirmed via each project's own `>RAM`-targeted SECTIONS). Fixed Keil to 768K. 3. RTC_ActiveTamper (NUCLEO-U545RE-Q) and RAMCFG_ECC_Error_Generation (NUCLEO-U575ZI-Q): both GCC .ld files had a stray "LENGTH = 100K" RAM size (repo-wide grep confirms these are the only 2 occurrences of this exact value in the whole repo) instead of the real chip RAM (256K and 768K respectively, both confirmed via the projects' own IAR files). 4. Fx_File_Edit_Standalone (NUCLEO-U545RE-Q): EWARM's RAM was 192K (0x2002FFFF) while GCC/`_estack` both target the chip's real 256K. 5. Fx_File_Edit_Standalone and Tx_Thread_Creation (STM32U5G9J-DK2): both GCC .ld files declared RAM as 256K instead of the chip's real 3008K (confirmed via 19 other correct GCC examples on the same board, and via the board's own Examples/BSP EWARM file). 6. Examples/BSP (STM32U5G9J-DK2): EWARM's RAM was 384K (0x2005FFFF) while this exact project's own GCC .ld correctly uses the chip's real 3008K. 7. Tx_MPU dual-partition ThreadX MPU demo (STM32U5G9J-DK2 and STM32U5x9J-DK): the GCC MODULE-partition linker script set FLASH ORIGIN to 0x08000000 - identical to, and fully overlapping, the MANAGER partition's own flash region (also 0x08000000, 128K) - instead of 0x08020000 (128K past MANAGER), which IAR's module.icf already correctly uses on both boards. Two independently-linked, MPU-isolated firmware images cannot share a flash base address. Fixed GCC's MODULE FLASH ORIGIN to 0x08020000 (LENGTH unchanged at 896k, so the region still ends at the same address IAR uses, 0x080FFFFF). Left the MODULE RAM size (GCC 128K vs IAR 64K at the same 0x20020000 origin, no overlap either way) untouched - could not rule out intentional extra headroom without reading the ThreadX MPU application's own memory-partitioning source. No local ARM toolchain available to compile/link-test these changes; verification relied on address-arithmetic cross-referencing against multiple independent references per finding (sibling toolchain files of the same project, other correct examples on the same board, and - critically - checking which MEMORY region a project's actual SECTIONS target, not just what's declared). Signed-off-by: yi chen <94xhn1@gmail.com> --- .../OpenBootloader/STM32CubeIDE/STM32U585AIIX_FLASH.ld | 4 ++-- .../MDF/ADF_AudioSoundDetector/EWARM/stm32u585xx_flash.icf | 4 ++-- .../FileX/Fx_File_Edit_Standalone/EWARM/stm32u545xx_flash.icf | 2 +- .../RTC/RTC_ActiveTamper/STM32CubeIDE/STM32U545RETXQ_FLASH.ld | 2 +- .../LPTIM/LPTIM_IC_LSE/MDK-ARM/LPTIM_IC_LSE/LPTIM_IC_LSE.sct | 2 +- .../STM32CubeIDE/STM32U575ZITXQ_FLASH.ld | 2 +- .../MDK-ARM/DCACHE_Maintenance/DCACHE_Maintenance.sct | 2 +- .../STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld | 2 +- .../Tx_MPU/STM32CubeIDE/STM32U5G9ZJTXQ_MODULE_FLASH.ld | 2 +- .../Tx_Thread_Creation/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld | 2 +- .../STM32U5G9J-DK2/Examples/BSP/EWARM/stm32u5g9xx_flash.icf | 2 +- .../Tx_MPU/STM32CubeIDE/STM32U5A9NJHXQ_MODULE_FLASH.ld | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Projects/B-U585I-IOT02A/Applications/OpenBootloader/STM32CubeIDE/STM32U585AIIX_FLASH.ld b/Projects/B-U585I-IOT02A/Applications/OpenBootloader/STM32CubeIDE/STM32U585AIIX_FLASH.ld index f5c9fcb0a..557c764b2 100644 --- a/Projects/B-U585I-IOT02A/Applications/OpenBootloader/STM32CubeIDE/STM32U585AIIX_FLASH.ld +++ b/Projects/B-U585I-IOT02A/Applications/OpenBootloader/STM32CubeIDE/STM32U585AIIX_FLASH.ld @@ -46,8 +46,8 @@ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Memories definition */ MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K - ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 70K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 70K } /* Sections */ diff --git a/Projects/B-U585I-IOT02A/Examples/MDF/ADF_AudioSoundDetector/EWARM/stm32u585xx_flash.icf b/Projects/B-U585I-IOT02A/Examples/MDF/ADF_AudioSoundDetector/EWARM/stm32u585xx_flash.icf index 5e1f5b664..1b58b3ef3 100644 --- a/Projects/B-U585I-IOT02A/Examples/MDF/ADF_AudioSoundDetector/EWARM/stm32u585xx_flash.icf +++ b/Projects/B-U585I-IOT02A/Examples/MDF/ADF_AudioSoundDetector/EWARM/stm32u585xx_flash.icf @@ -6,8 +6,8 @@ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x28000000; -define symbol __ICFEDIT_region_RAM_end__ = 0x280BFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x200BFFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; diff --git a/Projects/NUCLEO-U545RE-Q/Applications/FileX/Fx_File_Edit_Standalone/EWARM/stm32u545xx_flash.icf b/Projects/NUCLEO-U545RE-Q/Applications/FileX/Fx_File_Edit_Standalone/EWARM/stm32u545xx_flash.icf index d3cd341b3..1dfa6559b 100644 --- a/Projects/NUCLEO-U545RE-Q/Applications/FileX/Fx_File_Edit_Standalone/EWARM/stm32u545xx_flash.icf +++ b/Projects/NUCLEO-U545RE-Q/Applications/FileX/Fx_File_Edit_Standalone/EWARM/stm32u545xx_flash.icf @@ -7,7 +7,7 @@ define symbol __ICFEDIT_intvec_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; -define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; +define symbol __ICFEDIT_region_RAM_end__ = 0x2003FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; diff --git a/Projects/NUCLEO-U545RE-Q/Examples/RTC/RTC_ActiveTamper/STM32CubeIDE/STM32U545RETXQ_FLASH.ld b/Projects/NUCLEO-U545RE-Q/Examples/RTC/RTC_ActiveTamper/STM32CubeIDE/STM32U545RETXQ_FLASH.ld index 6365b554a..4f7717f2c 100644 --- a/Projects/NUCLEO-U545RE-Q/Examples/RTC/RTC_ActiveTamper/STM32CubeIDE/STM32U545RETXQ_FLASH.ld +++ b/Projects/NUCLEO-U545RE-Q/Examples/RTC/RTC_ActiveTamper/STM32CubeIDE/STM32U545RETXQ_FLASH.ld @@ -45,7 +45,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 100K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K } diff --git a/Projects/NUCLEO-U575ZI-Q/Examples/LPTIM/LPTIM_IC_LSE/MDK-ARM/LPTIM_IC_LSE/LPTIM_IC_LSE.sct b/Projects/NUCLEO-U575ZI-Q/Examples/LPTIM/LPTIM_IC_LSE/MDK-ARM/LPTIM_IC_LSE/LPTIM_IC_LSE.sct index 5816e9d9d..c59d80dbd 100644 --- a/Projects/NUCLEO-U575ZI-Q/Examples/LPTIM/LPTIM_IC_LSE/MDK-ARM/LPTIM_IC_LSE/LPTIM_IC_LSE.sct +++ b/Projects/NUCLEO-U575ZI-Q/Examples/LPTIM/LPTIM_IC_LSE/MDK-ARM/LPTIM_IC_LSE/LPTIM_IC_LSE.sct @@ -9,7 +9,7 @@ LR_IROM1 0x08000000 0x00200000 { ; load region size_region .ANY (+RO) .ANY (+XO) } - RW_IRAM1 0x20000000 0x00030000 { ; RW data + RW_IRAM1 0x20000000 0x000C0000 { ; RW data .ANY (+RW +ZI) } RW_SRAM4 0x28000000 0x4000 { ; RW data diff --git a/Projects/NUCLEO-U575ZI-Q/Examples/RAMCFG/RAMCFG_ECC_Error_Generation/STM32CubeIDE/STM32U575ZITXQ_FLASH.ld b/Projects/NUCLEO-U575ZI-Q/Examples/RAMCFG/RAMCFG_ECC_Error_Generation/STM32CubeIDE/STM32U575ZITXQ_FLASH.ld index 932c0988a..3e5132fa2 100644 --- a/Projects/NUCLEO-U575ZI-Q/Examples/RAMCFG/RAMCFG_ECC_Error_Generation/STM32CubeIDE/STM32U575ZITXQ_FLASH.ld +++ b/Projects/NUCLEO-U575ZI-Q/Examples/RAMCFG/RAMCFG_ECC_Error_Generation/STM32CubeIDE/STM32U575ZITXQ_FLASH.ld @@ -46,7 +46,7 @@ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Memories definition */ MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 100K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K } diff --git a/Projects/STM32U575I-EV/Examples/DCACHE/DCACHE_Maintenance/MDK-ARM/DCACHE_Maintenance/DCACHE_Maintenance.sct b/Projects/STM32U575I-EV/Examples/DCACHE/DCACHE_Maintenance/MDK-ARM/DCACHE_Maintenance/DCACHE_Maintenance.sct index bd7670c0f..07112b90b 100644 --- a/Projects/STM32U575I-EV/Examples/DCACHE/DCACHE_Maintenance/MDK-ARM/DCACHE_Maintenance/DCACHE_Maintenance.sct +++ b/Projects/STM32U575I-EV/Examples/DCACHE/DCACHE_Maintenance/MDK-ARM/DCACHE_Maintenance/DCACHE_Maintenance.sct @@ -9,7 +9,7 @@ LR_IROM1 0x08000000 0x00200000 { ; load region size_region .ANY (+RO) .ANY (+XO) } - RW_IRAM1 0x20000000 0x00030000 { ; RW data + RW_IRAM1 0x20000000 0x000C0000 { ; RW data .ANY (+RW +ZI) } RW_aDST_Buffer1 0x60000000 0x2000000 { ; RW data diff --git a/Projects/STM32U5G9J-DK2/Applications/FileX/Fx_File_Edit_Standalone/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld b/Projects/STM32U5G9J-DK2/Applications/FileX/Fx_File_Edit_Standalone/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld index 623cb7db3..129f29b90 100644 --- a/Projects/STM32U5G9J-DK2/Applications/FileX/Fx_File_Edit_Standalone/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld +++ b/Projects/STM32U5G9J-DK2/Applications/FileX/Fx_File_Edit_Standalone/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld @@ -44,7 +44,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 3008K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } diff --git a/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5G9ZJTXQ_MODULE_FLASH.ld b/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5G9ZJTXQ_MODULE_FLASH.ld index 2721c7958..c8ade42a0 100644 --- a/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5G9ZJTXQ_MODULE_FLASH.ld +++ b/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5G9ZJTXQ_MODULE_FLASH.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 896k + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 896k RAM (wx) : ORIGIN = 0x20020000, LENGTH = 128k } diff --git a/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_Thread_Creation/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld b/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_Thread_Creation/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld index 623cb7db3..129f29b90 100644 --- a/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_Thread_Creation/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld +++ b/Projects/STM32U5G9J-DK2/Applications/ThreadX/Tx_Thread_Creation/STM32CubeIDE/STM32U5G9ZJTXQ_FLASH.ld @@ -44,7 +44,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 3008K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } diff --git a/Projects/STM32U5G9J-DK2/Examples/BSP/EWARM/stm32u5g9xx_flash.icf b/Projects/STM32U5G9J-DK2/Examples/BSP/EWARM/stm32u5g9xx_flash.icf index 0a4e673f2..06004fce8 100644 --- a/Projects/STM32U5G9J-DK2/Examples/BSP/EWARM/stm32u5g9xx_flash.icf +++ b/Projects/STM32U5G9J-DK2/Examples/BSP/EWARM/stm32u5g9xx_flash.icf @@ -7,7 +7,7 @@ define symbol __ICFEDIT_intvec_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x083FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; -define symbol __ICFEDIT_region_RAM_end__ = 0x2005FFFF; +define symbol __ICFEDIT_region_RAM_end__ = 0x202EFFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x6000; diff --git a/Projects/STM32U5x9J-DK/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5A9NJHXQ_MODULE_FLASH.ld b/Projects/STM32U5x9J-DK/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5A9NJHXQ_MODULE_FLASH.ld index 2721c7958..c8ade42a0 100644 --- a/Projects/STM32U5x9J-DK/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5A9NJHXQ_MODULE_FLASH.ld +++ b/Projects/STM32U5x9J-DK/Applications/ThreadX/Tx_MPU/STM32CubeIDE/STM32U5A9NJHXQ_MODULE_FLASH.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 896k + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 896k RAM (wx) : ORIGIN = 0x20020000, LENGTH = 128k }