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