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