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