1/* 2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6/** Simplified memory map for the bootloader. 7 * Make sure the bootloader can load into main memory without overwriting itself. 8 * 9 * ESP32-C3 ROM static data usage is as follows: 10 * - 0x3fccae00 - 0x3fcdc710: Shared buffers, used in UART/USB/SPI download mode only 11 * - 0x3fcdc710 - 0x3fcde710: PRO CPU stack, can be reclaimed as heap after RTOS startup 12 * - 0x3fcde710 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) 13 * 14 * The 2nd stage bootloader can take space up to the end of ROM shared 15 * buffers area (0x3fcdc710). 16 */ 17 18/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ 19iram_dram_offset = 0x700000; 20 21/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, 22 * and work out iram_seg and iram_loader_seg addresses from there, backwards. 23 */ 24 25/* These lengths can be adjusted, if necessary: */ 26bootloader_usable_dram_end = 0x3fcdc710; 27bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ 28bootloader_dram_seg_len = 0x5000; 29bootloader_iram_loader_seg_len = 0x7000; 30bootloader_iram_seg_len = 0x2000; 31 32/* Start of the lower region is determined by region size and the end of the higher region */ 33bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; 34bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; 35bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; 36bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; 37 38MEMORY 39{ 40 iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len 41 iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len 42 dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len 43} 44 45/* The app may use RAM for static allocations up to the start of iram_loader_seg. 46 * If you have changed something above and this assert fails: 47 * 1. Check what the new value of bootloader_iram_loader_seg start is. 48 * 2. Update the value in this assert. 49 * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c3/memory.ld.in to the same value. 50 */ 51ASSERT(bootloader_iram_loader_seg_start == 0x403ce710, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); 52 53/* Default entry point: */ 54ENTRY(call_start_cpu0); 55 56SECTIONS 57{ 58 59 .iram_loader.text : 60 { 61 . = ALIGN (16); 62 _loader_text_start = ABSOLUTE(.); 63 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 64 *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ 65 *liblog.a:(.literal .text .literal.* .text.*) 66 *libgcc.a:(.literal .text .literal.* .text.*) 67 *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) 68 *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) 69 *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) 70 *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) 71 *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) 72 *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) 73 *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) 74 *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) 75 *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) 76 *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) 77 *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) 78 *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) 79 *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) 80 *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) 81 *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) 82 *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) 83 *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) 84 *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) 85 *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) 86 *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) 87 *libspi_flash.a:*.*(.literal .text .literal.* .text.*) 88 *libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) 89 *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) 90 *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) 91 *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) 92 *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) 93 *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) 94 *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) 95 *libefuse.a:*.*(.literal .text .literal.* .text.*) 96 *(.fini.literal) 97 *(.fini) 98 *(.gnu.version) 99 _loader_text_end = ABSOLUTE(.); 100 } > iram_loader_seg 101 102 .iram.text : 103 { 104 . = ALIGN (16); 105 *(.entry.text) 106 *(.init.literal) 107 *(.init) 108 } > iram_seg 109 110 111 /* Shared RAM */ 112 .dram0.bss (NOLOAD) : 113 { 114 . = ALIGN (8); 115 _dram_start = ABSOLUTE(.); 116 _bss_start = ABSOLUTE(.); 117 *(.dynsbss) 118 *(.sbss) 119 *(.sbss.*) 120 *(.gnu.linkonce.sb.*) 121 *(.scommon) 122 *(.sbss2) 123 *(.sbss2.*) 124 *(.gnu.linkonce.sb2.*) 125 *(.dynbss) 126 *(.bss) 127 *(.bss.*) 128 *(.gnu.linkonce.b.*) 129 *(COMMON) 130 . = ALIGN (8); 131 _bss_end = ABSOLUTE(.); 132 } > dram_seg 133 134 .dram0.data : 135 { 136 _data_start = ABSOLUTE(.); 137 *(.data) 138 *(.data.*) 139 *(.gnu.linkonce.d.*) 140 *(.data1) 141 *(.sdata) 142 *(.sdata.*) 143 *(.gnu.linkonce.s.*) 144 *(.gnu.linkonce.s2.*) 145 *(.jcr) 146 _data_end = ABSOLUTE(.); 147 } > dram_seg 148 149 .dram0.rodata : 150 { 151 _rodata_start = ABSOLUTE(.); 152 *(.rodata) 153 *(.rodata.*) 154 *(.gnu.linkonce.r.*) 155 *(.rodata1) 156 *(.sdata2 .sdata2.* .srodata .srodata.*) 157 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 158 *(.xt_except_table) 159 *(.gcc_except_table) 160 *(.gnu.linkonce.e.*) 161 *(.gnu.version_r) 162 *(.eh_frame) 163 . = (. + 3) & ~ 3; 164 /* C++ constructor and destructor tables, properly ordered: */ 165 __init_array_start = ABSOLUTE(.); 166 KEEP (*crtbegin.*(.ctors)) 167 KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) 168 KEEP (*(SORT(.ctors.*))) 169 KEEP (*(.ctors)) 170 __init_array_end = ABSOLUTE(.); 171 KEEP (*crtbegin.*(.dtors)) 172 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 173 KEEP (*(SORT(.dtors.*))) 174 KEEP (*(.dtors)) 175 /* C++ exception handlers table: */ 176 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 177 *(.xt_except_desc) 178 *(.gnu.linkonce.h.*) 179 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 180 *(.xt_except_desc_end) 181 *(.dynamic) 182 *(.gnu.version_d) 183 _rodata_end = ABSOLUTE(.); 184 /* Literals are also RO data. */ 185 _lit4_start = ABSOLUTE(.); 186 *(*.lit4) 187 *(.lit4.*) 188 *(.gnu.linkonce.lit4.*) 189 _lit4_end = ABSOLUTE(.); 190 . = ALIGN(4); 191 _dram_end = ABSOLUTE(.); 192 } > dram_seg 193 194 .iram.text : 195 { 196 _stext = .; 197 _text_start = ABSOLUTE(.); 198 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 199 *(.iram .iram.*) /* catch stray IRAM_ATTR */ 200 *(.fini.literal) 201 *(.fini) 202 *(.gnu.version) 203 204 /** CPU will try to prefetch up to 16 bytes of 205 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 206 * safe access to up to 16 bytes after the last real instruction, add 207 * dummy bytes to ensure this 208 */ 209 . += 16; 210 211 _text_end = ABSOLUTE(.); 212 _etext = .; 213 } > iram_seg 214 215} 216 217 218/** 219 * Appendix: Memory Usage of ROM bootloader 220 * 221 * 0x3fccae00 ------------------> _dram0_0_start 222 * | | 223 * | | 224 * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h 225 * | | 226 * | | 227 * 0x3fcdc710 ------------------> __stack_sentry 228 * | | 229 * | | 2. Startup pro cpu stack (freed when IDF app is running) 230 * | | 231 * 0x3fcde710 ------------------> __stack (pro cpu) 232 * | | 233 * | | 234 * | | 3. Shared memory only used in startup code or nonos/early boot* 235 * | | (can be freed when IDF runs) 236 * | | 237 * | | 238 * 0x3fcdf060 ------------------> _dram0_rtos_reserved_start 239 * | | 240 * | | 241 * | | 4. Shared memory used in startup code and when IDF runs 242 * | | 243 * | | 244 * 0x3fcdf664 ------------------> _dram0_rtos_reserved_end 245 * | | 246 * 0x3fcdf830 ------------------> _data_start_interface 247 * | | 248 * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) 249 * | | 250 * 0x3fce0000 ------------------> _data_end_interface 251 */ 252