diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index e9d1684c689..7195bf36c31 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -163,6 +163,15 @@ MEMORY /* PSRAM seg */ extern_ram_seg(RWX) : org = 0x48000000, len = IDROM_SEG_SIZE + +#if CONFIG_SPIRAM_XIP_FROM_PSRAM + /** + * Distinct region overlapping `drom_seg` at the same origin, so `.ext_ram.dummy` + * gets its own location counter and `.ext_ram.bss` can reclaim the space of + * NOLOAD rodata (e.g. `.rodata_wlog_*`). + */ + ext_ram_xip_seg(RWX) : org = 0x48000020, len = IDROM_SEG_SIZE - 0x20 +#endif // CONFIG_SPIRAM_XIP_FROM_PSRAM } /* Heap ends at top of dram0_0_seg */ @@ -212,7 +221,7 @@ REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS #if CONFIG_SPIRAM_XIP_FROM_PSRAM - REGION_ALIAS("ext_ram_seg", drom_seg); + REGION_ALIAS("ext_ram_seg", ext_ram_xip_seg); #else REGION_ALIAS("ext_ram_seg", extern_ram_seg); #endif //#if CONFIG_SPIRAM_XIP_FROM_PSRAM diff --git a/components/esp_system/ld/esp32s31/memory.ld.in b/components/esp_system/ld/esp32s31/memory.ld.in index 5c472a46a77..666eca55342 100644 --- a/components/esp_system/ld/esp32s31/memory.ld.in +++ b/components/esp_system/ld/esp32s31/memory.ld.in @@ -85,6 +85,15 @@ MEMORY /* PSRAM seg */ extern_ram_seg(RWX) : org = 0x50000000, len = IDROM_SEG_SIZE + +#if CONFIG_SPIRAM_XIP_FROM_PSRAM + /** + * Distinct region overlapping `drom_seg` at the same origin, so `.ext_ram.dummy` + * gets its own location counter and `.ext_ram.bss` can reclaim the space of + * NOLOAD rodata (e.g. `.rodata_wlog_*`). + */ + ext_ram_xip_seg(RWX) : org = 0x50000020, len = IDROM_SEG_SIZE - 0x20 +#endif // CONFIG_SPIRAM_XIP_FROM_PSRAM } /* Heap ends at top of dram0_0_seg */ @@ -114,7 +123,7 @@ REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS #if CONFIG_SPIRAM_XIP_FROM_PSRAM - REGION_ALIAS("ext_ram_seg", drom_seg); + REGION_ALIAS("ext_ram_seg", ext_ram_xip_seg); #else REGION_ALIAS("ext_ram_seg", extern_ram_seg); #endif //#if CONFIG_SPIRAM_XIP_FROM_PSRAM diff --git a/components/esp_system/ld/ld.ext_ram.sections b/components/esp_system/ld/ld.ext_ram.sections index b214e5915b3..434cc259d85 100644 --- a/components/esp_system/ld/ld.ext_ram.sections +++ b/components/esp_system/ld/ld.ext_ram.sections @@ -9,6 +9,13 @@ .ext_ram.dummy (NOLOAD) : { HIDDEN(_ext_ram_on_same_bus = ORIGIN(ext_ram_seg) == ORIGIN(flash_rodata_seg)); + /** + * This must be the first section placed in `ext_ram_seg`, and `ext_ram_seg` must be + * a distinct region (not a REGION_ALIAS of `flash_rodata_seg`) so it has its own + * location counter. Otherwise NOLOAD rodata (e.g. .rodata_wlog_*) placed after + * `_rodata_reserved_end` leaves the counter past the skip target, and moving it + * backwards here is a hard linker error. + */ . = _ext_ram_on_same_bus ? ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start) : 0; . = ALIGN(_ext_ram_on_same_bus ? _esp_mmu_page_size : 0); } > ext_ram_seg