1/* 2 * SPDX-FileCopyrightText: 2023 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-H2 ROM static data usage is as follows: 11 * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only 12 * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup 13 * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs) 14 * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed) 15 * 16 * The 2nd stage bootloader can take space up to the end of ROM shared 17 * buffers area (0x4084d380). 18 */ 19 20/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, 21 * and work out iram_seg and iram_loader_seg addresses from there, backwards. 22 */ 23 24/* These lengths can be adjusted, if necessary: */ 25bootloader_usable_dram_end = 0x4084cfd0; 26bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ 27bootloader_dram_seg_len = 0xA000; 28bootloader_iram_loader_seg_len = 0x7000; 29bootloader_iram_seg_len = 0x8800; 30 31/* Start of the lower region is determined by region size and the end of the higher region */ 32bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; 33bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; 34bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; 35bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; 36 37MEMORY 38{ 39 iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len 40 iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len 41 dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len 42} 43 44/* The app may use RAM for static allocations up to the start of iram_loader_seg. 45 * If you have changed something above and this assert fails: 46 * 1. Check what the new value of bootloader_iram_loader_seg start is. 47 * 2. Update the value in this assert. 48 * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h2/memory.ld.in to the same value. 49 */ 50ASSERT(bootloader_iram_loader_seg_start == 0x40839FD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); 51 52/* Default entry point: */ 53ENTRY(main); 54 55SECTIONS 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 *libhal.a:*.*(.literal .text .literal.* .text.*) 64 *esp_mcuboot.*(.literal .text .literal.* .text.*) 65 *esp_loader.*(.literal .text .literal.* .text.*) 66 *main.*(.literal .text .literal.* .text.*) 67 *(.fini.literal) 68 *(.fini) 69 *(.gnu.version) 70 _loader_text_end = ABSOLUTE(.); 71 } > iram_loader_seg 72 73 .iram.text : 74 { 75 . = ALIGN (16); 76 *(.entry.text) 77 *(.init.literal) 78 *(.init) 79 } > iram_seg 80 81 82 /* Shared RAM */ 83 .dram0.bss (NOLOAD) : 84 { 85 . = ALIGN (8); 86 _dram_start = ABSOLUTE(.); 87 _bss_start = ABSOLUTE(.); 88 *(.dynsbss) 89 *(.sbss) 90 *(.sbss.*) 91 *(.gnu.linkonce.sb.*) 92 *(.scommon) 93 *(.sbss2) 94 *(.sbss2.*) 95 *(.gnu.linkonce.sb2.*) 96 *(.dynbss) 97 *(.bss) 98 *(.bss.*) 99 *(.gnu.linkonce.b.*) 100 *(COMMON) 101 . = ALIGN (8); 102 _bss_end = ABSOLUTE(.); 103 } >dram_seg 104 105 .dram0.data : 106 { 107 _data_start = ABSOLUTE(.); 108 *(.data) 109 *(.data.*) 110 *(.gnu.linkonce.d.*) 111 *(.data1) 112 *(.sdata) 113 *(.sdata.*) 114 *(.gnu.linkonce.s.*) 115 *(.sdata2) 116 *(.sdata2.*) 117 *(.gnu.linkonce.s2.*) 118 *(.jcr) 119 _data_end = ABSOLUTE(.); 120 } >dram_seg 121 122 .dram0.rodata : 123 { 124 _rodata_start = ABSOLUTE(.); 125 *(.rodata) 126 *(.rodata.*) 127 *(.gnu.linkonce.r.*) 128 *(.rodata1) 129 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 130 *(.xt_except_table) 131 *(.gcc_except_table) 132 *(.gnu.linkonce.e.*) 133 *(.gnu.version_r) 134 *(.eh_frame) 135 . = (. + 3) & ~ 3; 136 /* C++ constructor and destructor tables, properly ordered: */ 137 __init_array_start = ABSOLUTE(.); 138 KEEP (*crtbegin.*(.ctors)) 139 KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) 140 KEEP (*(SORT(.ctors.*))) 141 KEEP (*(.ctors)) 142 __init_array_end = ABSOLUTE(.); 143 KEEP (*crtbegin.*(.dtors)) 144 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 145 KEEP (*(SORT(.dtors.*))) 146 KEEP (*(.dtors)) 147 /* C++ exception handlers table: */ 148 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 149 *(.xt_except_desc) 150 *(.gnu.linkonce.h.*) 151 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 152 *(.xt_except_desc_end) 153 *(.dynamic) 154 *(.gnu.version_d) 155 _rodata_end = ABSOLUTE(.); 156 /* Literals are also RO data. */ 157 _lit4_start = ABSOLUTE(.); 158 *(*.lit4) 159 *(.lit4.*) 160 *(.gnu.linkonce.lit4.*) 161 _lit4_end = ABSOLUTE(.); 162 . = ALIGN(4); 163 _dram_end = ABSOLUTE(.); 164 } >dram_seg 165 166 .iram.text : 167 { 168 _stext = .; 169 _text_start = ABSOLUTE(.); 170 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 171 *(.iram .iram.*) /* catch stray IRAM_ATTR */ 172 *(.fini.literal) 173 *(.fini) 174 *(.gnu.version) 175 _text_end = ABSOLUTE(.); 176 _etext = .; 177 } > iram_seg 178 179} 180