mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
e0d29d4ada
PMS aware chips require prefetch padding size for instruction fetch, or some memory alignment considerations. These settings are now exposed through kconfig options (hidden) and used through common ld template. This shall help to add and manage future chips support easily for these considerations. Closes IDF-3624
406 lines
11 KiB
Plaintext
406 lines
11 KiB
Plaintext
/*
|
|
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
/* 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(4);
|
|
|
|
mapping[rtc_text]
|
|
|
|
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
|
|
_rtc_text_end = ABSOLUTE(.);
|
|
} > rtc_iram_seg
|
|
|
|
/*
|
|
This section is required to skip rtc.text area because rtc_iram_seg and
|
|
rtc_data_seg are reflect the same address space on different buses.
|
|
*/
|
|
.rtc.dummy :
|
|
{
|
|
_rtc_dummy_start = ABSOLUTE(.);
|
|
_rtc_fast_start = ABSOLUTE(.);
|
|
. = SIZEOF(.rtc.text);
|
|
_rtc_dummy_end = ABSOLUTE(.);
|
|
} > rtc_data_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 :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_force_fast_start = ABSOLUTE(.);
|
|
|
|
mapping[rtc_force_fast]
|
|
|
|
*(.rtc.force_fast .rtc.force_fast.*)
|
|
. = ALIGN(4) ;
|
|
|
|
_rtc_force_fast_end = ABSOLUTE(.);
|
|
} > 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.
|
|
The memory location of the data is dependent on
|
|
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
|
*/
|
|
.rtc.data :
|
|
{
|
|
_rtc_data_start = ABSOLUTE(.);
|
|
|
|
mapping[rtc_data]
|
|
|
|
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
|
|
_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.*)
|
|
*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.
|
|
The memory location of the data is dependent on
|
|
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
|
*/
|
|
.rtc_noinit (NOLOAD):
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_noinit_start = ABSOLUTE(.);
|
|
*(.rtc_noinit .rtc_noinit.*)
|
|
. = ALIGN(4) ;
|
|
_rtc_noinit_end = ABSOLUTE(.);
|
|
} > 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 :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_force_slow_start = ABSOLUTE(.);
|
|
*(.rtc.force_slow .rtc.force_slow.*)
|
|
. = ALIGN(4) ;
|
|
_rtc_force_slow_end = ABSOLUTE(.);
|
|
} > rtc_slow_seg
|
|
|
|
/* 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.")
|
|
|
|
/* Send .iram0 code to iram */
|
|
.iram0.vectors :
|
|
{
|
|
_iram_start = ABSOLUTE(.);
|
|
/* Vectors go to IRAM */
|
|
_vector_table = ABSOLUTE(.);
|
|
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
|
. = 0x0;
|
|
KEEP(*(.WindowVectors.text));
|
|
. = 0x180;
|
|
KEEP(*(.Level2InterruptVector.text));
|
|
. = 0x1c0;
|
|
KEEP(*(.Level3InterruptVector.text));
|
|
. = 0x200;
|
|
KEEP(*(.Level4InterruptVector.text));
|
|
. = 0x240;
|
|
KEEP(*(.Level5InterruptVector.text));
|
|
. = 0x280;
|
|
KEEP(*(.DebugExceptionVector.text));
|
|
. = 0x2c0;
|
|
KEEP(*(.NMIExceptionVector.text));
|
|
. = 0x300;
|
|
KEEP(*(.KernelExceptionVector.text));
|
|
. = 0x340;
|
|
KEEP(*(.UserExceptionVector.text));
|
|
. = 0x3C0;
|
|
KEEP(*(.DoubleExceptionVector.text));
|
|
. = 0x400;
|
|
_invalid_pc_placeholder = ABSOLUTE(.);
|
|
*(.*Vector.literal)
|
|
|
|
*(.UserEnter.literal);
|
|
*(.UserEnter.text);
|
|
. = ALIGN (16);
|
|
*(.entry.text)
|
|
*(.init.literal)
|
|
*(.init)
|
|
|
|
_init_end = ABSOLUTE(.);
|
|
} > iram0_0_seg
|
|
|
|
.iram0.text :
|
|
{
|
|
/* Code marked as runnning out of IRAM */
|
|
_iram_text_start = ABSOLUTE(.);
|
|
|
|
mapping[iram0_text]
|
|
|
|
} > iram0_0_seg
|
|
|
|
.dram0.data :
|
|
{
|
|
_data_start = ABSOLUTE(.);
|
|
*(.gnu.linkonce.d.*)
|
|
*(.data1)
|
|
*(.sdata)
|
|
*(.sdata.*)
|
|
*(.gnu.linkonce.s.*)
|
|
*(.sdata2)
|
|
*(.sdata2.*)
|
|
*(.gnu.linkonce.s2.*)
|
|
*(.jcr)
|
|
|
|
_esp_system_init_fn_array_start = ABSOLUTE(.);
|
|
KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*)))
|
|
_esp_system_init_fn_array_end = ABSOLUTE(.);
|
|
|
|
mapping[dram0_data]
|
|
|
|
_data_end = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
} > dram0_0_seg
|
|
|
|
/**
|
|
* 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*)
|
|
. = ALIGN(4);
|
|
_ext_ram_noinit_end = ABSOLUTE(.);
|
|
} > extern_ram_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):
|
|
{
|
|
. = ALIGN(4);
|
|
_noinit_start = ABSOLUTE(.);
|
|
*(.noinit .noinit.*)
|
|
. = ALIGN(4) ;
|
|
_noinit_end = ABSOLUTE(.);
|
|
} > dram0_0_seg
|
|
|
|
/* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/
|
|
.ext_ram.bss (NOLOAD) :
|
|
{
|
|
_ext_ram_bss_start = ABSOLUTE(.);
|
|
|
|
mapping[extern_ram]
|
|
|
|
. = ALIGN(4);
|
|
_ext_ram_bss_end = ABSOLUTE(.);
|
|
} > extern_ram_seg
|
|
|
|
/* Shared RAM */
|
|
.dram0.bss (NOLOAD) :
|
|
{
|
|
. = ALIGN (8);
|
|
_bss_start = ABSOLUTE(.);
|
|
|
|
mapping[dram0_bss]
|
|
|
|
. = ALIGN (8);
|
|
_bss_end = ABSOLUTE(.);
|
|
} > dram0_0_seg
|
|
|
|
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
|
"DRAM segment data does not fit.")
|
|
|
|
.flash.appdesc : ALIGN(0x10)
|
|
{
|
|
_rodata_start = ABSOLUTE(.);
|
|
|
|
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
|
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
|
|
|
/* Create an empty gap within this section. Thanks to this, the end of this
|
|
* section will match .flah.rodata's begin address. Thus, both sections
|
|
* will be merged when creating the final bin image. */
|
|
. = ALIGN(ALIGNOF(.flash.rodata));
|
|
} >default_rodata_seg
|
|
|
|
.flash.rodata : ALIGN(0x10)
|
|
{
|
|
_flash_rodata_start = ABSOLUTE(.);
|
|
|
|
mapping[flash_rodata]
|
|
|
|
|
|
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
|
*(.gnu.linkonce.r.*)
|
|
*(.rodata1)
|
|
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
|
|
*(.xt_except_table)
|
|
*(.gcc_except_table .gcc_except_table.*)
|
|
*(.gnu.linkonce.e.*)
|
|
*(.gnu.version_r)
|
|
. = (. + 3) & ~ 3;
|
|
__eh_frame = ABSOLUTE(.);
|
|
KEEP(*(.eh_frame))
|
|
. = (. + 7) & ~ 3;
|
|
/* C++ constructor and destructor tables
|
|
|
|
Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt
|
|
*/
|
|
__init_array_start = ABSOLUTE(.);
|
|
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*)))
|
|
__init_array_end = ABSOLUTE(.);
|
|
|
|
KEEP (*crtbegin.*(.dtors))
|
|
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
|
KEEP (*(SORT(.dtors.*)))
|
|
KEEP (*(.dtors))
|
|
/* C++ exception handlers table: */
|
|
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
|
|
*(.xt_except_desc)
|
|
*(.gnu.linkonce.h.*)
|
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
|
*(.xt_except_desc_end)
|
|
*(.dynamic)
|
|
*(.gnu.version_d)
|
|
/* Addresses of memory regions reserved via
|
|
SOC_RESERVE_MEMORY_REGION() */
|
|
soc_reserved_memory_region_start = ABSOLUTE(.);
|
|
KEEP (*(.reserved_memory_address))
|
|
soc_reserved_memory_region_end = ABSOLUTE(.);
|
|
_rodata_end = ABSOLUTE(.);
|
|
/* Literals are also RO data. */
|
|
_lit4_start = ABSOLUTE(.);
|
|
*(*.lit4)
|
|
*(.lit4.*)
|
|
*(.gnu.linkonce.lit4.*)
|
|
_lit4_end = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
_thread_local_start = ABSOLUTE(.);
|
|
*(.tdata)
|
|
*(.tdata.*)
|
|
*(.tbss)
|
|
*(.tbss.*)
|
|
_thread_local_end = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
} >default_rodata_seg
|
|
|
|
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
|
|
|
.flash.rodata_noload (NOLOAD) :
|
|
{
|
|
. = ALIGN (4);
|
|
mapping[rodata_noload]
|
|
} > default_rodata_seg
|
|
|
|
.flash.text :
|
|
{
|
|
_stext = .;
|
|
_text_start = ABSOLUTE(.);
|
|
|
|
mapping[flash_text]
|
|
|
|
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
|
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
|
|
*(.fini.literal)
|
|
*(.fini)
|
|
*(.gnu.version)
|
|
|
|
/** 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(.);
|
|
_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
|
|
|
|
/* Marks the end of IRAM code segment */
|
|
.iram0.text_end (NOLOAD) :
|
|
{
|
|
. = ALIGN (4);
|
|
_iram_text_end = ABSOLUTE(.);
|
|
} > iram0_0_seg
|
|
|
|
.iram0.data :
|
|
{
|
|
. = ALIGN(4);
|
|
_iram_data_start = ABSOLUTE(.);
|
|
|
|
mapping[iram0_data]
|
|
|
|
_iram_data_end = ABSOLUTE(.);
|
|
} > iram0_0_seg
|
|
|
|
.iram0.bss (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_iram_bss_start = ABSOLUTE(.);
|
|
|
|
mapping[iram0_bss]
|
|
|
|
_iram_bss_end = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
_iram_end = ABSOLUTE(.);
|
|
} > iram0_0_seg
|
|
|
|
/* Marks the end of data, bss and possibly rodata */
|
|
.dram0.heap_start (NOLOAD) :
|
|
{
|
|
. = ALIGN (8);
|
|
_heap_start = ABSOLUTE(.);
|
|
} > dram0_0_seg
|
|
}
|
|
|
|
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.")
|