diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 47935d218b..44636ded4f 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -103,11 +103,7 @@ else() target_linker_script(${COMPONENT_LIB} INTERFACE "ld/${target}/memory.ld.in") # Generate sections.ld.in and pass it through linker script generator - set(sections_name "ld/${target}/sections.ld.in") - if(CONFIG_IDF_TARGET_ESP32P4 AND NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3) - set(sections_name "ld/${target}/sections.rev3.ld.in") - endif() - target_linker_script(${COMPONENT_LIB} INTERFACE "${sections_name}" + target_linker_script(${COMPONENT_LIB} INTERFACE "ld/${target}/sections.ld.in" PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld") endif() diff --git a/components/esp_system/ld/esp32/memory.ld.in b/components/esp_system/ld/esp32/memory.ld.in index a498654fee..7e79c4ccf8 100644 --- a/components/esp_system/ld/esp32/memory.ld.in +++ b/components/esp_system/ld/esp32/memory.ld.in @@ -195,9 +195,6 @@ _heap_end = ALIGN(0x40000000 - _sram1_iram_len - 3, 4); _heap_end = 0x40000000 - CONFIG_ESP32_TRACEMEM_RESERVE_DRAM; #endif - -_data_seg_org = ORIGIN(rtc_data_seg); - /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow memory segment else the data will be placed in fast memory segment */ diff --git a/components/esp_system/ld/esp32/sections.ld.in b/components/esp_system/ld/esp32/sections.ld.in index fe8db96b24..303f9e317a 100644 --- a/components/esp_system/ld/esp32/sections.ld.in +++ b/components/esp_system/ld/esp32/sections.ld.in @@ -19,7 +19,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_text_start) - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) @@ -49,7 +49,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -68,7 +68,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -83,7 +83,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -100,6 +100,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -222,8 +224,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] - + SECTION_MAPPINGS(iram0_text) } > iram0_0_seg .dram0.data : @@ -237,7 +238,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -250,6 +251,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -275,7 +277,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _ext_ram_bss_start) - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -285,11 +287,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(8, _bss_end) } > dram0_0_seg @@ -326,7 +324,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -344,16 +342,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - 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); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -387,9 +375,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .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 +#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)) @@ -401,15 +417,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + 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 @@ -424,7 +443,7 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) } > default_rodata_seg .flash.text : @@ -437,7 +456,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -478,7 +497,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_data_start) - mapping[iram0_data] + SECTION_MAPPINGS(iram0_data) _iram_data_end = ABSOLUTE(.); } > iram0_0_seg @@ -487,7 +506,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_bss_start) - mapping[iram0_bss] + SECTION_MAPPINGS(iram0_bss) _iram_bss_end = ABSOLUTE(.); ALIGNED_SYMBOL(4, _iram_end) @@ -500,7 +519,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_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)), 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 06a8b0e8a1..6a8a68b707 100644 --- a/components/esp_system/ld/esp32c2/sections.ld.in +++ b/components/esp_system/ld/esp32c2/sections.ld.in @@ -4,363 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 930a3df6a6..46242b5800 100644 --- a/components/esp_system/ld/esp32c3/memory.ld.in +++ b/components/esp_system/ld/esp32c3/memory.ld.in @@ -19,6 +19,8 @@ * 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 */ @@ -117,38 +119,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 97d2dbdae0..7e9194b284 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -4,479 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 3a51897294..9f6d6c84a2 100644 --- a/components/esp_system/ld/esp32c5/memory.ld.in +++ b/components/esp_system/ld/esp32c5/memory.ld.in @@ -132,47 +132,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 7c91f21709..ac9ad9508a 100644 --- a/components/esp_system/ld/esp32c5/sections.ld.in +++ b/components/esp_system/ld/esp32c5/sections.ld.in @@ -4,541 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_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 - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 - - /* 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 9ca127b96d..14b5779bff 100644 --- a/components/esp_system/ld/esp32c6/memory.ld.in +++ b/components/esp_system/ld/esp32c6/memory.ld.in @@ -136,41 +136,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 3a802209d5..82a54cdc52 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -4,486 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 a1af258aeb..4d4d5cd06d 100644 --- a/components/esp_system/ld/esp32c61/memory.ld.in +++ b/components/esp_system/ld/esp32c61/memory.ld.in @@ -77,34 +77,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 ee103b1197..fa08689924 100644 --- a/components/esp_system/ld/esp32c61/sections.ld.in +++ b/components/esp_system/ld/esp32c61/sections.ld.in @@ -4,400 +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"); - _vector_table_start = ABSOLUTE(.); - KEEP(*(.exception_vectors_table.text)); - KEEP(*(.exception_vectors.text)); +#include "ld.iram.sections" - ALIGNED_SYMBOL(4, _invalid_pc_placeholder) +#include "ld.dram.sections" - /* 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 +#include "ld.flash.sections" - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); +#include "ld.ext_ram.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 - - /** - * 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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_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 - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 - - /* 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 6ca9270169..7ce5824179 100644 --- a/components/esp_system/ld/esp32h2/memory.ld.in +++ b/components/esp_system/ld/esp32h2/memory.ld.in @@ -129,40 +129,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 c97e2dba30..82a54cdc52 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -4,488 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 ba0c0866fa..606610dfde 100644 --- a/components/esp_system/ld/esp32h21/memory.ld.in +++ b/components/esp_system/ld/esp32h21/memory.ld.in @@ -111,41 +111,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 66a460d8dd..41b565df28 100644 --- a/components/esp_system/ld/esp32h21/sections.ld.in +++ b/components/esp_system/ld/esp32h21/sections.ld.in @@ -6,475 +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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 8d1855351a..648b880920 100644 --- a/components/esp_system/ld/esp32h4/memory.ld.in +++ b/components/esp_system/ld/esp32h4/memory.ld.in @@ -65,37 +65,24 @@ MEMORY #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS /** - * `extern_ram_seg` and `drom_seg` / `irom_seg` share the same bus and the address region. + * `ext_ram_seg` and `drom_seg` / `irom_seg` share the same bus and the address region. * A dummy section is used to avoid overlap. See `.ext_ram.dummy` in `sections.ld.in` */ - 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 = 0x40; diff --git a/components/esp_system/ld/esp32h4/sections.ld.in b/components/esp_system/ld/esp32h4/sections.ld.in index b956d9cdee..eefd5535e3 100644 --- a/components/esp_system/ld/esp32h4/sections.ld.in +++ b/components/esp_system/ld/esp32h4/sections.ld.in @@ -6,365 +6,21 @@ /* 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.ext_ram.sections" - } > sram_seg +#include "ld.heap.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); - - 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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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)); - } > 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_noload)); - } > default_rodata_seg - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 - - /* 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/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 212270b349..78770994f7 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -159,37 +159,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 @@ -199,16 +208,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 fb59d8397b..cc4a798ba6 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -4,577 +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.spm.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.") - - .spm.text : - { - /* Code marked as running out of SPM */ - _spm_text_start = ABSOLUTE(.); - - arrays[spm_text] - mapping[spm_text] - - _spm_text_end = ABSOLUTE(.); - } > spm_idram_seg - - .spm.data : - { - _spm_data_start = ABSOLUTE(.); - - arrays[spm_data] - mapping[spm_data] - - _spm_data_end = ABSOLUTE(.); - } > spm_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. - */ - ALIGNED_SYMBOL(4, __preinit_array_start) - ALIGNED_SYMBOL(4, __bothinit_array_start) - KEEP (*(.preinit_array)) - __preinit_array_end = ABSOLUTE(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_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 - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 = .; - - 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 8dd54f4722..0000000000 --- a/components/esp_system/ld/esp32p4/sections.rev3.ld.in +++ /dev/null @@ -1,568 +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.") - - .spm.text : - { - /* Code marked as running out of SPM */ - _spm_text_start = ABSOLUTE(.); - - arrays[spm_text] - mapping[spm_text] - - _spm_text_end = ABSOLUTE(.); - } > spm_idram_seg - - .spm.data : - { - _spm_data_start = ABSOLUTE(.); - - arrays[spm_data] - mapping[spm_data] - - _spm_data_end = ABSOLUTE(.); - } > spm_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(.); - ALIGNED_SYMBOL(4, __init_array_start) - KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) - 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. - * - * Storing all TLS structures in flash increases binary size, but avoids - * runtime issues and reduces TLS allocations on the stack. - */ - /* 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.*) - _thread_local_data_end = ABSOLUTE(.); - - /* tbss sections */ - _thread_local_bss_start = ABSOLUTE(.); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - _thread_local_bss_end = ABSOLUTE(.); - - . = ALIGN(ALIGNOF(.flash.rodata_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 - } > rodata_seg_low - ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload) - ASSERT(_thread_local_data_end == _thread_local_bss_start, - "tdata and tbss must be contiguous.") - ASSERT_PICOLIBC_REENT_STUB() - - /** - * 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 = .; - - 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/esp32s2/memory.ld.in b/components/esp_system/ld/esp32s2/memory.ld.in index ca7c4d6d93..94869fa209 100644 --- a/components/esp_system/ld/esp32s2/memory.ld.in +++ b/components/esp_system/ld/esp32s2/memory.ld.in @@ -165,8 +165,6 @@ _heap_start = _heap_low_start; _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow memory segment else the data will be placed in fast memory segment */ diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index ec5c02cb10..a855309552 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -28,7 +28,7 @@ SECTIONS HIDDEN(_rtc_code_start = .); - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) @@ -63,7 +63,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -82,7 +82,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -97,7 +97,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -114,6 +114,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -211,7 +213,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] + SECTION_MAPPINGS(iram0_text) /* Padding for possible CPU prefetch + alignment for PMS split lines */ . += _esp_memprot_prefetch_pad_size; @@ -239,7 +241,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -265,7 +267,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _ext_ram_bss_start) - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -280,6 +282,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -291,11 +294,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(16, _bss_end) } > dram0_0_seg @@ -329,7 +328,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -347,16 +346,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - 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); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -390,9 +379,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .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 +#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)) @@ -404,15 +421,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + 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 @@ -427,7 +447,8 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) + } > default_rodata_seg .flash.text : @@ -440,7 +461,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -484,7 +505,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32s3/memory.ld.in b/components/esp_system/ld/esp32s3/memory.ld.in index 87103fff8d..f847815df5 100644 --- a/components/esp_system/ld/esp32s3/memory.ld.in +++ b/components/esp_system/ld/esp32s3/memory.ld.in @@ -185,9 +185,6 @@ _heap_start = _heap_low_start; /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - - /* RTC fast memory shares the same range for both data and instructions */ REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 4376cc393d..da3e457f04 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -24,7 +24,7 @@ SECTIONS *(.rtc.entry.literal .rtc.entry.text) - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) *(.rtc_text_end_test) @@ -47,7 +47,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -66,7 +66,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -81,7 +81,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -98,6 +98,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -195,8 +197,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] - + SECTION_MAPPINGS(iram0_text) } > iram0_0_seg /** @@ -205,8 +206,7 @@ SECTIONS */ .dram0.dummy (NOLOAD): { - /* MAX() uses unsigned long arithmetic. Add offset to prevent underflow when _iram_end < _diram_i_start */ - . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start + (_diram_i_start - ORIGIN(iram0_0_seg)), (_diram_i_start - ORIGIN(iram0_0_seg))) - (_diram_i_start - ORIGIN(iram0_0_seg)); + . = ORIGIN(dram0_0_seg) + ((_iram_end > _diram_i_start) ? (_iram_end - _diram_i_start) : 0); } > dram0_0_seg .dram0.data : @@ -220,7 +220,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -245,11 +245,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(16, _bss_end) } > dram0_0_seg @@ -267,7 +263,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -341,7 +337,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -359,16 +355,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - 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); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -402,9 +388,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .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 +#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)) @@ -416,15 +430,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + 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 @@ -439,7 +456,7 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) } > default_rodata_seg /** @@ -459,7 +476,7 @@ SECTIONS { _ext_ram_bss_start = ABSOLUTE(.); - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -474,6 +491,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -497,7 +515,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_data_start) - mapping[iram0_data] + SECTION_MAPPINGS(iram0_data) ALIGNED_SYMBOL(4, _iram_data_end) } > iram0_0_seg @@ -506,7 +524,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_bss_start) - mapping[iram0_bss] + SECTION_MAPPINGS(iram0_bss) _iram_bss_end = ABSOLUTE(.); ALIGNED_SYMBOL(4, _iram_end) @@ -519,7 +537,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_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)), diff --git a/components/esp_system/ld/ld.cmake b/components/esp_system/ld/ld.cmake deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index f2e2570ef7..51e2d3f2eb 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -105,7 +105,12 @@ ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \ #endif #if EH_FRAME_LINKING_ENABLED +#if CONFIG_IDF_TARGET_ARCH_RISCV #define SECTION_AFTER_FLASH_RODATA .eh_frame_hdr +#endif +#if CONFIG_IDF_TARGET_ARCH_XTENSA +#define SECTION_AFTER_FLASH_RODATA .eh_frame +#endif #else #define SECTION_AFTER_FLASH_RODATA .flash.tdata #endif @@ -120,3 +125,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 73% rename from components/esp_system/ld/elf_misc.ld.in rename to components/esp_system/ld/ld.debug.sections index be87bf97b7..2f94fddfa8 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. @@ -10,20 +11,23 @@ . = 0; LONG(0); _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) } @@ -33,18 +37,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) } @@ -54,30 +63,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. @@ -88,18 +81,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..15e4d507ed --- /dev/null +++ b/components/esp_system/ld/ld.flash.sections @@ -0,0 +1,258 @@ +#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_array_start) + KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))) + 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/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 6ccd739fae..84f751c663 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -444,30 +444,36 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u LOW ADDRESS |---------------------------| Linker Symbols | Section | -------------- - | .flash.rodata | - 0x0|---------------------------| <- _flash_rodata_start - ^ | Other Data | - | |---------------------------| <- _thread_local_start - | | .tbss | ^ - V | | | - 0xNNN | int example; | | tls_area_size - | | | - | .tdata | V - |---------------------------| <- _thread_local_end + | .flash.tdata | + 0x0|---------------------------| <- _thread_local_data_start ^ + | .flash.tdata | | + | int var_1 = 1; | | + | | <- _thread_local_data_end | + | | <- _thread_local_bss_start | tls_area_size + | | | + | .flash.tbss (NOLOAD) | | + | int var_2; | | + |---------------------------| <- _thread_local_bss_end V | Other data | | ... | |---------------------------| HIGH ADDRESS */ // Calculate the TLS area's size (rounded up to multiple of 16 bytes). - extern int _thread_local_start, _thread_local_end, _flash_rodata_start, _flash_rodata_align; - const uint32_t tls_area_size = ALIGNUP(16, (uint32_t)&_thread_local_end - (uint32_t)&_thread_local_start); + extern int _tls_section_alignment; + extern char _thread_local_data_start, _thread_local_data_end; + extern char _thread_local_bss_start, _thread_local_bss_end; + const uint32_t tls_data_size = (uint32_t)&_thread_local_data_end - (uint32_t)&_thread_local_data_start; + const uint32_t tls_bss_size = (uint32_t)&_thread_local_bss_end - (uint32_t)&_thread_local_bss_start; + const uint32_t tls_area_size = ALIGNUP(16, tls_data_size + tls_bss_size); // TODO: check that TLS area fits the stack // Allocate space for the TLS area on the stack. The area must be allocated at a 16-byte aligned address uxStackPointer = STACKPTR_ALIGN_DOWN(16, uxStackPointer - (UBaseType_t)tls_area_size); - // Initialize the TLS area with the initialization values of each TLS variable - memcpy((void *)uxStackPointer, &_thread_local_start, tls_area_size); + // Initialize the TLS data with the initialization values of each TLS variable + memcpy((void *)uxStackPointer, &_thread_local_data_start, tls_data_size); + // Initialize the TLS bss with zeroes + memset((void *)(uxStackPointer + tls_data_size), 0, tls_bss_size); /* Calculate the THREADPTR register's initialization value based on the link-time offset and the TLS area allocated on @@ -494,10 +500,10 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u - "offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)" - TCB_SIZE is hardcoded to 8 */ - const uint32_t tls_section_align = (uint32_t)&_flash_rodata_align; // ALIGN value of .flash.rodata section + const uint32_t tls_section_align = (uint32_t)&_tls_section_alignment; // ALIGN value of .flash.tdata section #define TCB_SIZE 8 const uint32_t base = ALIGNUP(tls_section_align, TCB_SIZE); - *ret_threadptr_reg_init = (uint32_t)uxStackPointer - ((uint32_t)&_thread_local_start - (uint32_t)&_flash_rodata_start) - base; + *ret_threadptr_reg_init = (uint32_t)uxStackPointer - base; return uxStackPointer; } diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 36337aa11a..655fb4aa35 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -8,7 +8,7 @@ * * SPDX-License-Identifier: MIT * - * SPDX-FileContributor: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2023-2026 Espressif Systems (Shanghai) CO LTD * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -224,30 +224,36 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u LOW ADDRESS |---------------------------| Linker Symbols | Section | -------------- - | .flash.rodata | - 0x0|---------------------------| <- _flash_rodata_start - ^ | Other Data | - | |---------------------------| <- _thread_local_start - | | .tbss | ^ - V | | | - 0xNNN | int example; | | tls_area_size - | | | - | .tdata | V - |---------------------------| <- _thread_local_end + | .flash.tdata | + 0x0|---------------------------| <- _thread_local_data_start ^ + | .flash.tdata | | + | int var_1 = 1; | | + | | <- _thread_local_data_end | + | | <- _thread_local_bss_start | tls_area_size + | | | + | .flash.tbss (NOLOAD) | | + | int var_2; | | + |---------------------------| <- _thread_local_bss_end V | Other data | | ... | |---------------------------| HIGH ADDRESS */ // Calculate the TLS area's size (rounded up to multiple of 16 bytes). - extern int _thread_local_start, _thread_local_end, _flash_rodata_start, _flash_rodata_align; - const uint32_t tls_area_size = ALIGNUP(16, (uint32_t)&_thread_local_end - (uint32_t)&_thread_local_start); + extern int _tls_section_alignment; + extern char _thread_local_data_start, _thread_local_data_end; + extern char _thread_local_bss_start, _thread_local_bss_end; + const uint32_t tls_data_size = (uint32_t)&_thread_local_data_end - (uint32_t)&_thread_local_data_start; + const uint32_t tls_bss_size = (uint32_t)&_thread_local_bss_end - (uint32_t)&_thread_local_bss_start; + const uint32_t tls_area_size = ALIGNUP(16, tls_data_size + tls_bss_size); // TODO: check that TLS area fits the stack // Allocate space for the TLS area on the stack. The area must be allocated at a 16-byte aligned address uxStackPointer = STACKPTR_ALIGN_DOWN(16, uxStackPointer - (UBaseType_t)tls_area_size); - // Initialize the TLS area with the initialization values of each TLS variable - memcpy((void *)uxStackPointer, &_thread_local_start, tls_area_size); + // Initialize the TLS data with the initialization values of each TLS variable + memcpy((void *)uxStackPointer, &_thread_local_data_start, tls_data_size); + // Initialize the TLS bss with zeroes + memset((void *)(uxStackPointer + tls_data_size), 0, tls_bss_size); /* Calculate the THREADPTR register's initialization value based on the link-time offset and the TLS area allocated on @@ -274,10 +280,10 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u - "offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)" - TCB_SIZE is hardcoded to 8 */ - const uint32_t tls_section_align = (uint32_t)&_flash_rodata_align; // ALIGN value of .flash.rodata section + const uint32_t tls_section_align = (uint32_t)&_tls_section_alignment; // ALIGN value of .flash.tdata section #define TCB_SIZE 8 const uint32_t base = ALIGNUP(tls_section_align, TCB_SIZE); - *ret_threadptr_reg_init = (uint32_t)uxStackPointer - ((uint32_t)&_thread_local_start - (uint32_t)&_flash_rodata_start) - base; + *ret_threadptr_reg_init = (uint32_t)uxStackPointer - base; return uxStackPointer; }