diff --git a/cpu/esp32/ld/esp32s2/memory.ld b/cpu/esp32/ld/esp32s2/memory.ld new file mode 100644 index 0000000000..9996caf60c --- /dev/null +++ b/cpu/esp32/ld/esp32s2/memory.ld @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* ESP32S2 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 = 4; +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 bytewise access. */ + /* IRAM for CPU.*/ + iram0_0_seg (RX) : org = (0x40020000 + 0x2000 + 0x2000), len = 0x3FFE0000 - (0x3FFB0000 + 0x2000 + 0x2000) + /* Even though the segment name is iram, it is actually mapped to flash + */ + iram0_2_seg (RX) : org = 0x40080020, len = 0x780000-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 bootloader and ROM bss/data/stack. */ + dram0_0_seg (RW) : org = (0x3FFB0000 + 0x2000 + 0x2000), len = 0x3FFE0000 - (0x3FFB0000 + 0x2000 + 0x2000) - 0 + /* Flash mapped constant data */ + drom0_0_seg (R) : org = 0x3F000020, len = 0x3f0000-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 = 0x40070000, len = 0x2000 + /* RTC slow memory (data accessible). Persists over deep sleep. + + Start of RTC slow memory is reserved for ULP co-processor code + data, if enabled. + */ + rtc_slow_seg(RW) : org = 0x50000000 + 0, + len = 0x2000 - 0 + /* RTC fast memory (same block as above), viewed from data bus */ + rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - 0 + /* external memory, covers the dport, dram0, dram1 cacheable address space */ + extern_ram_seg(RWX) : org = 0x3F500000, + len = 0xA80000 +} +_static_data_end = _bss_end; + +/** + * _heap_end = 0x40000000; + * + * NOTE: + * In RIOT, we suppose that + * - SRAM0 (0x3FFB_0000 ~ 0x3FFB_2000 / 0x4002_0000 ~ 0x4002_2000) 8 kByte ICache, + * - SRAM0 (0x3FFB_2000 ~ 0x3FFB_4000 / 0x4002_2000 ~ 0x4002_4000) 8 kByte DCache, + * - SRAM1 (0x3FFB_4000 ~ 0x3FFD_FFFF / 0x4002_4000 ~ 0x4002_6C000) 176 kByte + * addresses the same memory and is used as IRAM and DRAM. + * Therefore, we suppose _heap_end is at 0x3FFE_0000. + */ +_heap_end = 0x3FFE0000; +/*_eheap = 0x3FFE0000; */ + +_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 + TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */ +REGION_ALIAS("rtc_data_location", rtc_slow_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_reserved_start == ORIGIN(default_rodata_seg), + ".flash.appdesc section must be placed at the beginning of the rodata segment.") +*/ diff --git a/cpu/esp32/ld/esp32s2/sections.ld b/cpu/esp32/ld/esp32s2/sections.ld new file mode 100644 index 0000000000..483429033c --- /dev/null +++ b/cpu/esp32/ld/esp32s2/sections.ld @@ -0,0 +1,601 @@ +/* Automatically generated file; DO NOT EDIT */ +/* Espressif IoT Development Framework Linker Script */ +/* Generated from: /home/gs/tmp/esp-idf-v4.4.1/components/esp_system/ld/esp32s2/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 : + { + _rtc_text_start = ABSOLUTE(.); + . = ALIGN(4); + + _rtc_code_start = .; + + *(.rtc.literal .rtc.text .rtc.text.*) + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + _rtc_code_end = .; + + /* possibly align + add 16B for CPU dummy speculative instr. fetch */ + . = ((_rtc_code_end - _rtc_code_start) == 0) ? ALIGN(0) : ALIGN(4) + 16; + + _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(.); + + _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. + The memory location of the data is dependent on + CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option. + */ + .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. + The memory location of the data is dependent on + CONFIG_ESP32S2_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(.); + + *(.iram1 .iram1.*) + + /* Xtensa basic functionality written in assembler should be placed in IRAM */ + *xtensa/*(.literal .text .literal.* .text.*) + /* 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/*regi2c_ctrl.*(.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.*) + + *libxt_hal.a:(.literal .literal.* .text .text.*) + *libxtensa.a:eri.*(.literal .literal.* .text .text.*) + *libxtensa.a:xtensa_intr_asm.*(.literal .literal.* .text .text.*) + + /* Added to maintain compability, there are no iram0 data section to put + * sections:iram_coredump entry defined in espcoredump's linker.lf file */ + _coredump_iram_start = 0; + _coredump_iram_end = 0; + + /* align + add 16B for CPU dummy speculative instr. fetch */ + . = ALIGN(_esp_memprot_align_size) + _esp_memprot_prefetch_pad_size; + /* iram_end_test section exists for use by memprot unit tests only */ + *(.iram_end_test) + _iram_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + .dram0_reserved_for_iram (NOLOAD): + { + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } > dram0_0_seg + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.gnu.linkonce.d.*) + *(.data1) + *(.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(.); + *(.dram2.coredump .dram2.coredump.*) + _coredump_dram_end = ABSOLUTE(.); + *libapp_trace.a:app_trace.*(.rodata .rodata.*) + *libapp_trace.a: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/*regi2c_ctrl.*(.rodata .rodata.*) + *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(.); + + *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 + + /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + + . = ALIGN(4); + _ext_ram_bss_end = ABSOLUTE(.); + } > extern_ram_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + + *(.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 + + .flash.appdesc : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); + _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(.); + + *(.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) + . = (. + 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(.); + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN(4); + } >default_rodata_seg + + _flash_rodata_align = ALIGNOF(.flash.rodata); + + .flash.rodata_noload (NOLOAD) : + { + . = ALIGN (4); + *(.rodata_wlog_debug .rodata_wlog_debug.*) + *(.rodata_wlog_verbose .rodata_wlog_verbose.*) + } > default_rodata_seg + + .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 + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + . = 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(.); + _sheap = ABSOLUTE(.); + } > dram0_0_seg + + . = _heap_end; + _eheap = ABSOLUTE(.); +} + +ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_heap_start - _data_start) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.")