1/* 2 * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** Simplified memory map for the bootloader. 8 * Make sure the bootloader can load into main memory without overwriting itself. 9 * 10 * ESP32-C6 ROM static data usage is as follows: 11 * - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only 12 * - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup 13 * - 0x4087e610 - 0x40880000: ROM .bss and .data (not easily reclaimable) 14 * 15 * The 2nd stage bootloader can take space up to the end of ROM shared 16 * buffers area (0x4087c610). 17 */ 18 19/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, 20 * and work out iram_seg and iram_loader_seg addresses from there, backwards. 21 */ 22 23/* These lengths can be adjusted, if necessary: */ 24bootloader_usable_dram_end = 0x4087c610; 25bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ 26bootloader_dram_seg_len = 0xA000; 27bootloader_iram_loader_seg_len = 0x7000; 28bootloader_iram_seg_len = 0x9000; 29 30/* Start of the lower region is determined by region size and the end of the higher region */ 31bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; /* 0x4087c610 - 0x2000 = 0x4087a610 */ 32bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; /* 0x4087a610 - 0x5000 = 0x40875610 */ 33bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; /* 0x40875610 - 0x7000 = 0x4086e610 */ 34bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; /* 0x4086e610 - 0x3000 = 0x4086b610 */ 35 36MEMORY 37{ 38 iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len 39 iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len 40 dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len 41} 42 43/* The app may use RAM for static allocations up to the start of iram_loader_seg. 44 * If you have changed something above and this assert fails: 45 * 1. Check what the new value of bootloader_iram_loader_seg start is. 46 * 2. Update the value in this assert. 47 * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c6/memory.ld.in to the same value. 48 */ 49ASSERT(bootloader_iram_loader_seg_start == 0x40869610, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); 50 51/* Default entry point: */ 52ENTRY(main); 53 54SECTIONS 55{ 56 .iram_loader.text : 57 { 58 . = ALIGN (16); 59 _loader_text_start = ABSOLUTE(.); 60 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 61 *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ 62 *libhal.a:*.*(.literal .text .literal.* .text.*) 63 *esp_mcuboot.*(.literal .text .literal.* .text.*) 64 *esp_loader.*(.literal .text .literal.* .text.*) 65 *main.*(.literal .text .literal.* .text.*) 66 *(.fini.literal) 67 *(.fini) 68 *(.gnu.version) 69 _loader_text_end = ABSOLUTE(.); 70 } > iram_loader_seg 71 72 .iram.text : 73 { 74 . = ALIGN (16); 75 *(.entry.text) 76 *(.init.literal) 77 *(.init) 78 } > iram_seg 79 80 /* Shared RAM */ 81 .dram0.bss (NOLOAD) : 82 { 83 . = ALIGN (8); 84 _dram_start = ABSOLUTE(.); 85 _bss_start = ABSOLUTE(.); 86 *(.dynsbss) 87 *(.sbss) 88 *(.sbss.*) 89 *(.gnu.linkonce.sb.*) 90 *(.scommon) 91 *(.sbss2) 92 *(.sbss2.*) 93 *(.gnu.linkonce.sb2.*) 94 *(.dynbss) 95 *(.bss) 96 *(.bss.*) 97 *(.gnu.linkonce.b.*) 98 *(COMMON) 99 . = ALIGN (8); 100 _bss_end = ABSOLUTE(.); 101 } >dram_seg 102 103 .dram0.data : 104 { 105 _data_start = ABSOLUTE(.); 106 *(.data) 107 *(.data.*) 108 *(.gnu.linkonce.d.*) 109 *(.data1) 110 *(.sdata) 111 *(.sdata.*) 112 *(.gnu.linkonce.s.*) 113 *(.sdata2) 114 *(.sdata2.*) 115 *(.gnu.linkonce.s2.*) 116 *(.jcr) 117 _data_end = ABSOLUTE(.); 118 } >dram_seg 119 120 .dram0.rodata : 121 { 122 _rodata_start = ABSOLUTE(.); 123 *(.rodata) 124 *(.rodata.*) 125 *(.gnu.linkonce.r.*) 126 *(.rodata1) 127 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 128 *(.xt_except_table) 129 *(.gcc_except_table) 130 *(.gnu.linkonce.e.*) 131 *(.gnu.version_r) 132 *(.eh_frame) 133 . = (. + 3) & ~ 3; 134 /* C++ constructor and destructor tables, properly ordered: */ 135 __init_array_start = ABSOLUTE(.); 136 KEEP (*crtbegin.*(.ctors)) 137 KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) 138 KEEP (*(SORT(.ctors.*))) 139 KEEP (*(.ctors)) 140 __init_array_end = ABSOLUTE(.); 141 KEEP (*crtbegin.*(.dtors)) 142 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 143 KEEP (*(SORT(.dtors.*))) 144 KEEP (*(.dtors)) 145 /* C++ exception handlers table: */ 146 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 147 *(.xt_except_desc) 148 *(.gnu.linkonce.h.*) 149 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 150 *(.xt_except_desc_end) 151 *(.dynamic) 152 *(.gnu.version_d) 153 _rodata_end = ABSOLUTE(.); 154 /* Literals are also RO data. */ 155 _lit4_start = ABSOLUTE(.); 156 *(*.lit4) 157 *(.lit4.*) 158 *(.gnu.linkonce.lit4.*) 159 _lit4_end = ABSOLUTE(.); 160 . = ALIGN(4); 161 _dram_end = ABSOLUTE(.); 162 } >dram_seg 163 164 .iram.text : 165 { 166 _stext = .; 167 _text_start = ABSOLUTE(.); 168 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 169 *(.iram .iram.*) /* catch stray IRAM_ATTR */ 170 *(.fini.literal) 171 *(.fini) 172 *(.gnu.version) 173 _text_end = ABSOLUTE(.); 174 _etext = .; 175 } > iram_seg 176 177} 178