diff --git a/components/esp_system/ld/esp32c2/memory.ld.in b/components/esp_system/ld/esp32c2/memory.ld.in index ec02e05b65..c534d2af20 100644 --- a/components/esp_system/ld/esp32c2/memory.ld.in +++ b/components/esp_system/ld/esp32c2/memory.ld.in @@ -9,6 +9,12 @@ #include "sdkconfig.h" #include "ld.common" +/** + * physical memory is mapped twice to the virtual address (IRAM and DRAM). + * `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory + */ +_iram_dram_shared = 1; + #define SRAM_IRAM_START 0x4037C000 #define SRAM_DRAM_START 0x3FCA0000 #define ICACHE_SIZE 0x4000 /* ICache size is fixed to 16KB on ESP32-C2 */ @@ -64,29 +70,15 @@ MEMORY /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000; +REGION_ALIAS("iram_text_seg", iram0_0_seg); +REGION_ALIAS("dram_seg", dram0_0_seg); #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", iram0_2_seg); + REGION_ALIAS("flash_text_seg", iram0_2_seg); + REGION_ALIAS("flash_rodata_seg", drom0_0_seg); #else - REGION_ALIAS("default_code_seg", iram0_0_seg); + REGION_ALIAS("flash_text_seg", iram0_0_seg); + REGION_ALIAS("flash_rodata_seg", dram0_0_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom0_0_seg); -#else - REGION_ALIAS("default_rodata_seg", dram0_0_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; diff --git a/components/esp_system/ld/esp32c2/sections.ld.in b/components/esp_system/ld/esp32c2/sections.ld.in index 4db9c8e5fc..6a8a68b707 100644 --- a/components/esp_system/ld/esp32c2/sections.ld.in +++ b/components/esp_system/ld/esp32c2/sections.ld.in @@ -4,368 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); +#include "ld.iram.sections" - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); +#include "ld.dram.sections" - mapping[iram0_text] +#include "ld.flash.sections" - } > iram0_0_seg +#include "ld.heap.sections" - /** - * This section is required to skip .iram0.text area because iram0_0_seg and - * dram0_0_seg reflect the same address space on different buses. - */ - .dram0.dummy (NOLOAD): - { - . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; - } > dram0_0_seg - - /** - * This section MUST be placed at the beginning of the DRAM0, which will be - * released along with iram0_bt.text when Bluetooth is no longer in use. - */ - .dram0.bt.data : - { - _data_start = ABSOLUTE(.); - mapping[dram0_bt_data] - } > dram0_0_seg - - .dram0.bt.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_bt_start) - - mapping[dram0_bt_bss] - - _bss_bt_end = ABSOLUTE(.); - } > dram0_0_seg - - .dram0.data : - { - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > dram0_0_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > dram0_0_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > dram0_0_seg - - ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), - "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - ALIGNED_SYMBOL(4, _iram_text_end) - } > iram0_0_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > iram0_0_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - } > iram0_0_seg - - /** - * This section needs to be placed at the end of the IRAM0, which will be - * released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no - * longer in use. - */ - .iram0.bt.text : - { - ALIGNED_SYMBOL(16, _iram_bt_text_start) - - mapping[iram0_bt_text] - - ALIGNED_SYMBOL(16, _iram_end) - } > iram0_0_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > dram0_0_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } - -ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), - "IRAM0 segment data does not fit.") - -ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), - "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/esp32c3/memory.ld.in b/components/esp_system/ld/esp32c3/memory.ld.in index 4c62313833..8dc87d84aa 100644 --- a/components/esp_system/ld/esp32c3/memory.ld.in +++ b/components/esp_system/ld/esp32c3/memory.ld.in @@ -16,9 +16,11 @@ #include "ld.common" /** - * physical memory is mapped twice to the vritual address (IRAM and DRAM). + * physical memory is mapped twice to the virtual address (IRAM and DRAM). * `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory */ +_iram_dram_shared = 1; + #define SRAM_IRAM_START 0x4037C000 #define SRAM_DRAM_START 0x3FC7C000 #define ICACHE_SIZE 0x4000 /* ICache size is fixed to 16KB on ESP32-C3 */ @@ -87,38 +89,25 @@ MEMORY /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * As C3 only has RTC fast memory, this is not configurable like on other targets */ +REGION_ALIAS("rtc_text_seg", rtc_iram_seg); REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_force_fast_seg", rtc_iram_seg); +REGION_ALIAS("rtc_force_slow_seg", rtc_iram_seg); + +REGION_ALIAS("iram_text_seg", iram0_0_seg); +REGION_ALIAS("dram_seg", dram0_0_seg); #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", iram0_2_seg); + REGION_ALIAS("flash_text_seg", iram0_2_seg); + REGION_ALIAS("flash_rodata_seg", drom0_0_seg); #else - REGION_ALIAS("default_code_seg", iram0_0_seg); + REGION_ALIAS("flash_text_seg", iram0_0_seg); + REGION_ALIAS("flash_rodata_seg", dram0_0_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom0_0_seg); -#else - REGION_ALIAS("default_rodata_seg", dram0_0_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in index 2bd4bcfa1e..7e9194b284 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -4,484 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - ALIGNED_SYMBOL(4, _rtc_fast_start) +#include "ld.rtc.sections" - HIDDEN(_rtc_code_start = .); +#include "ld.iram.sections" - mapping[rtc_text] +#include "ld.dram.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.flash.sections" - HIDDEN(_rtc_code_end = .); +#include "ld.heap.sections" - /* Padding for possible CPU prefetch + 4B alignment for PMS split lines. */ - . = ((_rtc_code_end - _rtc_code_start) == 0) ? - ALIGN(0) : _esp_memprot_prefetch_pad_size + ALIGN(4); - - _rtc_text_end = ABSOLUTE(.); - } > rtc_iram_seg - - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > rtc_data_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > rtc_data_location - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > rtc_data_location - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > rtc_data_location - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > rtc_slow_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied - * on it. - * >> put new data here << - */ - - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > iram0_0_seg - - /** - * This section is required to skip .iram0.text area because iram0_0_seg and - * dram0_0_seg reflect the same address space on different buses. - */ - .dram0.dummy (NOLOAD): - { - . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; - } > dram0_0_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > dram0_0_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > dram0_0_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > dram0_0_seg - - ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), - "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Padding for possible CPU prefetch + alignment for PMS split lines */ - . += _esp_memprot_prefetch_pad_size; - . = ALIGN(_esp_memprot_align_size); - - /* iram_end_test section exists for use by memprot unit tests only */ - *(.iram_end_test) - - _iram_text_end = ABSOLUTE(.); - } > iram0_0_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > iram0_0_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - ALIGNED_SYMBOL(16, _iram_end) - } > iram0_0_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > dram0_0_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } - -ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), - "IRAM0 segment data does not fit.") - -ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), - "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/esp32c5/memory.ld.in b/components/esp_system/ld/esp32c5/memory.ld.in index 160b3232a4..180998cb40 100644 --- a/components/esp_system/ld/esp32c5/memory.ld.in +++ b/components/esp_system/ld/esp32c5/memory.ld.in @@ -96,47 +96,34 @@ MEMORY lp_reserved_seg(RW) : org = 0x50000000 + 0x4000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM /* PSRAM seg */ - extern_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 + ext_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 } /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * C5 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section * Thus, the following region segments are not configurable like on other targets */ -REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); -REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_text_seg", lp_ram_seg); +REGION_ALIAS("rtc_data_seg", lp_ram_seg ); +REGION_ALIAS("rtc_slow_seg", lp_ram_seg ); +REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg); REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; +OFFSET_TEE = 0x2b0; diff --git a/components/esp_system/ld/esp32c5/sections.ld.in b/components/esp_system/ld/esp32c5/sections.ld.in index b865acd4e0..ac9ad9508a 100644 --- a/components/esp_system/ld/esp32c5/sections.ld.in +++ b/components/esp_system/ld/esp32c5/sections.ld.in @@ -4,546 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for the previous - * region (ULP mem) regardless of its end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) +#include "ld.rtc.sections" - *(.rtc.entry.text) +#include "ld.iram.sections" - mapping[rtc_text] +#include "ld.dram.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.flash.sections" - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.ext_ram.sections" - _rtc_text_end = ABSOLUTE(.); - } > lp_ram_seg +#include "ld.heap.sections" - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied - * on it. - * >> put new data here << - */ - - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - _vector_table_start = ABSOLUTE(.); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - ALIGNED_SYMBOL(4, _invalid_pc_placeholder) - - /* esp_tee_config_t structure: used to share information between the TEE and REE - * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) - * This symbol is expected by the TEE at an offset of 0x2b0 from the vector table start. - */ -#if CONFIG_SECURE_ENABLE_TEE - ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) - ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2b0, "esp_tee_app_cfg must be at an offset 0x2b0 from the vector table start"); - *libesp_tee.a:(.esp_tee_app_cfg); -#endif - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - /** - * This section is required to skip .iram0.text area because sram_seg and - * sram_seg reflect the same address space on different buses. - */ - .dram0.dummy (NOLOAD): - { - . = ORIGIN(sram_seg) + _iram_end - _iram_start; - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash text region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { -#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash rodata region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - - /* External RAM */ - /** - * This section is required to skip flash sections, because `extern_ram_seg` - * and `drom_seg` / `irom_seg` are on the same bus when app build use flash sections - */ - .ext_ram.dummy (NOLOAD): - { - . = ORIGIN(extern_ram_seg); - . = . + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (_esp_mmu_page_size); - } > extern_ram_seg - -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - /* This section holds .ext_ram.bss data, and will be put in PSRAM */ - .ext_ram.bss (NOLOAD) : - { - _ext_ram_bss_start = ABSOLUTE(.); - - mapping[extern_ram] - - ALIGNED_SYMBOL(4, _ext_ram_bss_end) - } > extern_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - -#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - /** - * This section holds data that won't be initialised when startup. - * This section locates in External RAM region. - */ - .ext_ram_noinit (NOLOAD) : - { - _ext_ram_noinit_start = ABSOLUTE(.); - - *(.ext_ram_noinit*) - - ALIGNED_SYMBOL(4, _ext_ram_noinit_end) - } > extern_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } - -ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "IRAM0 segment data does not fit.") - -ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/esp32c6/memory.ld.in b/components/esp_system/ld/esp32c6/memory.ld.in index 4345cd201f..130b57d918 100644 --- a/components/esp_system/ld/esp32c6/memory.ld.in +++ b/components/esp_system/ld/esp32c6/memory.ld.in @@ -101,41 +101,28 @@ MEMORY /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * C6 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section * Thus, the following region segments are not configurable like on other targets */ -REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); -REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_text_seg", lp_ram_seg); +REGION_ALIAS("rtc_data_seg", lp_ram_seg); +REGION_ALIAS("rtc_slow_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg); REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; +OFFSET_TEE = 0x2e0; diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in index ed1841e2a7..82a54cdc52 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -4,491 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for the previous - * region (ULP mem) regardless of its end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) +#include "ld.rtc.sections" - *(.rtc.entry.text) +#include "ld.iram.sections" - mapping[rtc_text] +#include "ld.dram.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.flash.sections" - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.heap.sections" - _rtc_text_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied - * on it. - * >> put new data here << - */ - - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - -#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS - /* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */ - KEEP(*(.ocd_stub.code)); - KEEP(*(.ocd_stub.tramp)); - . = ALIGN(0x800); - KEEP(*(.ocd_stub.data)); - KEEP(*(.ocd_stub.bss)); - KEEP(*(.ocd_stub.stack)); - KEEP(*(.ocd_stub.params)); - . = ALIGN(0x1000); - KEEP(*(.ocd_stub.scratchmem)); - ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000"); -#endif - - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - _vector_table_start = ABSOLUTE(.); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - /* esp_tee_config_t structure: used to share information between the TEE and REE - * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) - * This symbol is expected by the TEE at an offset of 0x300 from the vector table start. - */ -#if CONFIG_SECURE_ENABLE_TEE - ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) - ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start"); - *libesp_tee.a:(.esp_tee_app_cfg); -#endif - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } diff --git a/components/esp_system/ld/esp32c61/memory.ld.in b/components/esp_system/ld/esp32c61/memory.ld.in index 1d2137e899..c5b947b49b 100644 --- a/components/esp_system/ld/esp32c61/memory.ld.in +++ b/components/esp_system/ld/esp32c61/memory.ld.in @@ -59,34 +59,22 @@ MEMORY #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* PSRAM seg */ - extern_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 + ext_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 } /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; +OFFSET_TEE = 0x2b0; diff --git a/components/esp_system/ld/esp32c61/sections.ld.in b/components/esp_system/ld/esp32c61/sections.ld.in index 40b7d82740..fa08689924 100644 --- a/components/esp_system/ld/esp32c61/sections.ld.in +++ b/components/esp_system/ld/esp32c61/sections.ld.in @@ -4,391 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); +#include "ld.iram.sections" - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); +#include "ld.dram.sections" - mapping[iram0_text] +#include "ld.flash.sections" - } > sram_seg +#include "ld.ext_ram.sections" - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.heap.sections" - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - /** - * This section is required to skip .iram0.text area because sram_seg and - * sram_seg reflect the same address space on different buses. - */ - .dram0.dummy (NOLOAD): - { - . = ORIGIN(sram_seg) + _iram_end - _iram_start; - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash text region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { -#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash rodata region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - - /* External RAM */ - /** - * This section is required to skip flash sections, because `extern_ram_seg` - * and `drom_seg` / `irom_seg` are on the same bus when app build use flash sections - */ - .ext_ram.dummy (NOLOAD): - { - . = ORIGIN(extern_ram_seg); - . = . + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (_esp_mmu_page_size); - } > extern_ram_seg - -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - /* This section holds .ext_ram.bss data, and will be put in PSRAM */ - .ext_ram.bss (NOLOAD) : - { - _ext_ram_bss_start = ABSOLUTE(.); - - mapping[extern_ram] - - ALIGNED_SYMBOL(4, _ext_ram_bss_end) - } > extern_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - -#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - /** - * This section holds data that won't be initialized when startup. - * This section locates in External RAM region. - */ - .ext_ram_noinit (NOLOAD) : - { - _ext_ram_noinit_start = ABSOLUTE(.); - - *(.ext_ram_noinit*) - - ALIGNED_SYMBOL(4, _ext_ram_noinit_end) - } > extern_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } - -ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "IRAM0 segment data does not fit.") - -ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/esp32h2/memory.ld.in b/components/esp_system/ld/esp32h2/memory.ld.in index ba1e5d9960..c78b842214 100644 --- a/components/esp_system/ld/esp32h2/memory.ld.in +++ b/components/esp_system/ld/esp32h2/memory.ld.in @@ -97,40 +97,27 @@ MEMORY /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * As H2 only has RTC fast memory, this is not configurable like on other targets */ -REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); -REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_text_seg", lp_ram_seg); +REGION_ALIAS("rtc_data_seg", lp_ram_seg); +REGION_ALIAS("rtc_slow_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg); REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; +OFFSET_TEE = 0x2e0; diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index 09dd47ed2e..82a54cdc52 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -4,493 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for any potential previous - * region regardless of its end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) +#include "ld.rtc.sections" - *(.rtc.entry.text) +#include "ld.iram.sections" - mapping[rtc_text] +#include "ld.dram.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.flash.sections" - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.heap.sections" - _rtc_text_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied - * on it. - * >> put new data here << - */ - - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - -#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS - /* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */ - KEEP(*(.ocd_stub.code)); - KEEP(*(.ocd_stub.tramp)); - . = ALIGN(0x800); - KEEP(*(.ocd_stub.data)); - KEEP(*(.ocd_stub.bss)); - KEEP(*(.ocd_stub.stack)); - KEEP(*(.ocd_stub.params)); - . = ALIGN(0x1000); - KEEP(*(.ocd_stub.scratchmem)); - ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000"); -#endif - - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - _vector_table_start = ABSOLUTE(.); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - ALIGNED_SYMBOL(4, _invalid_pc_placeholder) - - /* esp_tee_config_t structure: used to share information between the TEE and REE - * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) - * This symbol is expected by the TEE at an offset of 0x300 from the vector table start. - */ -#if CONFIG_SECURE_ENABLE_TEE - ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) - ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start"); - *libesp_tee.a:(.esp_tee_app_cfg); -#endif - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } diff --git a/components/esp_system/ld/esp32h21/memory.ld.in b/components/esp_system/ld/esp32h21/memory.ld.in index e8d8e8c2ce..9f54f20d17 100644 --- a/components/esp_system/ld/esp32h21/memory.ld.in +++ b/components/esp_system/ld/esp32h21/memory.ld.in @@ -80,41 +80,27 @@ MEMORY /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * H21 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section * Thus, the following region segments are not configurable like on other targets */ -REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); -REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_text_seg", lp_ram_seg); +REGION_ALIAS("rtc_data_seg", lp_ram_seg); +REGION_ALIAS("rtc_slow_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg); REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x100; diff --git a/components/esp_system/ld/esp32h21/sections.ld.in b/components/esp_system/ld/esp32h21/sections.ld.in index cb7b93517c..41b565df28 100644 --- a/components/esp_system/ld/esp32h21/sections.ld.in +++ b/components/esp_system/ld/esp32h21/sections.ld.in @@ -6,480 +6,21 @@ /* TODO: [ESP32H21] IDF-11900, IDF-11908 */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for any potential previous - * region regardless of its end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) +#include "ld.rtc.sections" - *(.rtc.entry.text) +#include "ld.iram.sections" - mapping[rtc_text] +#include "ld.dram.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.flash.sections" - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.heap.sections" - _rtc_text_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied - * on it. - * >> put new data here << - */ - - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - -#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS - /* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */ - KEEP(*(.ocd_stub.code)); - KEEP(*(.ocd_stub.tramp)); - . = ALIGN(0x800); - KEEP(*(.ocd_stub.data)); - KEEP(*(.ocd_stub.bss)); - KEEP(*(.ocd_stub.stack)); - KEEP(*(.ocd_stub.params)); - . = ALIGN(0x1000); - KEEP(*(.ocd_stub.scratchmem)); - ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000"); -#endif - - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } diff --git a/components/esp_system/ld/esp32h4/memory.ld.in b/components/esp_system/ld/esp32h4/memory.ld.in index ac79824bb4..9d3cb3c865 100644 --- a/components/esp_system/ld/esp32h4/memory.ld.in +++ b/components/esp_system/ld/esp32h4/memory.ld.in @@ -69,28 +69,15 @@ MEMORY /* Heap ends at top of sram_seg */ _heap_end = 0x40000000; +REGION_ALIAS("iram_text_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_code_seg", irom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else - REGION_ALIAS("default_code_seg", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("default_rodata_seg", drom_seg); -#else - REGION_ALIAS("default_rodata_seg", sram_seg); -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS - -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x40; diff --git a/components/esp_system/ld/esp32h4/sections.ld.in b/components/esp_system/ld/esp32h4/sections.ld.in index 3dbf9aa964..27062100e5 100644 --- a/components/esp_system/ld/esp32h4/sections.ld.in +++ b/components/esp_system/ld/esp32h4/sections.ld.in @@ -6,331 +6,19 @@ /* TODO: [ESP32H4] IDF-12305 inherited from verification branch, need check */ -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { +#include "ld.iram.sections" - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); +#include "ld.dram.sections" - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); +#include "ld.flash.sections" - mapping[iram0_text] +#include "ld.heap.sections" - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(8, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(8, _bss_end) - } > sram_seg - - ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > default_code_seg - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > default_rodata_seg - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > default_rodata_seg - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - mapping[rodata_noload] - } > default_rodata_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } - -ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "IRAM0 segment data does not fit.") - -ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), - "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 37b5f0f8f1..ede8e20542 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -120,37 +120,46 @@ MEMORY /* Heap ends at top of dram0_0_seg */ _heap_end = 0x50000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /** * The lines below define location alias for .rtc.data section * P4 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section * Thus, the following region segments are not configurable like on other targets */ -REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); -REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); -REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_text_seg", lp_ram_seg); +REGION_ALIAS("rtc_data_seg", lp_ram_seg); +REGION_ALIAS("rtc_slow_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg); +REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg); REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("text_seg_low", irom_seg); -#else #if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 - REGION_ALIAS("text_seg_low", sram_low); + REGION_ALIAS("iram_text_seg", sram_low); + REGION_ALIAS("dram_seg", sram_low); + REGION_ALIAS("dram_high_seg", sram_high); + ASSERT(((_heap_start_high - ORIGIN(dram_high_seg)) <= LENGTH(dram_high_seg)), + "DRAM_HIGH segment data does not fit.") + + /* define X_low symbols */ + _data_start_low = _data_start; + _data_end_low = _data_end; + _bss_start_low = _bss_start; + _bss_end_low = _bss_end; + _heap_start_low = _heap_start; #else - REGION_ALIAS("text_seg_low", sram_seg); -#endif //CONFIG_ESP32P4_SELECTS_REV_LESS_V3 -#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("iram_text_seg", sram_seg); + REGION_ALIAS("dram_seg", sram_seg); +#endif #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - REGION_ALIAS("rodata_seg_low", drom_seg); + REGION_ALIAS("flash_text_seg", irom_seg); + REGION_ALIAS("flash_rodata_seg", drom_seg); #else #if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 - REGION_ALIAS("rodata_seg_low", sram_low); - REGION_ALIAS("rodata_seg_high", sram_high); + REGION_ALIAS("flash_text_seg", sram_low); + REGION_ALIAS("flash_rodata_seg", sram_low); #else - REGION_ALIAS("rodata_seg_low", sram_seg); + REGION_ALIAS("flash_text_seg", sram_seg); + REGION_ALIAS("flash_rodata_seg", sram_seg); #endif //CONFIG_ESP32P4_SELECTS_REV_LESS_V3 #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS @@ -160,16 +169,4 @@ REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); REGION_ALIAS("ext_ram_seg", extern_ram_seg); #endif //#if CONFIG_SPIRAM_XIP_FROM_PSRAM -/** - * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must - * also be first in the segment. - */ -#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS - ASSERT(_flash_rodata_dummy_start == ORIGIN(rodata_seg_low), - ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") -#endif - -#if CONFIG_ESP_SYSTEM_USE_EH_FRAME - ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); - ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); -#endif +ALIGN_VECTOR_TABLE = 0x40; diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index d3a97e8124..61be839fc6 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -4,582 +4,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "sdkconfig.h" -#include "ld.common" - /* Default entry point */ ENTRY(call_start_cpu0); SECTIONS { - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for the previous - * region (ULP mem/RTC reserved) regardless of their end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) +#include "ld.rtc.sections" - arrays[rtc_text] - mapping[rtc_text] +#include "ld.tcm.sections" - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) +#include "ld.iram.sections" - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); +#include "ld.dram.sections" - ALIGNED_SYMBOL(4, _rtc_text_end) - } > lp_ram_seg +#include "ld.flash.sections" - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) +#include "ld.ext_ram.sections" - arrays[rtc_force_fast] - mapping[rtc_force_fast] +#include "ld.heap.sections" - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - arrays[rtc_data] - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - arrays[rtc_bss] - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the beginning of the segment and code is relied - * on it. - * >> put new data here << - */ - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - _rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg); - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .tcm.text : - { - /* Code marked as running out of TCM */ - _tcm_text_start = ABSOLUTE(.); - - arrays[tcm_text] - mapping[tcm_text] - - _tcm_text_end = ABSOLUTE(.); - } > tcm_idram_seg - - .tcm.data : - { - _tcm_data_start = ABSOLUTE(.); - - arrays[tcm_data] - mapping[tcm_data] - - _tcm_data_end = ABSOLUTE(.); - } > tcm_idram_seg - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - arrays[iram0_text] - mapping[iram0_text] - - } > sram_low - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_low - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - arrays[iram0_data] - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_low - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - arrays[iram0_bss] - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(16, _iram_end) - } > sram_low - - .dram0.data : - { - _data_start_low = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - arrays[dram0_data] - mapping[dram0_data] - - _data_end_low = ABSOLUTE(.); - } > sram_low - - .dram1.data : - { - _data_start_high = ABSOLUTE(.); - - mapping[dram0_data] - - _data_end_high = ABSOLUTE(.); - } > sram_high - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_low - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - arrays[flash_text] - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash text region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > text_seg_low - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > rodata_seg_low - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - arrays[flash_rodata] - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - . = ALIGN(ALIGNOF(.flash.init_array)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array) - - .flash.init_array : - { - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - * - * RISC-V gcc is configured with --enable-initfini-array so it emits - * .init_array section instead. But the init_priority sections will be - * sorted for iteration in ascending order during startup. - * The rest of the init_array sections is sorted for iteration in descending - * order during startup, however. Hence a different section is generated for - * the init_priority functions which is iterated in ascending order during - * startup. The corresponding code can be found in startup.c. - */ - ALIGNED_SYMBOL(4, __init_priority_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) - __init_priority_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > rodata_seg_low - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { -#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash rodata region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - arrays[rodata_noload] - mapping[rodata_noload] - } > rodata_seg_low - -#if CONFIG_SPIRAM_XIP_FROM_PSRAM - /** - * This section is required to skip flash sections, because `extern_ram_seg` - * and `drom_seg` / `irom_seg` are on the same bus when xip on psram - */ - .ext_ram.dummy (NOLOAD): - { - . = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (_esp_mmu_page_size); - } > ext_ram_seg -#endif //CONFIG_SPIRAM_XIP_FROM_PSRAM - -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - /* This section holds .ext_ram.bss data, and will be put in PSRAM */ - .ext_ram.bss (NOLOAD) : - { - _ext_ram_bss_start = ABSOLUTE(.); - arrays[extern_ram] - mapping[extern_ram] - ALIGNED_SYMBOL(4, _ext_ram_bss_end) - } > ext_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - -#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - /** - * This section holds data that won't be initialised when startup. - * This section locates in External RAM region. - */ - .ext_ram_noinit (NOLOAD) : - { - _ext_ram_noinit_start = ABSOLUTE(.); - - *(.ext_ram_noinit*) - - ALIGNED_SYMBOL(4, _ext_ram_noinit_end) - } > ext_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(4, _bss_start_low) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - arrays[dram0_bss] - mapping[dram0_bss] - - ALIGNED_SYMBOL(4, _bss_end_low) - } > sram_low - - .dram1.bss (NOLOAD) : - { - ALIGNED_SYMBOL(4, _bss_start_high) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(4, _bss_end_high) - } > sram_high - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start_low (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start_low) - } > sram_low - - /* Marks the end of data, bss and possibly rodata */ - .dram1.heap_start_high (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start_high) - } > sram_high - -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } diff --git a/components/esp_system/ld/esp32p4/sections.rev3.ld.in b/components/esp_system/ld/esp32p4/sections.rev3.ld.in deleted file mode 100644 index 3ff1254a5b..0000000000 --- a/components/esp_system/ld/esp32p4/sections.rev3.ld.in +++ /dev/null @@ -1,572 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" -#include "ld.common" - -/* Default entry point */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - /** - * RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ - .rtc.text : - { - /* Align the start of RTC code region as per PMP granularity - * this ensures we do not overwrite the permissions for the previous - * region (ULP mem/RTC reserved) regardless of their end alignment - */ - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) - ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) - - arrays[rtc_text] - mapping[rtc_text] - - *rtc_wake_stub*.*(.text .text.*) - *(.rtc_text_end_test) - - /* Align the end of RTC code region as per PMP granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _rtc_text_end) - } > lp_ram_seg - - /** - * This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_fast : - { - ALIGNED_SYMBOL(4, _rtc_force_fast_start) - - arrays[rtc_force_fast] - mapping[rtc_force_fast] - - *(.rtc.force_fast .rtc.force_fast.*) - - ALIGNED_SYMBOL(4, _rtc_force_fast_end) - } > lp_ram_seg - - /** - * RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ - .rtc.data : - { - _rtc_data_start = ABSOLUTE(.); - - arrays[rtc_data] - mapping[rtc_data] - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) - - _rtc_data_end = ABSOLUTE(.); - } > lp_ram_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ - .rtc.bss (NOLOAD) : - { - _rtc_bss_start = ABSOLUTE(.); - - *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) - *rtc_wake_stub*.*(COMMON) - - arrays[rtc_bss] - mapping[rtc_bss] - - _rtc_bss_end = ABSOLUTE(.); - } > lp_ram_seg - - /** - * This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * User data marked with RTC_NOINIT_ATTR will be placed - * into this section. See the file "esp_attr.h" for more information. - */ - .rtc_noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_noinit_start) - - *(.rtc_noinit .rtc_noinit.*) - - ALIGNED_SYMBOL(4, _rtc_noinit_end) - } > lp_ram_seg - - /** - * This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ - .rtc.force_slow : - { - ALIGNED_SYMBOL(4, _rtc_force_slow_start) - - *(.rtc.force_slow .rtc.force_slow.*) - - ALIGNED_SYMBOL(4, _rtc_force_slow_end) - } > lp_ram_seg - -#if CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND - .rtc.p4_rev3_mspi_workaround : - { - ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_start) - KEEP (*(.p4_rev3_mspi_workaround.rtc_text .p4_rev3_mspi_workaround.rtc_text.*)) - ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_end) - } > rev3_mspi_workaround_seg -#endif - - /** - * This section holds RTC data that should have fixed addresses. - * The data are not initialized at power-up and are retained during deep - * sleep. - */ - .rtc_reserved (NOLOAD): - { - ALIGNED_SYMBOL(4, _rtc_reserved_start) - - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - - /** - * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the beginning of the segment and code is relied - * on it. - * >> put new data here << - */ - - _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; - _rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg); - ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), - "RTC reserved segment data does not fit.") - - /* Get size of rtc slow data based on rtc_data_location alias */ - _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_slow_end - _rtc_data_start) - : (_rtc_force_slow_end - _rtc_force_slow_start); - - _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) - ? (_rtc_force_fast_end - _rtc_fast_start) - : (_rtc_noinit_end - _rtc_fast_start); - - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), - "RTC_SLOW segment data does not fit.") - - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), - "RTC_FAST segment data does not fit.") - - .tcm.text : - { - /* Code marked as running out of TCM */ - _tcm_text_start = ABSOLUTE(.); - - arrays[tcm_text] - mapping[tcm_text] - - _tcm_text_end = ABSOLUTE(.); - } > tcm_idram_seg - - .tcm.data : - { - _tcm_data_start = ABSOLUTE(.); - - arrays[tcm_data] - mapping[tcm_data] - - _tcm_data_end = ABSOLUTE(.); - } > tcm_idram_seg - - .iram0.text : - { - _iram_start = ABSOLUTE(.); - /* Vectors go to start of IRAM */ - ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned"); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); - - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - - mapping[iram0_text] - - } > sram_seg - - /* Marks the end of IRAM code segment */ - .iram0.text_end (NOLOAD) : - { - /* Align the end of code region as per PMP region granularity */ - . = ALIGN(_esp_pmp_align_size); - - ALIGNED_SYMBOL(4, _iram_text_end) - } > sram_seg - - .iram0.data : - { - ALIGNED_SYMBOL(16, _iram_data_start) - - mapping[iram0_data] - - _iram_data_end = ABSOLUTE(.); - } > sram_seg - - .iram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(16, _iram_bss_start) - - mapping[iram0_bss] - - _iram_bss_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(16, _iram_end) - } > sram_seg - - /** - * This section is required to skip .iram0.text area because sram_seg and - * sram_seg reflect the same address space on different buses. - */ - .dram0.dummy (NOLOAD): - { - . = ORIGIN(sram_seg) + _iram_end - _iram_start; - } > sram_seg - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.gnu.linkonce.d.*) - *(.data1) - __global_pointer$ = . + 0x800; - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - - mapping[dram0_data] - - _data_end = ABSOLUTE(.); - } > sram_seg - - /** - * This section holds data that should not be initialized at power up. - * The section located in Internal SRAM memory region. The macro _NOINIT - * can be used as attribute to place data into this section. - * See the "esp_attr.h" file for more information. - */ - .noinit (NOLOAD): - { - ALIGNED_SYMBOL(4, _noinit_start) - - *(.noinit .noinit.*) - - ALIGNED_SYMBOL(4, _noinit_end) - } > sram_seg - - .dram0.bss (NOLOAD) : - { - ALIGNED_SYMBOL(4, _bss_start) - - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] - - ALIGNED_SYMBOL(4, _bss_end) - } > sram_seg - - /* Marks the end of data, bss and possibly rodata */ - .dram0.heap_start (NOLOAD) : - { - ALIGNED_SYMBOL(16, _heap_start) - } > sram_seg - - ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.") - - .flash.text : - { - _stext = .; - /** - * Mark the start of flash.text. - * This can be used by the MMU driver to maintain the virtual address. - */ - _instruction_reserved_start = ABSOLUTE(.); - _text_start = ABSOLUTE(.); - - arrays[flash_text] - mapping[flash_text] - - *(.stub) - *(.gnu.linkonce.t.*) - *(.gnu.warning) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - - /** - * CPU will try to prefetch up to 16 bytes of of instructions. - * This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += _esp_flash_mmap_prefetch_pad_size; - -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash text region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - - _text_end = ABSOLUTE(.); - /** - * Mark the flash.text end. - * This can be used for MMU driver to maintain virtual address. - */ - _instruction_reserved_end = ABSOLUTE(.); - _etext = .; - - /** - * Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } > text_seg_low - - /** - * Dummy section represents the .flash.text section but in default_rodata_seg. - * Thus, it must have its alignment and (at least) its size. - */ - .flash_rodata_dummy (NOLOAD): - { - _flash_rodata_dummy_start = .; - - . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); - - /* Add alignment of MMU page size + 0x20 bytes for the mapping header. */ - . = ALIGN(_esp_mmu_page_size) + 0x20; - } > rodata_seg_low - - .flash.appdesc : ALIGN(0x10) - { - /** - * Mark flash.rodata start. - * This can be used for mmu driver to maintain virtual address - */ - _rodata_reserved_start = ABSOLUTE(.); - _rodata_start = ABSOLUTE(.); - - /* !DO NOT PUT ANYTHING BEFORE THIS! */ - - /* Should be the first. App version info. */ - *(.rodata_desc .rodata_desc.*) - /* Should be the second. Custom app version info. */ - *(.rodata_custom_desc .rodata_custom_desc.*) - - /** - * Create an empty gap within this section. Thanks to this, the end of this - * section will match .flash.rodata's begin address. Thus, both sections - * will be merged when creating the final bin image. - */ - . = ALIGN(ALIGNOF(.flash.rodata)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) - - .flash.rodata : ALIGN(0x10) - { - _flash_rodata_start = ABSOLUTE(.); - - arrays[flash_rodata] - mapping[flash_rodata] - -#if CONFIG_LIBC_PICOLIBC - *(.got .got.plt) /* TODO: GCC-439 */ -#endif - *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.gcc_except_table .gcc_except_table.*) - *(.gnu.linkonce.e.*) - . = ALIGN(ALIGNOF(.flash.init_array)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array) - - .flash.init_array : - { - /** - * C++ constructor tables. - * - * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - - . = ALIGN(4); - PROVIDE(__init_priority_array_start = ABSOLUTE(.)); - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - . = ALIGN(4); - PROVIDE(__init_priority_array_end = ABSOLUTE(.)); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) - __init_array_end = ABSOLUTE(.); - __bothinit_array_end = ABSOLUTE(.); - - /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ - ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) - KEEP (*(.reserved_memory_address)) - soc_reserved_memory_region_end = ABSOLUTE(.); - - /* System init functions registered via ESP_SYSTEM_INIT_FN */ - ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) - _esp_system_init_fn_array_end = ABSOLUTE(.); - - _rodata_end = ABSOLUTE(.); - . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA) - -#if EH_FRAME_LINKING_ENABLED - .eh_frame_hdr : - { - ALIGNED_SYMBOL(4, __eh_frame_hdr) - - KEEP (*(.eh_frame_hdr)) - - __eh_frame_hdr_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.eh_frame)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) - - .eh_frame : - { - ALIGNED_SYMBOL(4, __eh_frame) - - KEEP (*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); - - __eh_frame_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.tdata)); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) -#endif // EH_FRAME_LINKING_ENABLED - - .flash.tdata : - { - /* Keep tdata and tbss sections contiguous (no gaps between them). - * The TLS runtime code calculates offsets assuming these sections are - * adjacent. Gaps would cause incorrect address calculations, leading - * to accessing wrong memory. - */ - /* tdata sections */ - _thread_local_data_start = ABSOLUTE(.); -#if CONFIG_LIBC_PICOLIBC - _picolibc_reent_stub_start = ABSOLUTE(.); - KEEP(*(.tdata.errno)) -#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - /* Reproduce the public fields from struct _reent. */ - KEEP(*(.tdata.tls_stdin)) - KEEP(*(.tdata.tls_stdout)) - KEEP(*(.tdata.tls_stderr)) -#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY - _picolibc_reent_stub_end = ABSOLUTE(.); -#endif // CONFIG_LIBC_PICOLIBC - *(.tdata .tdata.* .gnu.linkonce.td.*) - . = ALIGN(ALIGNOF(.flash.tbss)); - _thread_local_data_end = ABSOLUTE(.); - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) - ASSERT_PICOLIBC_REENT_STUB() - - .flash.tbss (NOLOAD) : - { - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - } > rodata_seg_low - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - - /** - * This section contains all the rodata that is not used - * at runtime, helping to avoid an increase in binary size. - */ - .flash.rodata_noload (NOLOAD) : - { -#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /* Align the end of flash rodata region as per PMP granularity to allow using the - * page alignment gap created while mapping the flash region into the PSRAM memory. - */ - . = ALIGN(_esp_pmp_align_size); -#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION - /** - * This symbol marks the end of flash.rodata. It can be utilized by the MMU - * driver to maintain the virtual address. - * NOLOAD rodata may not be included in this section. - */ - _rodata_reserved_end = .; - - arrays[rodata_noload] - mapping[rodata_noload] - } > rodata_seg_low - -#if CONFIG_SPIRAM_XIP_FROM_PSRAM - /** - * This section is required to skip flash sections, because `extern_ram_seg` - * and `drom_seg` / `irom_seg` are on the same bus when xip on psram - */ - .ext_ram.dummy (NOLOAD): - { - . = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (_esp_mmu_page_size); - } > ext_ram_seg -#endif //CONFIG_SPIRAM_XIP_FROM_PSRAM - -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - /* This section holds .ext_ram.bss data, and will be put in PSRAM */ - .ext_ram.bss (NOLOAD) : - { - _ext_ram_bss_start = ABSOLUTE(.); - arrays[extern_ram] - mapping[extern_ram] - ALIGNED_SYMBOL(4, _ext_ram_bss_end) - } > ext_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - -#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - /** - * This section holds data that won't be initialised when startup. - * This section locates in External RAM region. - */ - .ext_ram_noinit (NOLOAD) : - { - _ext_ram_noinit_start = ABSOLUTE(.); - - *(.ext_ram_noinit*) - - ALIGNED_SYMBOL(4, _ext_ram_noinit_end) - } > ext_ram_seg -#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - -#include "elf_misc.ld.in" -} diff --git a/components/esp_system/ld/ld.cmake b/components/esp_system/ld/ld.cmake index 9464a569ad..5fbb90f6c5 100644 --- a/components/esp_system/ld/ld.cmake +++ b/components/esp_system/ld/ld.cmake @@ -48,10 +48,6 @@ preprocess_linker_file("memory.ld.in" "memory.ld" ld_out_path) target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}") # Generate sections.ld.in and pass it through linker script generator -if(CONFIG_IDF_TARGET_ESP32P4 AND NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3) - preprocess_linker_file("sections.rev3.ld.in" "sections.ld.in" ld_out_path) -else() - preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path) -endif() +preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path) target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}" PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld") diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index f2e2570ef7..4c39566ae2 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -120,3 +120,8 @@ ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \ #else #define ASSERT_PICOLIBC_REENT_STUB() #endif + +#define SECTION_MAPPINGS(SECTION_NAME) \ +\n arrays[SECTION_NAME] \ +\n mapping[SECTION_NAME] \ +\n mutable[SECTION_NAME] diff --git a/components/esp_system/ld/elf_misc.ld.in b/components/esp_system/ld/ld.debug.sections similarity index 72% rename from components/esp_system/ld/elf_misc.ld.in rename to components/esp_system/ld/ld.debug.sections index ce56428853..cd26c00d7f 100644 --- a/components/esp_system/ld/elf_misc.ld.in +++ b/components/esp_system/ld/ld.debug.sections @@ -1,4 +1,5 @@ #include "sdkconfig.h" +#include "ld.common" /** * This section is not included in the binary image; it is only present in the ELF file. @@ -7,20 +8,23 @@ .noload 0 (INFO) : { _noload_keep_in_elf_start = ABSOLUTE(.); + SECTION_MAPPINGS(noload_keep_in_elf) KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - mapping[noload_keep_in_elf] _noload_keep_in_elf_end = ABSOLUTE(.); } /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } @@ -30,18 +34,23 @@ .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ .debug_addr 0 : { *(.debug_addr) } .debug_line_str 0 : { *(.debug_line_str) } @@ -51,30 +60,14 @@ .debug_rnglists 0 : { *(.debug_rnglists) } .debug_str_offsets 0 : { *(.debug_str_offsets) } - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } + /** + * Miscellaneous sections + */ + .comment 0 : { *(.comment) } + .note.GNU-stack 0 : { *(.note.GNU-stack) } -#if CONFIG_IDF_TARGET_ARCH_RISCV - .riscv.attributes 0: { *(.riscv.attributes) } + .riscv.attributes 0 : { *(.riscv.attributes) } - /DISCARD/ : - { - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - *(.rela.*) -#if CONFIG_LIBC_NEWLIB - *(.got .got.plt) /* TODO: GCC-382 */ -#endif -#if !EH_FRAME_LINKING_ENABLED - *(.eh_frame_hdr) - *(.eh_frame) -#endif // !EH_FRAME_LINKING_ENABLED - } -#elif CONFIG_IDF_TARGET_ARCH_XTENSA /** * .xt.prop and .xt.lit sections will be used by the debugger and disassembler * to get more information about raw data present in the code. @@ -85,18 +78,6 @@ * This section will only be present in the ELF file, not in the final binary * For more details, check GCC-212 */ - .xtensa.info 0: { *(.xtensa.info) } - .xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) } - .xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) } - - /DISCARD/ : - { - *(.fini) - *(.eh_frame_hdr) -#if !EH_FRAME_LINKING_ENABLED - *(.eh_frame) -#endif // !EH_FRAME_LINKING_ENABLED - } -#else - #error "Target architecture is not supported!" -#endif + .xtensa.info 0 : { *(.xtensa.info) } + .xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) } + .xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) } diff --git a/components/esp_system/ld/ld.discard.sections b/components/esp_system/ld/ld.discard.sections new file mode 100644 index 0000000000..8851195e68 --- /dev/null +++ b/components/esp_system/ld/ld.discard.sections @@ -0,0 +1,26 @@ +#include "sdkconfig.h" +#include "ld.common" + + /DISCARD/ : + { + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + *(.rela.*) +#if CONFIG_LIBC_NEWLIB + *(.got .got.plt) /* TODO: GCC-382 */ +#endif // CONFIG_LIBC_NEWLIB + + *(.fini) +#if CONFIG_IDF_TARGET_ARCH_XTENSA + *(.eh_frame_hdr) +#endif // CONFIG_IDF_TARGET_ARCH_XTENSA + +#if !EH_FRAME_LINKING_ENABLED + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !EH_FRAME_LINKING_ENABLED + } diff --git a/components/esp_system/ld/ld.dram.sections b/components/esp_system/ld/ld.dram.sections new file mode 100644 index 0000000000..5519139ab1 --- /dev/null +++ b/components/esp_system/ld/ld.dram.sections @@ -0,0 +1,116 @@ +#include "sdkconfig.h" +#include "ld.common" + + .dram0.dummy (NOLOAD) : + { + /** + * Reserve DRAM space for shared D/IRAM memory configuration. + * + * On certain ESP chips, the same physical SRAM is accessible via two + * different virtual address ranges: + * - IRAM: 0x4xxxxxxx + * - DRAM: 0x3Fxxxxxx + * + * While the virtual addresses differ, both ranges map to the same physical + * memory. + * + * When `_iram_dram_shared` is defined, it indicates this configuration exists. + * We must advance the DRAM location counter past the region used by IRAM code + * to prevent DRAM data from physically overwriting executable IRAM code. + */ + . = DEFINED(_iram_dram_shared) ? ORIGIN(dram_seg) + (_iram_end - _iram_start) : .; + } > dram_seg + + .dram0.data_start : + { + _data_start = .; + } > dram_seg + +#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED + /** + * This sections MUST be placed at the beginning of the DRAM, which will be + * released along with iram0_bt_text when Bluetooth is no longer in use. + */ + .dram0.bt.data : + { + SECTION_MAPPINGS(dram0_bt_data) + } > dram_seg + + .dram0.bt.bss (NOLOAD) : + { + ALIGNED_SYMBOL(8, _bss_bt_start) + + SECTION_MAPPINGS(dram0_bt_bss) + + _bss_bt_end = ABSOLUTE(.); + } > dram_seg +#endif + + .dram0.data : + { + *(.gnu.linkonce.d.*) + *(.data1) + __global_pointer$ = . + 0x800; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + + SECTION_MAPPINGS(dram0_data) + + _data_end = ABSOLUTE(.); + } > dram_seg + + /** + * This section holds data that should not be initialized at power up. + * The section is located in Internal SRAM memory region. The macro _NOINIT + * can be used as attribute to place data into this section. + * See the "esp_attr.h" file for more information. + */ + .noinit (NOLOAD) : + { + ALIGNED_SYMBOL(4, _noinit_start) + + SECTION_MAPPINGS(noinit) + *(.noinit .noinit.*) + + ALIGNED_SYMBOL(4, _noinit_end) + } > dram_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + ALIGNED_SYMBOL(8, _bss_start) + + SECTION_MAPPINGS(dram0_bss) + + ALIGNED_SYMBOL(8, _bss_end) + } > dram_seg + +#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 + .dram1.data : + { + _data_start_high = ABSOLUTE(.); + + mapping[dram0_data] + mutable[dram0_data] + + _data_end_high = ABSOLUTE(.); + } > dram_high_seg + + .dram1.bss (NOLOAD) : + { + ALIGNED_SYMBOL(8, _bss_start_high) + + mapping[dram0_bss] + mutable[dram0_bss] + + ALIGNED_SYMBOL(8, _bss_end_high) + } > dram_high_seg + + .dram1.heap_start (NOLOAD) : + { + ALIGNED_SYMBOL(16, _heap_start_high) + } > dram_high_seg +#endif diff --git a/components/esp_system/ld/ld.ext_ram.sections b/components/esp_system/ld/ld.ext_ram.sections new file mode 100644 index 0000000000..b214e5915b --- /dev/null +++ b/components/esp_system/ld/ld.ext_ram.sections @@ -0,0 +1,43 @@ +#include "sdkconfig.h" +#include "ld.common" + +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY || CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * Dummy section to skip flash rodata sections in case `ext_ram_seg` + * and `flash_rodata_seg` are on the same bus. + */ + .ext_ram.dummy (NOLOAD) : + { + HIDDEN(_ext_ram_on_same_bus = ORIGIN(ext_ram_seg) == ORIGIN(flash_rodata_seg)); + . = _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 + +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + /* This section holds .ext_ram.bss data, and will be put in PSRAM */ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + SECTION_MAPPINGS(extern_ram) + + ALIGNED_SYMBOL(4, _ext_ram_bss_end) + } > ext_ram_seg +#endif // CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * This section holds data that won't be initialized at startup. + * This section is located in the External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + SECTION_MAPPINGS(extram_noinit) + *(.ext_ram_noinit*) + + ALIGNED_SYMBOL(4, _ext_ram_noinit_end) + } > ext_ram_seg +#endif // CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY +#endif // CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY || CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY diff --git a/components/esp_system/ld/ld.flash.sections b/components/esp_system/ld/ld.flash.sections new file mode 100644 index 0000000000..72cab78373 --- /dev/null +++ b/components/esp_system/ld/ld.flash.sections @@ -0,0 +1,260 @@ +#include "sdkconfig.h" +#include "ld.common" + + .flash.text : + { + _stext = .; + + /** + * Mark the start of flash.text. + * This can be used by the MMU driver to maintain the virtual address. + */ + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + + SECTION_MAPPINGS(flash_text) + + *(.stub) + *(.gnu.linkonce.t.*) + *(.gnu.warning) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + + /** + * CPU will try to prefetch up to 16 bytes of instructions. + * This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction. + * Add dummy bytes to ensure this. + */ + . += _esp_flash_mmap_prefetch_pad_size; + +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION + /** + * Align the end of flash text region as per PMP granularity to allow using the + * page alignment gap created while mapping the flash region into the PSRAM memory. + */ + . = ALIGN(_esp_pmp_align_size); +#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION + + _text_end = ABSOLUTE(.); + + /** + * Mark the flash.text end. + * This can be used for MMU driver to maintain virtual address. + */ + _instruction_reserved_end = ABSOLUTE(.); + _etext = .; + + /** + * Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } > flash_text_seg + + /** + * Dummy section represents the .flash.text section but in flash_rodata_seg. + * Thus, it must have its alignment and (at least) its size. + */ + .flash_rodata_dummy (NOLOAD) : + { + _flash_rodata_dummy_start = .; + + . = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text); + + /* Add alignment of MMU page size + 0x20 bytes for the mapping header */ + . = ALIGN(_esp_mmu_page_size) + 0x20; + } > flash_rodata_seg + + .flash.appdesc : ALIGN(0x10) + { + /** + * Mark flash.rodata start. + * This can be used for MMU driver to maintain virtual address. + */ + _rodata_reserved_start = ABSOLUTE(.); + _rodata_start = ABSOLUTE(.); + + /* !DO NOT PUT ANYTHING BEFORE THIS! */ + + /* Should be the first: App version info */ + *(.rodata_desc .rodata_desc.*) + + /* Should be the second: Custom app version info */ + *(.rodata_custom_desc .rodata_custom_desc.*) + + /** + * Create an empty gap within this section. Thanks to this, the end of this + * section will match .flash.rodata's begin address. Thus, both sections + * will be merged when creating the final bin image. + */ + . = ALIGN(ALIGNOF(.flash.rodata)); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata) + + .flash.rodata : ALIGN(0x10) + { + _flash_rodata_start = ABSOLUTE(.); + + SECTION_MAPPINGS(flash_rodata) + +#if CONFIG_LIBC_PICOLIBC + *(.got .got.plt) /* TODO: GCC-439 */ +#endif + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + + . = ALIGN(ALIGNOF(.flash.init_array)); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array) + + .flash.init_array : + { + /** + * C++ constructor tables. + * + * Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt. + */ + ALIGNED_SYMBOL(4, __preinit_array_start) + ALIGNED_SYMBOL(4, __bothinit_array_start) + KEEP (*(.preinit_array)) + __preinit_array_end = ABSOLUTE(.); + ALIGNED_SYMBOL(4, __init_priority_array_start) + KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) + __init_priority_array_end = ABSOLUTE(.); + ALIGNED_SYMBOL(4, __init_array_start) + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) + __init_array_end = ABSOLUTE(.); + __bothinit_array_end = ABSOLUTE(.); + + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ + ALIGNED_SYMBOL(4, soc_reserved_memory_region_start) + KEEP (*(.reserved_memory_address)) + soc_reserved_memory_region_end = ABSOLUTE(.); + + /* System init functions registered via ESP_SYSTEM_INIT_FN */ + ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start) + KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) + _esp_system_init_fn_array_end = ABSOLUTE(.); + + _rodata_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA) + +#if EH_FRAME_LINKING_ENABLED + .eh_frame_hdr : + { + ALIGNED_SYMBOL(4, __eh_frame_hdr) + + KEEP (*(.eh_frame_hdr)) + + __eh_frame_hdr_end = ABSOLUTE(.); + + . = ALIGN(ALIGNOF(.eh_frame)); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) + + .eh_frame : + { + ALIGNED_SYMBOL(4, __eh_frame) + + KEEP (*(.eh_frame)) + + /** + * As we are not linking with crtend.o, which includes the CIE terminator + * (see __FRAME_END__ in libgcc sources), it is manually provided here. + */ + LONG(0); + + __eh_frame_end = ABSOLUTE(.); + + . = ALIGN(ALIGNOF(.flash.tdata)); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) +#if CONFIG_ESP_SYSTEM_USE_EH_FRAME + ASSERT((__eh_frame_hdr_end > __eh_frame_hdr), "eh_frame_hdr size is 0") + ASSERT((__eh_frame_end > __eh_frame), "eh_frame size is 0") +#endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME +#endif // EH_FRAME_LINKING_ENABLED + + .flash.tdata : + { + /** + * IMPORTANT: Keep tdata and tbss sections contiguous (no gaps between them). + * The TLS runtime code calculates offsets assuming these sections are + * adjacent. Gaps would cause incorrect address calculations, leading + * to accessing wrong memory. + */ + + /* Thread-local data sections */ + _thread_local_data_start = ABSOLUTE(.); + +#if CONFIG_LIBC_PICOLIBC + _picolibc_reent_stub_start = ABSOLUTE(.); + KEEP(*(.tdata.errno)) + +#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY + /* Reproduce the public fields from struct _reent */ + KEEP(*(.tdata.tls_stdin)) + KEEP(*(.tdata.tls_stdout)) + KEEP(*(.tdata.tls_stderr)) +#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY + + _picolibc_reent_stub_end = ABSOLUTE(.); +#endif // CONFIG_LIBC_PICOLIBC + + *(.tdata .tdata.* .gnu.linkonce.td.*) + + . = ALIGN(ALIGNOF(.flash.tbss)); + _thread_local_data_end = ABSOLUTE(.); + } > flash_rodata_seg + ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss) + ASSERT_PICOLIBC_REENT_STUB() + + .flash.tbss (NOLOAD) : + { + /* Thread-local BSS sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); + } > flash_rodata_seg + ASSERT(_thread_local_data_end == _thread_local_bss_start, + "tdata and tbss must be contiguous.") + + /** + * This section contains all the rodata that is not used at runtime, + * helping to avoid an increase in binary size. + */ + .flash.rodata_noload (NOLOAD) : + { +#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION + /** + * Align the end of flash rodata region as per PMP granularity to allow using the + * page alignment gap created while mapping the flash region into the PSRAM memory. + */ + . = ALIGN(_esp_pmp_align_size); +#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION + /** + * This symbol marks the end of flash.rodata. It can be utilized by the MMU + * driver to maintain the virtual address. + * NOLOAD rodata may not be included in this section. + */ + _rodata_reserved_end = .; + + SECTION_MAPPINGS(rodata_noload) + } > flash_rodata_seg + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /** + * If rodata default segment is placed in `flash_rodata_seg`, then flash's first + * rodata section must also be first in the segment. + */ + ASSERT(_flash_rodata_dummy_start == ORIGIN(flash_rodata_seg), + ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") +#endif diff --git a/components/esp_system/ld/ld.heap.sections b/components/esp_system/ld/ld.heap.sections new file mode 100644 index 0000000000..a9841c33ce --- /dev/null +++ b/components/esp_system/ld/ld.heap.sections @@ -0,0 +1,8 @@ +#include "sdkconfig.h" + + .dram0.heap_start (NOLOAD) : + { + ALIGNED_SYMBOL(16, _heap_start) + } > dram_seg + ASSERT(((_heap_start - ORIGIN(dram_seg)) <= LENGTH(dram_seg)), + "DRAM segment data does not fit.") diff --git a/components/esp_system/ld/ld.iram.sections b/components/esp_system/ld/ld.iram.sections new file mode 100644 index 0000000000..5a44f0c87f --- /dev/null +++ b/components/esp_system/ld/ld.iram.sections @@ -0,0 +1,97 @@ +#include "sdkconfig.h" +#include "ld.common" + + .iram0.text : + { + _iram_start = ABSOLUTE(.); + +#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS + /* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */ + KEEP(*(.ocd_stub.code)); + KEEP(*(.ocd_stub.tramp)); + . = ALIGN(0x800); + KEEP(*(.ocd_stub.data)); + KEEP(*(.ocd_stub.bss)); + KEEP(*(.ocd_stub.stack)); + KEEP(*(.ocd_stub.params)); + . = ALIGN(0x1000); + KEEP(*(.ocd_stub.scratchmem)); + ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000"); +#endif + + /* Vectors go to start of IRAM */ + ASSERT(ABSOLUTE(.) % ALIGN_VECTOR_TABLE == 0, "vector address must be ALIGN_VECTOR_TABLE byte aligned"); + _vector_table_start = ABSOLUTE(.); + KEEP(*(.exception_vectors_table.text)); + KEEP(*(.exception_vectors.text)); + +#if CONFIG_SECURE_ENABLE_TEE + /* esp_tee_config_t structure: used to share information between the TEE and REE + * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) + */ + ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) + ASSERT(ABSOLUTE(.) == _vector_table_start + OFFSET_TEE, "esp_tee_app_cfg must be at an offset OFFSET_TEE from the vector table start"); + *libesp_tee.a:(.esp_tee_app_cfg); +#endif + + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + SECTION_MAPPINGS(iram0_text) + } > iram_text_seg + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + /* Padding for possible CPU prefetch + alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(_esp_memprot_align_size); + + /* Align the end of code region as per PMP region granularity */ + . = ALIGN(_esp_pmp_align_size); + + /* iram_end_test section exists for use by memprot unit tests only */ + *(.iram_end_test) + + ALIGNED_SYMBOL(4, _iram_text_end) + } > iram_text_seg + + .iram0.data : + { + ALIGNED_SYMBOL(16, _iram_data_start) + + SECTION_MAPPINGS(iram0_data) + + _iram_data_end = ABSOLUTE(.); + } > iram_text_seg + + .iram0.bss (NOLOAD) : + { + ALIGNED_SYMBOL(16, _iram_bss_start) + + SECTION_MAPPINGS(iram0_bss) + + _iram_bss_end = ABSOLUTE(.); + } > iram_text_seg + +#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED + /** + * This section needs to be placed at the end of the IRAM0, which will be + * released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no + * longer in use. + */ + .iram0.bt.text : + { + ALIGNED_SYMBOL(16, _iram_bt_text_start) + + SECTION_MAPPINGS(iram0_bt_text) + } > iram_text_seg +#endif + + .iram0.end (NOLOAD) : + { + ALIGNED_SYMBOL(16, _iram_end) + } > iram_text_seg + +ASSERT(((_iram_end - ORIGIN(iram_text_seg)) <= LENGTH(iram_text_seg)), + "IRAM0 segment data does not fit.") diff --git a/components/esp_system/ld/ld.rtc.sections b/components/esp_system/ld/ld.rtc.sections new file mode 100644 index 0000000000..26edbe9daa --- /dev/null +++ b/components/esp_system/ld/ld.rtc.sections @@ -0,0 +1,170 @@ +#include "sdkconfig.h" +#include "ld.common" + +#if CONFIG_SOC_RTC_MEM_SUPPORTED + /** + * RTC fast memory holds RTC wake stub code, + * including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + /** + * Align the start of RTC code region as per PMP granularity. + * This ensures we do not overwrite the permissions for the previous + * region (ULP mem/RTC reserved) regardless of their end alignment. + */ + . = ALIGN(_esp_pmp_align_size); + + _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + HIDDEN(_rtc_code_start = .); + + *(.rtc.entry.text) + + SECTION_MAPPINGS(rtc_text) + + *rtc_wake_stub*.*(.text .text.*) + *(.rtc_text_end_test) + + /* Align the end of RTC code region as per PMP granularity */ + . = ALIGN(_esp_pmp_align_size); + + HIDDEN(_rtc_code_end = .); + + /* Padding for possible CPU prefetch + 4B alignment for PMS split lines. */ + . = ((_rtc_code_end - _rtc_code_start) == 0) ? + ALIGN(0) : _esp_memprot_prefetch_pad_size + ALIGN(4); + _rtc_text_end = ABSOLUTE(.); + } > rtc_text_seg + + + /** + * This section is located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + ALIGNED_SYMBOL(4, _rtc_force_fast_start) + + SECTION_MAPPINGS(rtc_force_fast) + *(.rtc.force_fast .rtc.force_fast.*) + + ALIGNED_SYMBOL(4, _rtc_force_fast_end) + } > rtc_force_fast_seg + + /** + * RTC data section holds RTC wake stub data/rodata, including from + * any source file named rtc_wake_stub*.c and the data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + SECTION_MAPPINGS(rtc_data) + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) + + _rtc_data_end = ABSOLUTE(.); + } > rtc_data_seg + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + + *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) + *rtc_wake_stub*.*(COMMON) + SECTION_MAPPINGS(rtc_bss) + + _rtc_bss_end = ABSOLUTE(.); + } > rtc_data_seg + + /** + * This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * User data marked with RTC_NOINIT_ATTR will be placed into this section. + * See the file "esp_attr.h" for more information. + */ + .rtc_noinit (NOLOAD) : + { + ALIGNED_SYMBOL(4, _rtc_noinit_start) + + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) + + ALIGNED_SYMBOL(4, _rtc_noinit_end) + } > rtc_data_seg + + /** + * This section is located in RTC SLOW Memory area. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + ALIGNED_SYMBOL(4, _rtc_force_slow_start) + + *(.rtc.force_slow .rtc.force_slow.*) + + ALIGNED_SYMBOL(4, _rtc_force_slow_end) + } > rtc_force_slow_seg + + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ + .rtc_reserved (NOLOAD) : + { + ALIGNED_SYMBOL(4, _rtc_reserved_start) + + /** + * IMPORTANT: Existing data must not be moved. + * Data have adhered to the beginning or ending of the segment + * (depending on chip) and code relies on it. + */ +#if CONFIG_IDF_TARGET_ESP32P4 + KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + /** + * Put new data after this line + * vvvvvvvvvvvvvvvvvvvvvvvvvvvv + */ +#else // CONFIG_IDF_TARGET_ESP32P4 + /** + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * Put new data before this line + */ + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) +#endif // CONFIG_IDF_TARGET_ESP32P4 + + _rtc_reserved_end = ABSOLUTE(.); + } > rtc_reserved_seg + + _rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg); + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; + ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), + "RTC reserved segment data does not fit.") + + /* Get size of rtc slow data based on rtc_data_seg alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_seg)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_seg)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + +#if CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND + .rtc.p4_rev3_mspi_workaround : + { + ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_start) + KEEP (*(.p4_rev3_mspi_workaround.rtc_text .p4_rev3_mspi_workaround.rtc_text.*)) + ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_end) + } > rev3_mspi_workaround_seg +#endif // CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND +#endif // CONFIG_SOC_RTC_MEM_SUPPORTED diff --git a/components/esp_system/ld/ld.tcm.sections b/components/esp_system/ld/ld.tcm.sections new file mode 100644 index 0000000000..625740b1d0 --- /dev/null +++ b/components/esp_system/ld/ld.tcm.sections @@ -0,0 +1,15 @@ +#include "ld.common" + .tcm.text : + { + /* Code marked as running out of TCM */ + _tcm_text_start = ABSOLUTE(.); + SECTION_MAPPINGS(tcm_text) + _tcm_text_end = ABSOLUTE(.); + } > tcm_idram_seg + + .tcm.data : + { + _tcm_data_start = ABSOLUTE(.); + SECTION_MAPPINGS(tcm_data) + _tcm_data_end = ABSOLUTE(.); + } > tcm_idram_seg