/* * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * * ESP32-C2 ROM static data usage is as follows: * - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only * - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup * - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) * * The 2nd stage bootloader can take space up to the end of ROM shared * buffers area (0x3fcdcb70). */ /* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ iram_dram_offset = 0x6e0000; /* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, * and work out iram_seg and iram_loader_seg addresses from there, backwards. */ /* These lengths can be adjusted, if necessary: */ bootloader_usable_dram_end = 0x3fcdcb70; bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ bootloader_dram_seg_len = 0xA000; bootloader_iram_loader_seg_len = 0x7000; bootloader_iram_seg_len = 0x8800; /* Start of the lower region is determined by region size and the end of the higher region */ bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; MEMORY { iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len } /* The app may use RAM for static allocations up to the start of iram_loader_seg. * If you have changed something above and this assert fails: * 1. Check what the new value of bootloader_iram_loader_seg start is. * 2. Update the value in this assert. * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value. */ ASSERT(bootloader_iram_loader_seg_start == 0x403a9b70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); /* Default entry point: */ ENTRY(main); SECTIONS { .iram_loader.text : { . = ALIGN (16); _loader_text_start = ABSOLUTE(.); *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ *libhal.a:*.*(.literal .text .literal.* .text.*) *esp_mcuboot.*(.literal .text .literal.* .text.*) *esp_loader.*(.literal .text .literal.* .text.*) *main.*(.literal .text .literal.* .text.*) *(.fini.literal) *(.fini) *(.gnu.version) _loader_text_end = ABSOLUTE(.); } > iram_loader_seg .iram.text : { . = ALIGN (16); *(.entry.text) *(.init.literal) *(.init) } > iram_seg /* Shared RAM */ .dram0.bss (NOLOAD) : { . = ALIGN (8); _dram_start = ABSOLUTE(.); _bss_start = ABSOLUTE(.); *(.dynsbss) *(.sbss) *(.sbss.*) *(.gnu.linkonce.sb.*) *(.scommon) *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) *(.dynbss) *(.bss) *(.bss.*) *(.gnu.linkonce.b.*) *(COMMON) . = ALIGN (8); _bss_end = ABSOLUTE(.); } >dram_seg .dram0.data : { _data_start = ABSOLUTE(.); *(.data) *(.data.*) *(.gnu.linkonce.d.*) *(.data1) *(.sdata) *(.sdata.*) *(.gnu.linkonce.s.*) *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) *(.jcr) _data_end = ABSOLUTE(.); } >dram_seg .dram0.rodata : { _rodata_start = ABSOLUTE(.); *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) *(.rodata1) __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); *(.xt_except_table) *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ __init_array_start = ABSOLUTE(.); KEEP (*crtbegin.*(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.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) _rodata_end = ABSOLUTE(.); /* Literals are also RO data. */ _lit4_start = ABSOLUTE(.); *(*.lit4) *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); . = ALIGN(4); _dram_end = ABSOLUTE(.); } >dram_seg .iram.text : { _stext = .; _text_start = ABSOLUTE(.); *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.iram .iram.*) /* catch stray IRAM_ATTR */ *(.fini.literal) *(.fini) *(.gnu.version) _text_end = ABSOLUTE(.); _etext = .; } > iram_seg }