diff --git a/cpu/esp32/ld/esp32c3/memory.ld b/cpu/esp32/ld/esp32c3/memory.ld new file mode 100644 index 0000000000..b251c2841c --- /dev/null +++ b/cpu/esp32/ld/esp32c3/memory.ld @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * ESP32-C3 Linker Script Memory Layout + * This file describes the memory layout (memory blocks) by virtual memory addresses. + * This linker script is passed through the C preprocessor to include configuration options. + * Please use preprocessor features sparingly! + * Restrict to simple macros with numeric values, and/or #if/#endif blocks. + */ +/* + * Automatically generated file. DO NOT EDIT. + * Espressif IoT Development Framework (ESP-IDF) Configuration Header + */ + +/* List of deprecated options */ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* CPU instruction prefetch padding size for flash mmap scenario */ +_esp_flash_mmap_prefetch_pad_size = 16; +/* CPU instruction prefetch padding size for memory protection scenario */ +_esp_memprot_prefetch_pad_size = 16; +/* Memory alignment size for PMS */ +_esp_memprot_align_size = 512; +MEMORY +{ + /** + * All these values assume the flash cache is on, and have the blocks this uses subtracted from the length + * of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but + * are connected to the data port of the CPU and eg allow byte-wise access. + */ + /* IRAM for PRO CPU. */ + iram0_0_seg (RX) : org = (0x4037C000 + 0x4000), len = 0x403D0000 - (0x4037C000 - 0x3FC7C000) - (0x3FC7C000 + 0x4000) + /* Flash mapped instruction data */ + iram0_2_seg (RX) : org = 0x42000020, len = 0x800000-0x20 + /** + * (0x20 offset above is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB).) + */ + /** + * Shared data RAM, excluding memory reserved for ROM bss/data/stack. + * Enabling Bluetooth & Trace Memory features in menuconfig will decrease the amount of RAM available. + */ + dram0_0_seg (RW) : org = (0x3FC7C000 + 0x4000), len = 0x403D0000 - (0x4037C000 - 0x3FC7C000) - (0x3FC7C000 + 0x4000) + /* Flash mapped constant data */ + drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20 + /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */ + /** + * RTC fast memory (executable). Persists over deep sleep. + */ + rtc_iram_seg(RWX) : org = 0x50000000, len = 0x2000 - 0 +} +_static_data_end = _bss_end; +/* 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_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); + REGION_ALIAS("default_code_seg", iram0_2_seg); + REGION_ALIAS("default_rodata_seg", drom0_0_seg); +/** + * If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must + * also be first in the segment. + */ +/* TODO + ASSERT(_rodata_start == ORIGIN(default_rodata_seg), + ".flash.appdesc section must be placed at the beginning of the rodata segment.") +*/ diff --git a/cpu/esp32/ld/esp32c3/sections.ld b/cpu/esp32/ld/esp32c3/sections.ld new file mode 100644 index 0000000000..1f9207f8e2 --- /dev/null +++ b/cpu/esp32/ld/esp32c3/sections.ld @@ -0,0 +1,608 @@ +/* Automatically generated file; DO NOT EDIT */ +/* Espressif IoT Development Framework Linker Script */ +/* Generated from: esp-idf/components/esp_system/ld/esp32c3/sections.ld.in */ + +/* + * 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); + _rtc_fast_start = ABSOLUTE(.); + + *(.rtc.literal .rtc.text .rtc.text.*) + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + *(.rtc_text_end_test) + + /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ + . += _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 : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + _coredump_rtc_fast_start = ABSOLUTE(.); + *(.rtc.fast.coredump .rtc.fast.coredump.*) + _coredump_rtc_fast_end = ABSOLUTE(.); + + *(.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. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + _coredump_rtc_start = ABSOLUTE(.); + *(.rtc.coredump .rtc.coredump.*) + _coredump_rtc_end = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + + *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) : + { + /* part that is initialized if not waking up from deep sleep */ + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.*(.bss .bss.*) + *rtc_wake_stub*.*(COMMON) + _rtc_bss_end = ABSOLUTE(.); + /* part that saves some data for rtc periph module, this part is + only initialized at power on reset */ + _rtc_bss_rtc_start = ABSOLUTE(.); + *(.rtc.bss .rtc.bss.*) + _rtc_bss_rtc_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): + { + . = 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.") + + .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.text)); + . = ALIGN(4); + + _invalid_pc_placeholder = ABSOLUTE(.); + + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + *(.iram1 .iram1.*) + + /* parts of RIOT that should run in IRAM */ + *core/*(.literal .text .literal.* .text.*) + *esp_common_periph/flash.*(.literal .text .literal.* .text.*) + *esp_common/thread_arch.*(.literal .text .literal.* .text.*) + *esp_freertos_common/*(.literal .text .literal.* .text.*) + + /* parts of ESP-IDF that should run in IRAM */ + /* find components/ -type f -name linker.lf -exec grep "(noflash)" {} \; -print */ + /* find components/ -type f -name linker.lf -exec grep "(noflash_text)" {} \; -print */ + *components/app_trace/app_trace.*(.literal .literal.* .text .text.*) + *components/app_trace/app_trace_util.*(.literal .literal.* .text .text.*) + *components/esp_event/default_event_loop.*(.literal.esp_event_isr_post .text.esp_event_isr_post) + *components/esp_event/esp_event.*(.literal.esp_event_isr_post_to .text.esp_event_isr_post_to) + *components/esp_hw_support/cpu_util.*(.literal .literal.* .text .text.*) + *components/esp_hw_support/*/rtc_clk.*(.literal .literal.* .text .text.*) + *components/esp_hw_support/*/rtc_init.*(.literal.rtc_vddsdio_set_config .text.rtc_vddsdio_set_config) + *components/esp_hw_support/*/rtc_pm.*(.literal .literal.* .text .text.*) + *components/esp_hw_support/*/rtc_sleep.*(.literal .literal.* .text .text.*) + *components/esp_hw_support/*/rtc_time.*(.literal .literal.* .text .text.*) + *components/esp_hw_support/*/rtc_wdt.*(.literal .literal.* .text .text.*) + *components/esp_ringbuf/*(.literal .literal.* .text .text.*) + *components/esp_rom/esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *components/esp_system/esp_err.*(.literal .literal.* .text .text.*) + *components/esp_system/esp_system.*(.literal.esp_system_abort .text.esp_system_abort) + *components/esp_system/ubsan.*(.literal .literal.* .text .text.*) + + *libgcc.a:_divsf3.*(.literal .literal.* .text .text.*) + *libgcc.a:lib2funcs.*(.literal .literal.* .text .text.*) + *libgcc.a:save-restore.*(.literal .literal.* .text .text.*) + *libgcov.a:(.literal .literal.* .text .text.*) + + *components/hal/cpu_hal.*(.literal .literal.* .text .text.*) + *components/hal/i2c_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/ledc_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/soc_hal.*(.literal .literal.* .text .text.*) + *components/hal/spi_flash_encrypt_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + *components/hal/spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/spi_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/spi_slave_hal_iram.*(.literal .literal.* .text .text.*) + *components/hal/systimer_hal.*(.literal .literal.* .text .text.*) + *components/hal/twai_hal.*(.literal .literal.* .text .text.*) + *components/hal/uart_hal.*(.literal .literal.* .text .text.*) + *components/hal/wdt_hal_iram.*(.literal .literal.* .text .text.*) + *components/heap/heap_tlsf.*(.literal .literal.* .text .text.*) + *components/heap/multi_heap.*(.literal .literal.* .text .text.*) + + *esp-idf/esp_idf_support.*(.literal.esp_log_write .text.esp_log_write) + + *libnet80211.a:(.wifi0iram .wifi0iram.*) + *libnet80211.a:(.wifirxiram .wifirxiram.*) + *libnet80211.a:(.wifislprxiram .wifislprxiram.*) + + *components/newlib/abort.*(.literal .literal.* .text .text.*) + *components/newlib/assert.*(.literal .literal.* .text .text.*) + *components/newlib/heap.*(.literal .literal.* .text .text.*) + *components/newlib/stdatomic.*(.literal .literal.* .text .text.*) + + *libpp.a:(.wifi0iram .wifi0iram.*) + *libpp.a:(.wifiorslpiram .wifiorslpiram.*) + *libpp.a:(.wifirxiram .wifirxiram.*) + *libpp.a:(.wifislprxiram .wifislprxiram.*) + *librtc.a:(.literal .literal.* .text .text.*) + + *components/soc/lldesc.*(.literal .literal.* .text .text.*) + *components/spi_flash/memspi_host_driver.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_boya.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_gd.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_generic.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_issi.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_mxic.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_mxic_opi.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_th.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_chip_winbond.*(.literal .literal.* .text .text.*) + *components/spi_flash/*/spi_flash_rom_patch.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_flash_timing_tuning.*(.literal .literal.* .text .text.*) + *components/spi_flash/spi_timing_config.*(.literal .literal.* .text .text.*) + + *components/riscv/interrupt.*(.literal .literal.* .text .text.*) + *components/riscv/vectors.*(.literal .literal.* .text .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.*) + KEEP (*(SORT(.xfa.*))) + *(.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(.); + + *(EXCLUDE_FILE(*libbt.a *libbtdm_app.a *libnimble.a) .data EXCLUDE_FILE(*libbt.a *libbtdm_app.a *libnimble.a) .data.*) + *(.dram1 .dram1.*) + _coredump_dram_start = ABSOLUTE(.); + *(.dram1.coredump .dram1.coredump.*) + _coredump_dram_end = ABSOLUTE(.); + *components/app_trace/app_trace.*(.rodata .rodata.*) + *components/app_trace/app_trace_util.*(.rodata .rodata.*) + _bt_data_start = ABSOLUTE(.); + *libbt.a:(.data .data.*) + . = ALIGN(4); + _bt_data_end = ABSOLUTE(.); + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN(4); + _btdm_data_end = ABSOLUTE(.); + + /* find components/ -type f -name linker.lf -exec grep "(noflash)" {} \; -print */ + *components/esp_hw_support/port/*/rtc_clk.*(.rodata .rodata.*) + *components/esp_rom/esp_rom_spiflash.*(.rodata .rodata.*) + *components/esp_system/esp_err.*(.rodata .rodata.*) + *components/esp_system/ubsan.*(.rodata .rodata.*) + + *libgcc.a:_divsf3.*(.rodata .rodata.*) + *libgcc.a:save-restore.*(.rodata .rodata.*) + *libgcov.a:(.rodata .rodata.*) + + *components/hal/cpu_hal.*(.rodata .rodata.*) + *components/hal/i2c_hal_iram.*(.rodata .rodata.*) + *components/hal/ledc_hal_iram.*(.rodata .rodata.*) + *components/hal/soc_hal.*(.rodata .rodata.*) + *components/hal/spi_flash_encrypt_hal_iram.*(.rodata .rodata.*) + *components/hal/spi_flash_hal_gpspi.*(.rodata .rodata.*) + *components/hal/spi_flash_hal_iram.*(.rodata .rodata.*) + *components/hal/spi_hal_iram.*(.rodata .rodata.*) + *components/hal/spi_slave_hal_iram.*(.rodata .rodata.*) + *components/hal/systimer_hal.*(.rodata .rodata.*) + *components/hal/twai_hal.*(.rodata .rodata.*) + *components/hal/uart_hal.*(.rodata .rodata.*) + *components/hal/wdt_hal_iram.*(.rodata .rodata.*) + *components/heap/heap_tlsf.*(.rodata .rodata.*) + *components/heap/multi_heap.*(.rodata .rodata.*) + + *components/newlib/abort.*(.rodata .rodata.*) + *components/newlib/assert.*(.rodata .rodata.*) + *components/newlib/heap.*(.rodata .rodata.*) + *components/newlib/stdatomic.*(.rodata .rodata.*) + + _nimble_data_start = ABSOLUTE(.); + *libnimble.a:(.data .data.*) + . = ALIGN(4); + _nimble_data_end = ABSOLUTE(.); + *libphy.a:(.rodata .rodata.*) + + *components/soc/lldesc.*(.rodata .rodata.*) + *components/spi_flash/memspi_host_driver.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_boya.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_gd.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_generic.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_issi.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_mxic.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_mxic_opi.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_th.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_chip_winbond.*(.rodata .rodata.*) + *components/spi_flash/*/spi_flash_rom_patch.*(.rodata .rodata.*) + *components/spi_flash/spi_flash_timing_tuning.*(.rodata .rodata.*) + *components/spi_flash/spi_timing_config.*(.rodata .rodata.*) + + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } > 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): + { + . = ALIGN(4); + _noinit_start = ABSOLUTE(.); + *(.noinit .noinit.*) + . = ALIGN(4) ; + _noinit_end = ABSOLUTE(.); + } > dram0_0_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + + *(.bss .bss.*) + *(.ext_ram.bss .ext_ram.bss.*) + *(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem) + *(COMMON) + _bt_bss_start = ABSOLUTE(.); + *libbt.a:(.bss .bss.* COMMON) + . = ALIGN(4); + _bt_bss_end = ABSOLUTE(.); + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN(4); + _btdm_bss_end = ABSOLUTE(.); + _nimble_bss_start = ABSOLUTE(.); + *libnimble.a:(.bss .bss.* COMMON) + . = ALIGN(4); + _nimble_bss_end = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.share.mem) + *(.gnu.linkonce.b.*) + + . = 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.text : + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + + *(.literal .literal.* .text .text.*) + + *(.wifi0iram .wifi0iram.*) + *(.wifiorslpiram .wifiorslpiram.*) + *(.wifirxiram .wifirxiram.*) + *(.wifislpiram .wifislpiram.*) + *(.wifislprxiram .wifislprxiram.*) + + *(.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(.); + _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 + + /** + * This dummy section represents the .flash.text section but in default_rodata_seg. + * Thus, it must have its alignement and (at least) its size. + */ + .flash_rodata_dummy (NOLOAD): + { + _flash_rodata_dummy_start = .; + /* Start at the same alignement constraint than .flash.text */ + . = ALIGN(ALIGNOF(.flash.text)); + /* Create an empty gap as big as .flash.text section */ + . = . + SIZEOF(.flash.text); + /* Prepare the alignement of the section above. Few bytes (0x20) must be + * added for the mapping header. */ + . = ALIGN(0x10000) + 0x20; + _rodata_reserved_start = .; + } > default_rodata_seg + + .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 .flash.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(.); + + *(.rodata .rodata.*) + + *(.rodata_wlog_error .rodata_wlog_error.*) + *(.rodata_wlog_info .rodata_wlog_info.*) + *(.rodata_wlog_warning .rodata_wlog_warning.*) + + KEEP (*(SORT(.roxfa.*))) + + *(.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) + . = (. + 7) & ~ 3; + /* + * C++ constructor and destructor tables + * Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt. + * + * RISC-V gcc is configured with --enable-initfini-array so it emits an .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. + */ + __init_priority_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) + __init_priority_array_end = ABSOLUTE(.); + __init_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) + __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.*) + *(.srodata) + *(.srodata.*) + _thread_local_end = ABSOLUTE(.); + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(.eh_frame)); + } > default_rodata_seg + + /* Keep this section shall be at least aligned on 4 */ + .eh_frame : ALIGN(8) + { + __eh_frame = ABSOLUTE(.); + KEEP (*(.eh_frame)) + __eh_frame_end = ABSOLUTE(.); + /* Guarantee that this section and the next one will be merged by making + * them adjacent. */ + . = ALIGN(ALIGNOF(.eh_frame_hdr)); + } > default_rodata_seg + + /* To avoid any exception in C++ exception frame unwinding code, this section + * shall be aligned on 8. */ + .eh_frame_hdr : ALIGN(8) + { + __eh_frame_hdr = ABSOLUTE(.); + KEEP (*(.eh_frame_hdr)) + __eh_frame_hdr_end = ABSOLUTE(.); + } > default_rodata_seg + + .flash.rodata_noload (NOLOAD) : + { + . = ALIGN (4); + *(.rodata_wlog_debug .rodata_wlog_debug.*) + *(.rodata_wlog_verbose .rodata_wlog_verbose.*) + } > default_rodata_seg + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + /* iram_end_test section exists for use by Memprot unit tests only */ + *(.iram_end_test) + /* ESP32-C3 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(_esp_memprot_align_size); + _iram_text_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.data : + { + . = ALIGN(16); + _iram_data_start = ABSOLUTE(.); + + *(.iram.data .iram.data.*) + _coredump_iram_start = ABSOLUTE(.); + *(.iram.data.coredump .iram.data.coredump.*) + _coredump_iram_end = ABSOLUTE(.); + + _iram_data_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + _iram_bss_start = ABSOLUTE(.); + + *(.iram.bss .iram.bss.*) + + _iram_bss_end = ABSOLUTE(.); + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + /* Marks the end of data, bss and possibly rodata */ + .dram0.heap_start (NOLOAD) : + { + . = ALIGN (16); + _heap_start = ABSOLUTE(.); + _sheap = ABSOLUTE(.); + } > dram0_0_seg + _eheap = phy_param_rom; + +} + +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.")