|
| 1 | +/* |
| 2 | + * SPDX-FileCopyrightText: 2025 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-P4 ROM static data usage is as follows: |
| 11 | + * - 0x4ff296b8 - 0x4ff3afc0: Shared buffers, used in UART/USB/SPI download mode only |
| 12 | + * - 0x4ff3afc0 - 0x4ff3fba4: CPU1 stack, can be reclaimed as heap after RTOS startup |
| 13 | + * - 0x4ff3fba4 - 0x4ff40000: 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: */ |
| 24 | +bootloader_usable_dram_end = 0x4ffbcfc0; |
| 25 | +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ |
| 26 | +bootloader_dram_seg_len = 0x5000; |
| 27 | +bootloader_iram_loader_seg_len = 0x7000; |
| 28 | +bootloader_iram_seg_len = 0x2D00; |
| 29 | + |
| 30 | +/* Start of the lower region is determined by region size and the end of the higher region */ |
| 31 | +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; |
| 32 | +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; |
| 33 | +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; |
| 34 | +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; |
| 35 | + |
| 36 | +MEMORY |
| 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/esp32p4/memory.ld.in to the same value. |
| 48 | + */ |
| 49 | +ASSERT(bootloader_iram_loader_seg_start == 0x4FFAEFC0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); |
| 50 | + |
| 51 | +/* Default entry point: */ |
| 52 | +ENTRY(call_start_cpu0); |
| 53 | + |
| 54 | +SECTIONS |
| 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 | + *libhal.a:key_mgr_hal.*(.literal.key_mgr_hal_set_key_usage .text.key_mgr_hal_set_key_usage) |
| 91 | + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) |
| 92 | + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) |
| 93 | + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) |
| 94 | + *libefuse.a:*.*(.literal .text .literal.* .text.*) |
| 95 | + *libriscv.a:rv_utils.*(.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.bootdesc : ALIGN(0x10) |
| 135 | + { |
| 136 | + _data_start = ABSOLUTE(.); |
| 137 | + *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ |
| 138 | + } > dram_seg |
| 139 | + |
| 140 | + .dram0.data : |
| 141 | + { |
| 142 | + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ |
| 143 | + *(.data) |
| 144 | + *(.data.*) |
| 145 | + *(.gnu.linkonce.d.*) |
| 146 | + *(.data1) |
| 147 | + *(.sdata) |
| 148 | + *(.sdata.*) |
| 149 | + *(.gnu.linkonce.s.*) |
| 150 | + *(.gnu.linkonce.s2.*) |
| 151 | + *(.jcr) |
| 152 | + _data_end = ABSOLUTE(.); |
| 153 | + } > dram_seg |
| 154 | + |
| 155 | + .dram0.rodata : |
| 156 | + { |
| 157 | + _rodata_start = ABSOLUTE(.); |
| 158 | + *(.rodata) |
| 159 | + *(.rodata.*) |
| 160 | + *(.gnu.linkonce.r.*) |
| 161 | + *(.rodata1) |
| 162 | + *(.sdata2 .sdata2.* .srodata .srodata.*) |
| 163 | + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); |
| 164 | + *(.xt_except_table) |
| 165 | + *(.gcc_except_table) |
| 166 | + *(.gnu.linkonce.e.*) |
| 167 | + *(.gnu.version_r) |
| 168 | + *(.eh_frame_hdr) |
| 169 | + *(.eh_frame) |
| 170 | + . = (. + 3) & ~ 3; |
| 171 | + /* C++ constructor and destructor tables, properly ordered: */ |
| 172 | + __init_array_start = ABSOLUTE(.); |
| 173 | + KEEP (*crtbegin.*(.ctors)) |
| 174 | + KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) |
| 175 | + KEEP (*(SORT(.ctors.*))) |
| 176 | + KEEP (*(.ctors)) |
| 177 | + __init_array_end = ABSOLUTE(.); |
| 178 | + KEEP (*crtbegin.*(.dtors)) |
| 179 | + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) |
| 180 | + KEEP (*(SORT(.dtors.*))) |
| 181 | + KEEP (*(.dtors)) |
| 182 | + /* C++ exception handlers table: */ |
| 183 | + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); |
| 184 | + *(.xt_except_desc) |
| 185 | + *(.gnu.linkonce.h.*) |
| 186 | + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); |
| 187 | + *(.xt_except_desc_end) |
| 188 | + *(.dynamic) |
| 189 | + *(.gnu.version_d) |
| 190 | + _rodata_end = ABSOLUTE(.); |
| 191 | + /* Literals are also RO data. */ |
| 192 | + _lit4_start = ABSOLUTE(.); |
| 193 | + *(*.lit4) |
| 194 | + *(.lit4.*) |
| 195 | + *(.gnu.linkonce.lit4.*) |
| 196 | + _lit4_end = ABSOLUTE(.); |
| 197 | + . = ALIGN(4); |
| 198 | + _dram_end = ABSOLUTE(.); |
| 199 | + } > dram_seg |
| 200 | + |
| 201 | + .iram.text : |
| 202 | + { |
| 203 | + _stext = .; |
| 204 | + _text_start = ABSOLUTE(.); |
| 205 | + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) |
| 206 | + *(.iram .iram.*) /* catch stray IRAM_ATTR */ |
| 207 | + *(.fini.literal) |
| 208 | + *(.fini) |
| 209 | + *(.gnu.version) |
| 210 | + |
| 211 | + /** CPU will try to prefetch up to 16 bytes of |
| 212 | + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow |
| 213 | + * safe access to up to 16 bytes after the last real instruction, add |
| 214 | + * dummy bytes to ensure this |
| 215 | + */ |
| 216 | + . += 16; |
| 217 | + |
| 218 | + _text_end = ABSOLUTE(.); |
| 219 | + _etext = .; |
| 220 | + } > iram_seg |
| 221 | + |
| 222 | + .riscv.attributes 0: { *(.riscv.attributes) } |
| 223 | + |
| 224 | + /* DWARF 1 */ |
| 225 | + .debug 0 : { *(.debug) } |
| 226 | + .line 0 : { *(.line) } |
| 227 | + /* GNU DWARF 1 extensions */ |
| 228 | + .debug_srcinfo 0 : { *(.debug_srcinfo) } |
| 229 | + .debug_sfnames 0 : { *(.debug_sfnames) } |
| 230 | + /* DWARF 1.1 and DWARF 2 */ |
| 231 | + .debug_aranges 0 : { *(.debug_aranges) } |
| 232 | + .debug_pubnames 0 : { *(.debug_pubnames) } |
| 233 | + /* DWARF 2 */ |
| 234 | + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } |
| 235 | + .debug_abbrev 0 : { *(.debug_abbrev) } |
| 236 | + .debug_line 0 : { *(.debug_line) } |
| 237 | + .debug_frame 0 : { *(.debug_frame) } |
| 238 | + .debug_str 0 : { *(.debug_str) } |
| 239 | + .debug_loc 0 : { *(.debug_loc) } |
| 240 | + .debug_macinfo 0 : { *(.debug_macinfo) } |
| 241 | + .debug_pubtypes 0 : { *(.debug_pubtypes) } |
| 242 | + /* DWARF 3 */ |
| 243 | + .debug_ranges 0 : { *(.debug_ranges) } |
| 244 | + /* SGI/MIPS DWARF 2 extensions */ |
| 245 | + .debug_weaknames 0 : { *(.debug_weaknames) } |
| 246 | + .debug_funcnames 0 : { *(.debug_funcnames) } |
| 247 | + .debug_typenames 0 : { *(.debug_typenames) } |
| 248 | + .debug_varnames 0 : { *(.debug_varnames) } |
| 249 | + /* GNU DWARF 2 extensions */ |
| 250 | + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } |
| 251 | + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } |
| 252 | + /* DWARF 4 */ |
| 253 | + .debug_types 0 : { *(.debug_types) } |
| 254 | + /* DWARF 5 */ |
| 255 | + .debug_addr 0 : { *(.debug_addr) } |
| 256 | + .debug_line_str 0 : { *(.debug_line_str) } |
| 257 | + .debug_loclists 0 : { *(.debug_loclists) } |
| 258 | + .debug_macro 0 : { *(.debug_macro) } |
| 259 | + .debug_names 0 : { *(.debug_names) } |
| 260 | + .debug_rnglists 0 : { *(.debug_rnglists) } |
| 261 | + .debug_str_offsets 0 : { *(.debug_str_offsets) } |
| 262 | + |
| 263 | + .comment 0 : { *(.comment) } |
| 264 | + .note.GNU-stack 0: { *(.note.GNU-stack) } |
| 265 | + |
| 266 | + /** |
| 267 | + * Discarding .rela.* sections results in the following mapping: |
| 268 | + * .rela.text.* -> .text.* |
| 269 | + * .rela.data.* -> .data.* |
| 270 | + * And so forth... |
| 271 | + */ |
| 272 | + /DISCARD/ : { *(.rela.*) } |
| 273 | + |
| 274 | + /** |
| 275 | + * This section is not included in the binary image; it is only present in the ELF file. |
| 276 | + * It is used to keep certain symbols in the ELF file. |
| 277 | + */ |
| 278 | + .noload 0 (INFO) : |
| 279 | + { |
| 280 | + _noload_keep_in_elf_start = ABSOLUTE(.); |
| 281 | + KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) |
| 282 | + _noload_keep_in_elf_end = ABSOLUTE(.); |
| 283 | + } |
| 284 | +} |
| 285 | + |
| 286 | + |
| 287 | +/** |
| 288 | + * Appendix: Memory Usage of ROM bootloader |
| 289 | + * |
| 290 | + * 0x4ff296b8 ------------------> _dram0_0_start |
| 291 | + * | | |
| 292 | + * | | |
| 293 | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h |
| 294 | + * | | |
| 295 | + * | | |
| 296 | + * 0x4ff3afc0 ------------------> __stack_sentry |
| 297 | + * | | |
| 298 | + * | | 2. Startup pro cpu stack (freed when IDF app is running) |
| 299 | + * | | |
| 300 | + * 0x4ff3cfc0 ------------------> __stack (pro cpu) |
| 301 | + * | | |
| 302 | + * | | Startup app cpu stack |
| 303 | + * | | |
| 304 | + * 0x4ff3efc0 ------------------> __stack_app (app cpu) |
| 305 | + * | | |
| 306 | + * | | |
| 307 | + * | | 3. Shared memory only used in startup code or nonos/early boot* |
| 308 | + * | | (can be freed when IDF runs) |
| 309 | + * | | |
| 310 | + * | | |
| 311 | + * 0x4ff3fba4 ------------------> _dram0_rtos_reserved_start |
| 312 | + * | | |
| 313 | + * | | |
| 314 | + * | | 4. Shared memory used in startup code and when IDF runs |
| 315 | + * | | |
| 316 | + * | | |
| 317 | + * 0x4ff3ff94 ------------------> _dram0_rtos_reserved_end |
| 318 | + * | | |
| 319 | + * 0x4ff3ffc8 ------------------> _data_start_interface |
| 320 | + * | | |
| 321 | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) |
| 322 | + * | | |
| 323 | + * 0x4ff40000 ------------------> _data_end_interface |
| 324 | + */ |
0 commit comments