/* This memory map assumes the flash cache is on; the blocks used are excluded from the various memory ranges see: https://github.com/espressif/esp-idf/blob/master/components/soc/src/esp32/soc_memory_layout.c for details */ /* override entry point */ ENTRY(ESP32Reset) /* reserved at the start of DRAM for e.g. teh BT stack */ RESERVE_DRAM = 0; /* reserved at the start of the RTC memories for use by the ULP processor */ RESERVE_RTC_FAST = 0; RESERVE_RTC_SLOW = 0; /* define stack size for both cores */ STACK_SIZE = 8k; /* Specify main memory areas */ MEMORY { reserved_cache_seg : ORIGIN = 0x40070000, len = 64k /* SRAM0; reserved for usage as flash cache*/ vectors_seg ( RX ) : ORIGIN = 0x40080000, len = 1k /* SRAM0 */ iram_seg ( RX ) : ORIGIN = 0x40080400, len = 128k-0x400 /* SRAM0 */ reserved_for_rom_seg : ORIGIN = 0x3FFAE000, len = 8k /* SRAM2; reserved for usage by the ROM */ dram_seg ( RW ) : ORIGIN = 0x3FFB0000 + RESERVE_DRAM, len = 176k - RESERVE_DRAM /* SRAM2+1; first 64kB used by BT if enable */ reserved_for_boot_seg : ORIGIN = 0x3FFDC200, len = 144k /* SRAM1; reserved for static ROM usage; can be used for heap */ /* external flash The 0x20 offset 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).) */ irom_seg ( RX ) : ORIGIN = 0x400D0020, len = 3M - 0x20 drom_seg ( R ) : ORIGIN = 0x3F400020, len = 4M - 0x20 /* RTC fast memory (executable). Persists over deep sleep. Only for core 0 (PRO_CPU) */ rtc_fast_iram_seg(RWX) : ORIGIN = 0x400C0000, len = 8k /* RTC fast memory (same block as above), viewed from data bus. Only for core 0 (PRO_CPU) */ rtc_fast_dram_seg(RW) : ORIGIN = 0x3FF80000 + RESERVE_RTC_FAST, len = 8k - RESERVE_RTC_FAST /* RTC slow memory (data accessible). Persists over deep sleep. */ rtc_slow_seg(RW) : ORIGIN = 0x50000000 + RESERVE_RTC_SLOW, len = 8k - RESERVE_RTC_SLOW /* external memory, including data and text, 4MB is the maximum, if external psram is bigger, paging is required */ psram_seg(RWX) : ORIGIN = 0x3F800000, len = 4M } /* map generic regions to output sections */ INCLUDE "alias.x" /* esp32 specific regions */ SECTIONS { .rtc_fast.text : { . = ALIGN(4); *(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*) } > rtc_fast_iram_seg AT > RODATA /* 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_fast.dummy (NOLOAD) : { _rtc_dummy_start = ABSOLUTE(.); /* needed to make section proper size */ . = SIZEOF(.rtc_fast.text); _rtc_dummy_end = ABSOLUTE(.); /* needed to make section proper size */ } > rtc_fast_dram_seg .rtc_fast.data : { _rtc_fast_data_start = ABSOLUTE(.); . = ALIGN(4); *(.rtc_fast.data .rtc_fast.data.*) _rtc_fast_data_end = ABSOLUTE(.); } > rtc_fast_dram_seg AT > RODATA .rtc_fast.bss (NOLOAD) : { _rtc_fast_bss_start = ABSOLUTE(.); . = ALIGN(4); *(.rtc_fast.bss .rtc_fast.bss.*) _rtc_fast_bss_end = ABSOLUTE(.); } > rtc_fast_dram_seg .rtc_fast.noinit (NOLOAD) : { . = ALIGN(4); *(.rtc_fast.noinit .rtc_fast.noinit.*) } > rtc_fast_dram_seg .rtc_slow.text : { . = ALIGN(4); *(.rtc_slow.literal .rtc_slow.text .rtc_slow.literal.* .rtc_slow.text.*) } > rtc_slow_seg AT > RODATA .rtc_slow.data : { _rtc_slow_data_start = ABSOLUTE(.); . = ALIGN(4); *(.rtc_slow.data .rtc_slow.data.*) _rtc_slow_data_end = ABSOLUTE(.); } > rtc_slow_seg AT > RODATA .rtc_slow.bss (NOLOAD) : { _rtc_slow_bss_start = ABSOLUTE(.); . = ALIGN(4); *(.rtc_slow.bss .rtc_slow.bss.*) _rtc_slow_bss_end = ABSOLUTE(.); } > rtc_slow_seg .rtc_slow.noinit (NOLOAD) : { . = ALIGN(4); *(.rtc_slow.noinit .rtc_slow.noinit.*) } > rtc_slow_seg .external.data : { _external_data_start = ABSOLUTE(.); . = ALIGN(4); *(.external.data .external.data.*) _external_data_end = ABSOLUTE(.); } > psram_seg AT > RODATA .external.bss (NOLOAD) : { _external_bss_start = ABSOLUTE(.); . = ALIGN(4); *(.external.bss .external.bss.*) _external_bss_end = ABSOLUTE(.); } > psram_seg .external.noinit (NOLOAD) : { . = ALIGN(4); *(.external.noinit .external.noinit.*) } > psram_seg /* must be last segment using psram_seg */ .external_heap_start (NOLOAD) : { . = ALIGN (4); _external_heap_start = ABSOLUTE(.); } > psram_seg /* wifi data */ .rwtext.wifi : { . = ALIGN(4); *( .wifi0iram .wifi0iram.*) *( .wifirxiram .wifirxiram.*) *( .iram1 .iram1.*) } > RWTEXT AT > RODATA .data.wifi : { . = ALIGN(4); *( .dram1 .dram1.*) } > RWDATA AT > RODATA } _external_ram_start = ABSOLUTE(ORIGIN(psram_seg)); _external_ram_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg)); _heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)+LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE; _text_heap_end = ABSOLUTE(ORIGIN(iram_seg)+LENGTH(iram_seg)); _external_heap_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg)); _stack_start_cpu1 = _heap_end; _stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE; _stack_start_cpu0 = _stack_end_cpu1; _stack_end_cpu0 = _stack_start_cpu0 + STACK_SIZE; EXTERN(DefaultHandler); EXTERN(WIFI_EVENT); /* Force inclusion of WiFi libraries */ INCLUDE "device.x"