Merge branch 'feature/refactor_linker_scripts_v5.5' into 'release/v5.5'

feat(esp_system): refactor linker scripts to reduce duplicated code (v5.5)

See merge request espressif/esp-idf!45729
This commit is contained in:
Alexey Gerenkov
2026-03-30 21:19:53 +08:00
39 changed files with 1178 additions and 5040 deletions
@@ -141,9 +141,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 */
+58 -38
View File
@@ -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.
*
@@ -381,9 +369,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))
@@ -395,15 +411,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
@@ -418,7 +437,7 @@ SECTIONS
*/
_rodata_reserved_end = ABSOLUTE(.);
mapping[rodata_noload]
SECTION_MAPPINGS(rodata_noload)
} > default_rodata_seg
.flash.text :
@@ -431,7 +450,7 @@ SECTIONS
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
SECTION_MAPPINGS(flash_text)
*(.stub)
*(.gnu.warning)
@@ -472,7 +491,7 @@ SECTIONS
{
ALIGNED_SYMBOL(4, _iram_data_start)
mapping[iram0_data]
SECTION_MAPPINGS(iram0_data)
_iram_data_end = ABSOLUTE(.);
} > iram0_0_seg
@@ -481,7 +500,7 @@ SECTIONS
{
ALIGNED_SYMBOL(4, _iram_bss_start)
mapping[iram0_bss]
SECTION_MAPPINGS(iram0_bss)
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, _iram_end)
@@ -494,7 +513,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)),
+13 -21
View File
@@ -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;
+6 -355
View File
@@ -4,368 +4,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
#include "ld.iram.sections"
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
#include "ld.dram.sections"
mapping[iram0_text]
#include "ld.flash.sections"
} > iram0_0_seg
#include "ld.heap.sections"
/**
* This section is required to skip .iram0.text area because iram0_0_seg and
* dram0_0_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
} > dram0_0_seg
/**
* This section MUST be placed at the beginning of the DRAM0, which will be
* released along with iram0_bt.text when Bluetooth is no longer in use.
*/
.dram0.bt.data :
{
_data_start = ABSOLUTE(.);
mapping[dram0_bt_data]
} > dram0_0_seg
.dram0.bt.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_bt_start)
mapping[dram0_bt_bss]
_bss_bt_end = ABSOLUTE(.);
} > dram0_0_seg
.dram0.data :
{
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > dram0_0_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > dram0_0_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > dram0_0_seg
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
ALIGNED_SYMBOL(4, _iram_text_end)
} > iram0_0_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > iram0_0_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
} > iram0_0_seg
/**
* This section needs to be placed at the end of the IRAM0, which will be
* released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no
* longer in use.
*/
.iram0.bt.text :
{
ALIGNED_SYMBOL(16, _iram_bt_text_start)
mapping[iram0_bt_text]
ALIGNED_SYMBOL(16, _iram_end)
} > iram0_0_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > dram0_0_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
+14 -25
View File
@@ -16,9 +16,11 @@
#include "ld.common"
/**
* physical memory is mapped twice to the vritual address (IRAM and DRAM).
* physical memory is mapped twice to the virtual address (IRAM and DRAM).
* `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory
*/
_iram_dram_shared = 1;
#define SRAM_IRAM_START 0x4037C000
#define SRAM_DRAM_START 0x3FC7C000
#define ICACHE_SIZE 0x4000 /* ICache size is fixed to 16KB on ESP32-C3 */
@@ -87,38 +89,25 @@ MEMORY
/* Heap ends at top of dram0_0_seg */
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* As C3 only has RTC fast memory, this is not configurable like on other targets
*/
REGION_ALIAS("rtc_text_seg", rtc_iram_seg);
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_force_fast_seg", rtc_iram_seg);
REGION_ALIAS("rtc_force_slow_seg", rtc_iram_seg);
REGION_ALIAS("iram_text_seg", iram0_0_seg);
REGION_ALIAS("dram_seg", dram0_0_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", iram0_2_seg);
REGION_ALIAS("flash_text_seg", iram0_2_seg);
REGION_ALIAS("flash_rodata_seg", drom0_0_seg);
#else
REGION_ALIAS("default_code_seg", iram0_0_seg);
REGION_ALIAS("flash_text_seg", iram0_0_seg);
REGION_ALIAS("flash_rodata_seg", dram0_0_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom0_0_seg);
#else
REGION_ALIAS("default_rodata_seg", dram0_0_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
+7 -470
View File
@@ -4,484 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
ALIGNED_SYMBOL(4, _rtc_fast_start)
#include "ld.rtc.sections"
HIDDEN(_rtc_code_start = .);
#include "ld.iram.sections"
mapping[rtc_text]
#include "ld.dram.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.flash.sections"
HIDDEN(_rtc_code_end = .);
#include "ld.heap.sections"
/* Padding for possible CPU prefetch + 4B alignment for PMS split lines. */
. = ((_rtc_code_end - _rtc_code_start) == 0) ?
ALIGN(0) : _esp_memprot_prefetch_pad_size + ALIGN(4);
_rtc_text_end = ABSOLUTE(.);
} > rtc_iram_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > rtc_data_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > rtc_data_location
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > rtc_data_location
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > rtc_data_location
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > rtc_slow_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the end of the segment and code is relied
* on it.
* >> put new data here <<
*/
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > iram0_0_seg
/**
* This section is required to skip .iram0.text area because iram0_0_seg and
* dram0_0_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
} > dram0_0_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > dram0_0_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > dram0_0_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > dram0_0_seg
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Padding for possible CPU prefetch + alignment for PMS split lines */
. += _esp_memprot_prefetch_pad_size;
. = ALIGN(_esp_memprot_align_size);
/* iram_end_test section exists for use by memprot unit tests only */
*(.iram_end_test)
_iram_text_end = ABSOLUTE(.);
} > iram0_0_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > iram0_0_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > iram0_0_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > dram0_0_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
+15 -28
View File
@@ -96,47 +96,34 @@ MEMORY
lp_reserved_seg(RW) : org = 0x50000000 + 0x4000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM
/* PSRAM seg */
extern_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
ext_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
}
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* C5 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section
* Thus, the following region segments are not configurable like on other targets
*/
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_text_seg", lp_ram_seg);
REGION_ALIAS("rtc_data_seg", lp_ram_seg );
REGION_ALIAS("rtc_slow_seg", lp_ram_seg );
REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
OFFSET_TEE = 0x2b0;
+8 -531
View File
@@ -4,546 +4,23 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for the previous
* region (ULP mem) regardless of its end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
#include "ld.rtc.sections"
*(.rtc.entry.text)
#include "ld.iram.sections"
mapping[rtc_text]
#include "ld.dram.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.flash.sections"
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.ext_ram.sections"
_rtc_text_end = ABSOLUTE(.);
} > lp_ram_seg
#include "ld.heap.sections"
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the end of the segment and code is relied
* on it.
* >> put new data here <<
*/
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_vector_table_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
/* esp_tee_config_t structure: used to share information between the TEE and REE
* (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.)
* This symbol is expected by the TEE at an offset of 0x2b0 from the vector table start.
*/
#if CONFIG_SECURE_ENABLE_TEE
ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg)
ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2b0, "esp_tee_app_cfg must be at an offset 0x2b0 from the vector table start");
*libesp_tee.a:(.esp_tee_app_cfg);
#endif
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
/**
* This section is required to skip .iram0.text area because sram_seg and
* sram_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(sram_seg) + _iram_end - _iram_start;
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash text region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash rodata region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
/* External RAM */
/**
* This section is required to skip flash sections, because `extern_ram_seg`
* and `drom_seg` / `irom_seg` are on the same bus when app build use flash sections
*/
.ext_ram.dummy (NOLOAD):
{
. = ORIGIN(extern_ram_seg);
. = . + (_rodata_reserved_end - _flash_rodata_dummy_start);
. = ALIGN (_esp_mmu_page_size);
} > extern_ram_seg
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
/* This section holds .ext_ram.bss data, and will be put in PSRAM */
.ext_ram.bss (NOLOAD) :
{
_ext_ram_bss_start = ABSOLUTE(.);
mapping[extern_ram]
ALIGNED_SYMBOL(4, _ext_ram_bss_end)
} > extern_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
/**
* This section holds data that won't be initialised when startup.
* This section locates in External RAM region.
*/
.ext_ram_noinit (NOLOAD) :
{
_ext_ram_noinit_start = ABSOLUTE(.);
*(.ext_ram_noinit*)
ALIGNED_SYMBOL(4, _ext_ram_noinit_end)
} > extern_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"DRAM segment data does not fit.")
+14 -27
View File
@@ -101,41 +101,28 @@ MEMORY
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* C6 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section
* Thus, the following region segments are not configurable like on other targets
*/
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_text_seg", lp_ram_seg);
REGION_ALIAS("rtc_data_seg", lp_ram_seg);
REGION_ALIAS("rtc_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
OFFSET_TEE = 0x2e0;
+7 -477
View File
@@ -4,491 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for the previous
* region (ULP mem) regardless of its end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
#include "ld.rtc.sections"
*(.rtc.entry.text)
#include "ld.iram.sections"
mapping[rtc_text]
#include "ld.dram.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.flash.sections"
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.heap.sections"
_rtc_text_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the end of the segment and code is relied
* on it.
* >> put new data here <<
*/
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.iram0.text :
{
_iram_start = ABSOLUTE(.);
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
/* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */
KEEP(*(.ocd_stub.code));
KEEP(*(.ocd_stub.tramp));
. = ALIGN(0x800);
KEEP(*(.ocd_stub.data));
KEEP(*(.ocd_stub.bss));
KEEP(*(.ocd_stub.stack));
KEEP(*(.ocd_stub.params));
. = ALIGN(0x1000);
KEEP(*(.ocd_stub.scratchmem));
ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000");
#endif
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_vector_table_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
/* esp_tee_config_t structure: used to share information between the TEE and REE
* (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.)
* This symbol is expected by the TEE at an offset of 0x300 from the vector table start.
*/
#if CONFIG_SECURE_ENABLE_TEE
ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg)
ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start");
*libesp_tee.a:(.esp_tee_app_cfg);
#endif
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
+10 -22
View File
@@ -59,34 +59,22 @@ MEMORY
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* PSRAM seg */
extern_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
ext_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
}
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
OFFSET_TEE = 0x2b0;
@@ -4,391 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
#include "ld.iram.sections"
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
#include "ld.dram.sections"
mapping[iram0_text]
#include "ld.flash.sections"
} > sram_seg
#include "ld.ext_ram.sections"
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.heap.sections"
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
/**
* This section is required to skip .iram0.text area because sram_seg and
* sram_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(sram_seg) + _iram_end - _iram_start;
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash text region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash rodata region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
/* External RAM */
/**
* This section is required to skip flash sections, because `extern_ram_seg`
* and `drom_seg` / `irom_seg` are on the same bus when app build use flash sections
*/
.ext_ram.dummy (NOLOAD):
{
. = ORIGIN(extern_ram_seg);
. = . + (_rodata_reserved_end - _flash_rodata_dummy_start);
. = ALIGN (_esp_mmu_page_size);
} > extern_ram_seg
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
/* This section holds .ext_ram.bss data, and will be put in PSRAM */
.ext_ram.bss (NOLOAD) :
{
_ext_ram_bss_start = ABSOLUTE(.);
mapping[extern_ram]
ALIGNED_SYMBOL(4, _ext_ram_bss_end)
} > extern_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
/**
* This section holds data that won't be initialized when startup.
* This section locates in External RAM region.
*/
.ext_ram_noinit (NOLOAD) :
{
_ext_ram_noinit_start = ABSOLUTE(.);
*(.ext_ram_noinit*)
ALIGNED_SYMBOL(4, _ext_ram_noinit_end)
} > extern_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"DRAM segment data does not fit.")
+14 -27
View File
@@ -97,40 +97,27 @@ MEMORY
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* As H2 only has RTC fast memory, this is not configurable like on other targets
*/
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_text_seg", lp_ram_seg);
REGION_ALIAS("rtc_data_seg", lp_ram_seg);
REGION_ALIAS("rtc_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
OFFSET_TEE = 0x2e0;
+7 -479
View File
@@ -4,493 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for any potential previous
* region regardless of its end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
#include "ld.rtc.sections"
*(.rtc.entry.text)
#include "ld.iram.sections"
mapping[rtc_text]
#include "ld.dram.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.flash.sections"
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.heap.sections"
_rtc_text_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the end of the segment and code is relied
* on it.
* >> put new data here <<
*/
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.iram0.text :
{
_iram_start = ABSOLUTE(.);
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
/* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */
KEEP(*(.ocd_stub.code));
KEEP(*(.ocd_stub.tramp));
. = ALIGN(0x800);
KEEP(*(.ocd_stub.data));
KEEP(*(.ocd_stub.bss));
KEEP(*(.ocd_stub.stack));
KEEP(*(.ocd_stub.params));
. = ALIGN(0x1000);
KEEP(*(.ocd_stub.scratchmem));
ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000");
#endif
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_vector_table_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
/* esp_tee_config_t structure: used to share information between the TEE and REE
* (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.)
* This symbol is expected by the TEE at an offset of 0x300 from the vector table start.
*/
#if CONFIG_SECURE_ENABLE_TEE
ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg)
ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start");
*libesp_tee.a:(.esp_tee_app_cfg);
#endif
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
+13 -27
View File
@@ -80,41 +80,27 @@ MEMORY
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* H21 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section
* Thus, the following region segments are not configurable like on other targets
*/
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_text_seg", lp_ram_seg);
REGION_ALIAS("rtc_data_seg", lp_ram_seg);
REGION_ALIAS("rtc_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x100;
@@ -6,480 +6,21 @@
/* TODO: [ESP32H21] IDF-11900, IDF-11908 */
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for any potential previous
* region regardless of its end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
#include "ld.rtc.sections"
*(.rtc.entry.text)
#include "ld.iram.sections"
mapping[rtc_text]
#include "ld.dram.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.flash.sections"
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.heap.sections"
_rtc_text_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the end of the segment and code is relied
* on it.
* >> put new data here <<
*/
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.iram0.text :
{
_iram_start = ABSOLUTE(.);
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
/* Do not move this block! OpenOCD expects this to be at the beginning of IRAM. */
KEEP(*(.ocd_stub.code));
KEEP(*(.ocd_stub.tramp));
. = ALIGN(0x800);
KEEP(*(.ocd_stub.data));
KEEP(*(.ocd_stub.bss));
KEEP(*(.ocd_stub.stack));
KEEP(*(.ocd_stub.params));
. = ALIGN(0x1000);
KEEP(*(.ocd_stub.scratchmem));
ASSERT(ABSOLUTE(.) == _iram_start + 0x2000, "openocd stub memory must be ended at _iram_start + 0x2000");
#endif
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
+8 -21
View File
@@ -69,28 +69,15 @@ MEMORY
/* Heap ends at top of sram_seg */
_heap_end = 0x40000000;
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", irom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_code_seg", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom_seg);
#else
REGION_ALIAS("default_rodata_seg", sram_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x40;
+6 -318
View File
@@ -6,331 +6,19 @@
/* TODO: [ESP32H4] IDF-12305 inherited from verification branch, need check */
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
#include "ld.iram.sections"
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
#include "ld.dram.sections"
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
#include "ld.flash.sections"
mapping[iram0_text]
#include "ld.heap.sections"
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(8, _bss_end)
} > sram_seg
ASSERT(((_bss_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > default_code_seg
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > default_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > default_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
mapping[rodata_noload]
} > default_rodata_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)),
"DRAM segment data does not fit.")
+27 -30
View File
@@ -120,37 +120,46 @@ MEMORY
/* Heap ends at top of dram0_0_seg */
_heap_end = 0x50000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/**
* The lines below define location alias for .rtc.data section
* P4 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section
* Thus, the following region segments are not configurable like on other targets
*/
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
REGION_ALIAS("rtc_text_seg", lp_ram_seg);
REGION_ALIAS("rtc_data_seg", lp_ram_seg);
REGION_ALIAS("rtc_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_fast_seg", lp_ram_seg);
REGION_ALIAS("rtc_force_slow_seg", lp_ram_seg);
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("text_seg_low", irom_seg);
#else
#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3
REGION_ALIAS("text_seg_low", sram_low);
REGION_ALIAS("iram_text_seg", sram_low);
REGION_ALIAS("dram_seg", sram_low);
REGION_ALIAS("dram_high_seg", sram_high);
ASSERT(((_heap_start_high - ORIGIN(dram_high_seg)) <= LENGTH(dram_high_seg)),
"DRAM_HIGH segment data does not fit.")
/* define X_low symbols */
_data_start_low = _data_start;
_data_end_low = _data_end;
_bss_start_low = _bss_start;
_bss_end_low = _bss_end;
_heap_start_low = _heap_start;
#else
REGION_ALIAS("text_seg_low", sram_seg);
#endif //CONFIG_ESP32P4_SELECTS_REV_LESS_V3
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("iram_text_seg", sram_seg);
REGION_ALIAS("dram_seg", sram_seg);
#endif
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("rodata_seg_low", drom_seg);
REGION_ALIAS("flash_text_seg", irom_seg);
REGION_ALIAS("flash_rodata_seg", drom_seg);
#else
#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3
REGION_ALIAS("rodata_seg_low", sram_low);
REGION_ALIAS("rodata_seg_high", sram_high);
REGION_ALIAS("flash_text_seg", sram_low);
REGION_ALIAS("flash_rodata_seg", sram_low);
#else
REGION_ALIAS("rodata_seg_low", sram_seg);
REGION_ALIAS("flash_text_seg", sram_seg);
REGION_ALIAS("flash_rodata_seg", sram_seg);
#endif //CONFIG_ESP32P4_SELECTS_REV_LESS_V3
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
@@ -160,16 +169,4 @@ REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
REGION_ALIAS("ext_ram_seg", extern_ram_seg);
#endif //#if CONFIG_SPIRAM_XIP_FROM_PSRAM
/**
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
* also be first in the segment.
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
ASSERT(_flash_rodata_dummy_start == ORIGIN(rodata_seg_low),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
#endif
ALIGN_VECTOR_TABLE = 0x40;
+9 -566
View File
@@ -4,582 +4,25 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for the previous
* region (ULP mem/RTC reserved) regardless of their end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
#include "ld.rtc.sections"
arrays[rtc_text]
mapping[rtc_text]
#include "ld.tcm.sections"
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
#include "ld.iram.sections"
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
#include "ld.dram.sections"
ALIGNED_SYMBOL(4, _rtc_text_end)
} > lp_ram_seg
#include "ld.flash.sections"
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
#include "ld.ext_ram.sections"
arrays[rtc_force_fast]
mapping[rtc_force_fast]
#include "ld.heap.sections"
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
arrays[rtc_data]
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
arrays[rtc_bss]
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the beginning of the segment and code is relied
* on it.
* >> put new data here <<
*/
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
_rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg);
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.tcm.text :
{
/* Code marked as running out of TCM */
_tcm_text_start = ABSOLUTE(.);
arrays[tcm_text]
mapping[tcm_text]
_tcm_text_end = ABSOLUTE(.);
} > tcm_idram_seg
.tcm.data :
{
_tcm_data_start = ABSOLUTE(.);
arrays[tcm_data]
mapping[tcm_data]
_tcm_data_end = ABSOLUTE(.);
} > tcm_idram_seg
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
arrays[iram0_text]
mapping[iram0_text]
} > sram_low
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_low
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
arrays[iram0_data]
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_low
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
arrays[iram0_bss]
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_low
.dram0.data :
{
_data_start_low = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
arrays[dram0_data]
mapping[dram0_data]
_data_end_low = ABSOLUTE(.);
} > sram_low
.dram1.data :
{
_data_start_high = ABSOLUTE(.);
mapping[dram0_data]
_data_end_high = ABSOLUTE(.);
} > sram_high
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_low
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
arrays[flash_text]
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash text region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > text_seg_low
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > rodata_seg_low
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
arrays[flash_rodata]
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
. = ALIGN(ALIGNOF(.flash.init_array));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array)
.flash.init_array :
{
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*
* RISC-V gcc is configured with --enable-initfini-array so it emits
* .init_array section instead. But the init_priority sections will be
* sorted for iteration in ascending order during startup.
* The rest of the init_array sections is sorted for iteration in descending
* order during startup, however. Hence a different section is generated for
* the init_priority functions which is iterated in ascending order during
* startup. The corresponding code can be found in startup.c.
*/
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > rodata_seg_low
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash rodata region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
arrays[rodata_noload]
mapping[rodata_noload]
} > rodata_seg_low
#if CONFIG_SPIRAM_XIP_FROM_PSRAM
/**
* This section is required to skip flash sections, because `extern_ram_seg`
* and `drom_seg` / `irom_seg` are on the same bus when xip on psram
*/
.ext_ram.dummy (NOLOAD):
{
. = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start);
. = ALIGN (_esp_mmu_page_size);
} > ext_ram_seg
#endif //CONFIG_SPIRAM_XIP_FROM_PSRAM
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
/* This section holds .ext_ram.bss data, and will be put in PSRAM */
.ext_ram.bss (NOLOAD) :
{
_ext_ram_bss_start = ABSOLUTE(.);
arrays[extern_ram]
mapping[extern_ram]
ALIGNED_SYMBOL(4, _ext_ram_bss_end)
} > ext_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
/**
* This section holds data that won't be initialised when startup.
* This section locates in External RAM region.
*/
.ext_ram_noinit (NOLOAD) :
{
_ext_ram_noinit_start = ABSOLUTE(.);
*(.ext_ram_noinit*)
ALIGNED_SYMBOL(4, _ext_ram_noinit_end)
} > ext_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(4, _bss_start_low)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
arrays[dram0_bss]
mapping[dram0_bss]
ALIGNED_SYMBOL(4, _bss_end_low)
} > sram_low
.dram1.bss (NOLOAD) :
{
ALIGNED_SYMBOL(4, _bss_start_high)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(4, _bss_end_high)
} > sram_high
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start_low (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start_low)
} > sram_low
/* Marks the end of data, bss and possibly rodata */
.dram1.heap_start_high (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start_high)
} > sram_high
#include "elf_misc.ld.in"
#include "ld.debug.sections"
#include "ld.discard.sections"
}
@@ -1,572 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "ld.common"
/* Default entry point */
ENTRY(call_start_cpu0);
SECTIONS
{
/**
* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
/* Align the start of RTC code region as per PMP granularity
* this ensures we do not overwrite the permissions for the previous
* region (ULP mem/RTC reserved) regardless of their end alignment
*/
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
arrays[rtc_text]
mapping[rtc_text]
*rtc_wake_stub*.*(.text .text.*)
*(.rtc_text_end_test)
/* Align the end of RTC code region as per PMP granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _rtc_text_end)
} > lp_ram_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
ALIGNED_SYMBOL(4, _rtc_force_fast_start)
arrays[rtc_force_fast]
mapping[rtc_force_fast]
*(.rtc.force_fast .rtc.force_fast.*)
ALIGNED_SYMBOL(4, _rtc_force_fast_end)
} > lp_ram_seg
/**
* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
arrays[rtc_data]
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
_rtc_data_end = ABSOLUTE(.);
} > lp_ram_seg
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
*rtc_wake_stub*.*(COMMON)
arrays[rtc_bss]
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > lp_ram_seg
/**
* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_noinit_start)
*(.rtc_noinit .rtc_noinit.*)
ALIGNED_SYMBOL(4, _rtc_noinit_end)
} > lp_ram_seg
/**
* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
ALIGNED_SYMBOL(4, _rtc_force_slow_start)
*(.rtc.force_slow .rtc.force_slow.*)
ALIGNED_SYMBOL(4, _rtc_force_slow_end)
} > lp_ram_seg
#if CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND
.rtc.p4_rev3_mspi_workaround :
{
ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_start)
KEEP (*(.p4_rev3_mspi_workaround.rtc_text .p4_rev3_mspi_workaround.rtc_text.*))
ALIGNED_SYMBOL(4, _rtc_p4_rev3_mspi_workaround_end)
} > rev3_mspi_workaround_seg
#endif
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep
* sleep.
*/
.rtc_reserved (NOLOAD):
{
ALIGNED_SYMBOL(4, _rtc_reserved_start)
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
/**
* New data can only be added here to ensure existing data are not moved.
* Because data have adhered to the beginning of the segment and code is relied
* on it.
* >> put new data here <<
*/
_rtc_reserved_end = ABSOLUTE(.);
} > rtc_reserved_seg
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
_rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg);
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
"RTC reserved segment data does not fit.")
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
.tcm.text :
{
/* Code marked as running out of TCM */
_tcm_text_start = ABSOLUTE(.);
arrays[tcm_text]
mapping[tcm_text]
_tcm_text_end = ABSOLUTE(.);
} > tcm_idram_seg
.tcm.data :
{
_tcm_data_start = ABSOLUTE(.);
arrays[tcm_data]
mapping[tcm_data]
_tcm_data_end = ABSOLUTE(.);
} > tcm_idram_seg
.iram0.text :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x40 == 0, "vector address must be 64 byte aligned");
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
} > sram_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* Align the end of code region as per PMP region granularity */
. = ALIGN(_esp_pmp_align_size);
ALIGNED_SYMBOL(4, _iram_text_end)
} > sram_seg
.iram0.data :
{
ALIGNED_SYMBOL(16, _iram_data_start)
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
} > sram_seg
.iram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(16, _iram_bss_start)
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(16, _iram_end)
} > sram_seg
/**
* This section is required to skip .iram0.text area because sram_seg and
* sram_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(sram_seg) + _iram_end - _iram_start;
} > sram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
mapping[dram0_data]
_data_end = ABSOLUTE(.);
} > sram_seg
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT
* can be used as attribute to place data into this section.
* See the "esp_attr.h" file for more information.
*/
.noinit (NOLOAD):
{
ALIGNED_SYMBOL(4, _noinit_start)
*(.noinit .noinit.*)
ALIGNED_SYMBOL(4, _noinit_end)
} > sram_seg
.dram0.bss (NOLOAD) :
{
ALIGNED_SYMBOL(4, _bss_start)
/**
* ldgen places all bss-related data to mapping[dram0_bss]
* (See components/esp_system/app.lf).
*/
mapping[dram0_bss]
ALIGNED_SYMBOL(4, _bss_end)
} > sram_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
ALIGNED_SYMBOL(16, _heap_start)
} > sram_seg
ASSERT(((_heap_start - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), "DRAM segment data does not fit.")
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
arrays[flash_text]
mapping[flash_text]
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
* dummy bytes to ensure this
*/
. += _esp_flash_mmap_prefetch_pad_size;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash text region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > text_seg_low
/**
* Dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > rodata_seg_low
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for mmu driver to maintain virtual address
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first. App version info. */
*(.rodata_desc .rodata_desc.*)
/* Should be the second. Custom app version info. */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
arrays[flash_rodata]
mapping[flash_rodata]
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
. = ALIGN(ALIGNOF(.flash.init_array));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array)
.flash.init_array :
{
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*/
ALIGNED_SYMBOL(4, __preinit_array_start)
ALIGNED_SYMBOL(4, __bothinit_array_start)
KEEP (*(.preinit_array))
__preinit_array_end = ABSOLUTE(.);
. = ALIGN(4);
PROVIDE(__init_priority_array_start = ABSOLUTE(.));
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
. = ALIGN(4);
PROVIDE(__init_priority_array_end = ABSOLUTE(.));
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
__bothinit_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/* Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* tdata sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent. */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > rodata_seg_low
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* tbss sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > rodata_seg_low
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used
* at runtime, helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/* Align the end of flash rodata region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
arrays[rodata_noload]
mapping[rodata_noload]
} > rodata_seg_low
#if CONFIG_SPIRAM_XIP_FROM_PSRAM
/**
* This section is required to skip flash sections, because `extern_ram_seg`
* and `drom_seg` / `irom_seg` are on the same bus when xip on psram
*/
.ext_ram.dummy (NOLOAD):
{
. = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start);
. = ALIGN (_esp_mmu_page_size);
} > ext_ram_seg
#endif //CONFIG_SPIRAM_XIP_FROM_PSRAM
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
/* This section holds .ext_ram.bss data, and will be put in PSRAM */
.ext_ram.bss (NOLOAD) :
{
_ext_ram_bss_start = ABSOLUTE(.);
arrays[extern_ram]
mapping[extern_ram]
ALIGNED_SYMBOL(4, _ext_ram_bss_end)
} > ext_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
/**
* This section holds data that won't be initialised when startup.
* This section locates in External RAM region.
*/
.ext_ram_noinit (NOLOAD) :
{
_ext_ram_noinit_start = ABSOLUTE(.);
*(.ext_ram_noinit*)
ALIGNED_SYMBOL(4, _ext_ram_noinit_end)
} > ext_ram_seg
#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
#include "elf_misc.ld.in"
}
@@ -109,8 +109,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 */
+57 -35
View File
@@ -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(8, _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.
*
@@ -384,9 +373,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))
@@ -398,15 +415,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
@@ -421,7 +441,8 @@ SECTIONS
*/
_rodata_reserved_end = ABSOLUTE(.);
mapping[rodata_noload]
SECTION_MAPPINGS(rodata_noload)
} > default_rodata_seg
.flash.text :
@@ -434,7 +455,7 @@ SECTIONS
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
mapping[flash_text]
SECTION_MAPPINGS(flash_text)
*(.stub)
*(.gnu.warning)
@@ -478,7 +499,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)),
@@ -130,9 +130,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 );
+59 -40
View File
@@ -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(8, _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.
*
@@ -396,9 +382,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))
@@ -410,15 +424,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
@@ -433,7 +450,7 @@ SECTIONS
*/
_rodata_reserved_end = ABSOLUTE(.);
mapping[rodata_noload]
SECTION_MAPPINGS(rodata_noload)
} > default_rodata_seg
/**
@@ -453,7 +470,7 @@ SECTIONS
{
_ext_ram_bss_start = ABSOLUTE(.);
mapping[extern_ram]
SECTION_MAPPINGS(extern_ram)
ALIGNED_SYMBOL(4, _ext_ram_bss_end)
} > extern_ram_seg
@@ -468,6 +485,7 @@ SECTIONS
{
_ext_ram_noinit_start = ABSOLUTE(.);
SECTION_MAPPINGS(extram_noinit)
*(.ext_ram_noinit*)
ALIGNED_SYMBOL(4, _ext_ram_noinit_end)
@@ -491,7 +509,7 @@ SECTIONS
{
ALIGNED_SYMBOL(4, _iram_data_start)
mapping[iram0_data]
SECTION_MAPPINGS(iram0_data)
ALIGNED_SYMBOL(4, _iram_data_end)
} > iram0_0_seg
@@ -500,7 +518,7 @@ SECTIONS
{
ALIGNED_SYMBOL(4, _iram_bss_start)
mapping[iram0_bss]
SECTION_MAPPINGS(iram0_bss)
_iram_bss_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, _iram_end)
@@ -513,7 +531,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)),
+1 -5
View File
@@ -48,10 +48,6 @@ preprocess_linker_file("memory.ld.in" "memory.ld" ld_out_path)
target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}")
# Generate sections.ld.in and pass it through linker script generator
if(CONFIG_IDF_TARGET_ESP32P4 AND NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
preprocess_linker_file("sections.rev3.ld.in" "sections.ld.in" ld_out_path)
else()
preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path)
endif()
preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path)
target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}"
PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld")
+10
View File
@@ -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]
@@ -1,4 +1,5 @@
#include "sdkconfig.h"
#include "ld.common"
/**
* This section is not included in the binary image; it is only present in the ELF file.
@@ -7,20 +8,23 @@
.noload 0 (INFO) :
{
_noload_keep_in_elf_start = ABSOLUTE(.);
SECTION_MAPPINGS(noload_keep_in_elf)
KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*))
mapping[noload_keep_in_elf]
_noload_keep_in_elf_end = ABSOLUTE(.);
}
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
@@ -30,18 +34,23 @@
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
/* DWARF 3 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* GNU DWARF 2 extensions */
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
/* DWARF 4 */
.debug_types 0 : { *(.debug_types) }
/* DWARF 5 */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
@@ -51,30 +60,14 @@
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.comment 0 : { *(.comment) }
.note.GNU-stack 0: { *(.note.GNU-stack) }
/**
* Miscellaneous sections
*/
.comment 0 : { *(.comment) }
.note.GNU-stack 0 : { *(.note.GNU-stack) }
#if CONFIG_IDF_TARGET_ARCH_RISCV
.riscv.attributes 0: { *(.riscv.attributes) }
.riscv.attributes 0 : { *(.riscv.attributes) }
/DISCARD/ :
{
/**
* Discarding .rela.* sections results in the following mapping:
* .rela.text.* -> .text.*
* .rela.data.* -> .data.*
* And so forth...
*/
*(.rela.*)
#if CONFIG_LIBC_NEWLIB
*(.got .got.plt) /* TODO: GCC-382 */
#endif
#if !EH_FRAME_LINKING_ENABLED
*(.eh_frame_hdr)
*(.eh_frame)
#endif // !EH_FRAME_LINKING_ENABLED
}
#elif CONFIG_IDF_TARGET_ARCH_XTENSA
/**
* .xt.prop and .xt.lit sections will be used by the debugger and disassembler
* to get more information about raw data present in the code.
@@ -85,18 +78,6 @@
* This section will only be present in the ELF file, not in the final binary
* For more details, check GCC-212
*/
.xtensa.info 0: { *(.xtensa.info) }
.xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) }
.xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) }
/DISCARD/ :
{
*(.fini)
*(.eh_frame_hdr)
#if !EH_FRAME_LINKING_ENABLED
*(.eh_frame)
#endif // !EH_FRAME_LINKING_ENABLED
}
#else
#error "Target architecture is not supported!"
#endif
.xtensa.info 0 : { *(.xtensa.info) }
.xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) }
.xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) }
@@ -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
}
+116
View File
@@ -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
@@ -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
+260
View File
@@ -0,0 +1,260 @@
#include "sdkconfig.h"
#include "ld.common"
.flash.text :
{
_stext = .;
/**
* Mark the start of flash.text.
* This can be used by the MMU driver to maintain the virtual address.
*/
_instruction_reserved_start = ABSOLUTE(.);
_text_start = ABSOLUTE(.);
SECTION_MAPPINGS(flash_text)
*(.stub)
*(.gnu.linkonce.t.*)
*(.gnu.warning)
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
/**
* CPU will try to prefetch up to 16 bytes of instructions.
* This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction.
* Add dummy bytes to ensure this.
*/
. += _esp_flash_mmap_prefetch_pad_size;
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* Align the end of flash text region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
_text_end = ABSOLUTE(.);
/**
* Mark the flash.text end.
* This can be used for MMU driver to maintain virtual address.
*/
_instruction_reserved_end = ABSOLUTE(.);
_etext = .;
/**
* Similar to _iram_start, this symbol goes here so it is
* resolved by addr2line in preference to the first symbol in
* the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} > flash_text_seg
/**
* Dummy section represents the .flash.text section but in flash_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD) :
{
_flash_rodata_dummy_start = .;
. = ALIGN(ALIGNOF(.flash.text)) + SIZEOF(.flash.text);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > flash_rodata_seg
.flash.appdesc : ALIGN(0x10)
{
/**
* Mark flash.rodata start.
* This can be used for MMU driver to maintain virtual address.
*/
_rodata_reserved_start = ABSOLUTE(.);
_rodata_start = ABSOLUTE(.);
/* !DO NOT PUT ANYTHING BEFORE THIS! */
/* Should be the first: App version info */
*(.rodata_desc .rodata_desc.*)
/* Should be the second: Custom app version info */
*(.rodata_custom_desc .rodata_custom_desc.*)
/**
* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flash.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image.
*/
. = ALIGN(ALIGNOF(.flash.rodata));
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
SECTION_MAPPINGS(flash_rodata)
#if CONFIG_LIBC_PICOLIBC
*(.got .got.plt) /* TODO: GCC-439 */
#endif
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.gcc_except_table .gcc_except_table.*)
*(.gnu.linkonce.e.*)
. = ALIGN(ALIGNOF(.flash.init_array));
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.flash.rodata, .flash.init_array)
.flash.init_array :
{
/**
* C++ constructor tables.
*
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
*/
ALIGNED_SYMBOL(4, __preinit_array_start)
ALIGNED_SYMBOL(4, __bothinit_array_start)
KEEP (*(.preinit_array))
__preinit_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_priority_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
__init_priority_array_end = ABSOLUTE(.);
ALIGNED_SYMBOL(4, __init_array_start)
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
__init_array_end = ABSOLUTE(.);
__bothinit_array_end = ABSOLUTE(.);
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
/* System init functions registered via ESP_SYSTEM_INIT_FN */
ALIGNED_SYMBOL(4, _esp_system_init_fn_array_start)
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA));
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.flash.init_array, SECTION_AFTER_FLASH_RODATA)
#if EH_FRAME_LINKING_ENABLED
.eh_frame_hdr :
{
ALIGNED_SYMBOL(4, __eh_frame_hdr)
KEEP (*(.eh_frame_hdr))
__eh_frame_hdr_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.eh_frame));
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame)
.eh_frame :
{
ALIGNED_SYMBOL(4, __eh_frame)
KEEP (*(.eh_frame))
/**
* As we are not linking with crtend.o, which includes the CIE terminator
* (see __FRAME_END__ in libgcc sources), it is manually provided here.
*/
LONG(0);
__eh_frame_end = ABSOLUTE(.);
. = ALIGN(ALIGNOF(.flash.tdata));
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata)
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
ASSERT((__eh_frame_hdr_end > __eh_frame_hdr), "eh_frame_hdr size is 0")
ASSERT((__eh_frame_end > __eh_frame), "eh_frame size is 0")
#endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME
#endif // EH_FRAME_LINKING_ENABLED
.flash.tdata :
{
/**
* IMPORTANT: Keep tdata and tbss sections contiguous (no gaps between them).
* The TLS runtime code calculates offsets assuming these sections are
* adjacent. Gaps would cause incorrect address calculations, leading
* to accessing wrong memory.
*/
/* Thread-local data sections */
_thread_local_data_start = ABSOLUTE(.);
#if CONFIG_LIBC_PICOLIBC
_picolibc_reent_stub_start = ABSOLUTE(.);
KEEP(*(.tdata.errno))
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
/* Reproduce the public fields from struct _reent */
KEEP(*(.tdata.tls_stdin))
KEEP(*(.tdata.tls_stdout))
KEEP(*(.tdata.tls_stderr))
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
_picolibc_reent_stub_end = ABSOLUTE(.);
#endif // CONFIG_LIBC_PICOLIBC
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(ALIGNOF(.flash.tbss));
_thread_local_data_end = ABSOLUTE(.);
} > flash_rodata_seg
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
ASSERT_PICOLIBC_REENT_STUB()
.flash.tbss (NOLOAD) :
{
/* Thread-local BSS sections */
_thread_local_bss_start = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon .tcommon.*)
_thread_local_bss_end = ABSOLUTE(.);
} > flash_rodata_seg
ASSERT(_thread_local_data_end == _thread_local_bss_start,
"tdata and tbss must be contiguous.")
/**
* This section contains all the rodata that is not used at runtime,
* helping to avoid an increase in binary size.
*/
.flash.rodata_noload (NOLOAD) :
{
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* Align the end of flash rodata region as per PMP granularity to allow using the
* page alignment gap created while mapping the flash region into the PSRAM memory.
*/
. = ALIGN(_esp_pmp_align_size);
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
/**
* This symbol marks the end of flash.rodata. It can be utilized by the MMU
* driver to maintain the virtual address.
* NOLOAD rodata may not be included in this section.
*/
_rodata_reserved_end = .;
SECTION_MAPPINGS(rodata_noload)
} > flash_rodata_seg
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**
* If rodata default segment is placed in `flash_rodata_seg`, then flash's first
* rodata section must also be first in the segment.
*/
ASSERT(_flash_rodata_dummy_start == ORIGIN(flash_rodata_seg),
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
#endif
@@ -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.")
+97
View File
@@ -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.")
+170
View File
@@ -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
+15
View File
@@ -0,0 +1,15 @@
#include "ld.common"
.tcm.text :
{
/* Code marked as running out of TCM */
_tcm_text_start = ABSOLUTE(.);
SECTION_MAPPINGS(tcm_text)
_tcm_text_end = ABSOLUTE(.);
} > tcm_idram_seg
.tcm.data :
{
_tcm_data_start = ABSOLUTE(.);
SECTION_MAPPINGS(tcm_data)
_tcm_data_end = ABSOLUTE(.);
} > tcm_idram_seg
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -450,30 +450,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
@@ -500,10 +506,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;
}
@@ -8,7 +8,7 @@
*
* SPDX-License-Identifier: MIT
*
* SPDX-FileContributor: 2023-2024 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
@@ -220,30 +220,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
@@ -270,10 +276,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;
}
+1 -3
View File
@@ -985,9 +985,7 @@ def test_rtc_fast_reg2_execute_violation(dut: PanicTestDut, test_func_name: str)
# TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs
@pytest.mark.generic
@pytest.mark.xfail(
'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False
)
@pytest.mark.xfail(targets=['esp32s2'], reason='Multiple panic reasons for the same test may surface', run=False)
@idf_parametrize('config, target', CONFIGS_MEMPROT_RTC_FAST_MEM, indirect=['config', 'target'])
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration, IDF-14348')
def test_rtc_fast_reg3_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: