1/* 2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/* Default entry point */ 8ENTRY(call_start_cpu0); 9 10SECTIONS 11{ 12 .iram0.text : 13 { 14 _iram_start = ABSOLUTE(.); 15 /* Vectors go to start of IRAM */ 16 ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); 17 KEEP(*(.exception_vectors.text)); 18 . = ALIGN(4); 19 20 _invalid_pc_placeholder = ABSOLUTE(.); 21 22 /* Code marked as running out of IRAM */ 23 _iram_text_start = ABSOLUTE(.); 24 25 mapping[iram0_text] 26 27 } > iram0_0_seg 28 29 /** 30 * This section is required to skip .iram0.text area because iram0_0_seg and 31 * dram0_0_seg reflect the same address space on different buses. 32 */ 33 .dram0.dummy (NOLOAD): 34 { 35 . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; 36 } > dram0_0_seg 37 38 /** 39 * This section MUST be placed at the beginning of the DRAM0, 40 * which will be released along with iram0_bt.text when Bluetooth is no longer in use 41 */ 42 .dram0.bt.data : 43 { 44 _data_start = ABSOLUTE(.); 45 mapping[dram0_bt_data] 46 . = ALIGN(8); 47 } > dram0_0_seg 48 49 .dram0.bt.bss (NOLOAD) : 50 { 51 . = ALIGN (8); 52 _bss_bt_start = ABSOLUTE(.); 53 mapping[dram0_bt_bss] 54 _bss_bt_end = ABSOLUTE(.); 55 } > dram0_0_seg 56 57 .dram0.data : 58 { 59 *(.gnu.linkonce.d.*) 60 *(.data1) 61 __global_pointer$ = . + 0x800; 62 *(.sdata) 63 *(.sdata.*) 64 *(.gnu.linkonce.s.*) 65 *(.gnu.linkonce.s2.*) 66 *(.jcr) 67 68 mapping[dram0_data] 69 70 _data_end = ABSOLUTE(.); 71 . = ALIGN(4); 72 } > dram0_0_seg 73 74 /** 75 * This section holds data that should not be initialized at power up. 76 * The section located in Internal SRAM memory region. The macro _NOINIT 77 * can be used as attribute to place data into this section. 78 * See the "esp_attr.h" file for more information. 79 */ 80 .noinit (NOLOAD): 81 { 82 . = ALIGN(4); 83 _noinit_start = ABSOLUTE(.); 84 *(.noinit .noinit.*) 85 . = ALIGN(4) ; 86 _noinit_end = ABSOLUTE(.); 87 } > dram0_0_seg 88 89 /* Shared RAM */ 90 .dram0.bss (NOLOAD) : 91 { 92 . = ALIGN (8); 93 _bss_start = ABSOLUTE(.); 94 95 mapping[dram0_bss] 96 97 *(.dynsbss) 98 *(.sbss) 99 *(.sbss.*) 100 *(.gnu.linkonce.sb.*) 101 *(.scommon) 102 *(.sbss2) 103 *(.sbss2.*) 104 *(.gnu.linkonce.sb2.*) 105 *(.dynbss) 106 *(.share.mem) 107 *(.gnu.linkonce.b.*) 108 109 . = ALIGN (8); 110 _bss_end = ABSOLUTE(.); 111 } > dram0_0_seg 112 113 ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") 114 115 .flash.text : 116 { 117 _stext = .; 118 _instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */ 119 _text_start = ABSOLUTE(.); 120 121 mapping[flash_text] 122 123 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 124 *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ 125 *(.fini.literal) 126 *(.fini) 127 *(.gnu.version) 128 129 /** CPU will try to prefetch up to 16 bytes of 130 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 131 * safe access to up to 16 bytes after the last real instruction, add 132 * dummy bytes to ensure this 133 */ 134 . += _esp_flash_mmap_prefetch_pad_size; 135 136 _text_end = ABSOLUTE(.); 137 _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ 138 _etext = .; 139 140 /** 141 * Similar to _iram_start, this symbol goes here so it is 142 * resolved by addr2line in preference to the first symbol in 143 * the flash.text segment. 144 */ 145 _flash_cache_start = ABSOLUTE(0); 146 } > default_code_seg 147 148 /** 149 * This dummy section represents the .flash.text section but in default_rodata_seg. 150 * Thus, it must have its alignment and (at least) its size. 151 */ 152 .flash_rodata_dummy (NOLOAD): 153 { 154 _flash_rodata_dummy_start = .; 155 /* Start at the same alignment constraint than .flash.text */ 156 . = ALIGN(ALIGNOF(.flash.text)); 157 /* Create an empty gap as big as .flash.text section */ 158 . = . + SIZEOF(.flash.text); 159 /* Prepare the alignment of the section above. Few bytes (0x20) must be 160 * added for the mapping header. */ 161 . = ALIGN(_esp_mmu_block_size) + 0x20; 162 } > default_rodata_seg 163 164 .flash.appdesc : ALIGN(0x10) 165 { 166 _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ 167 _rodata_start = ABSOLUTE(.); 168 169 *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ 170 *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ 171 172 /* Create an empty gap within this section. Thanks to this, the end of this 173 * section will match .flash.rodata's begin address. Thus, both sections 174 * will be merged when creating the final bin image. */ 175 . = ALIGN(ALIGNOF(.flash.rodata)); 176 } >default_rodata_seg 177 178 .flash.rodata : ALIGN(0x10) 179 { 180 _flash_rodata_start = ABSOLUTE(.); 181 182 mapping[flash_rodata] 183 184 *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ 185 *(.gnu.linkonce.r.*) 186 *(.rodata1) 187 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 188 *(.xt_except_table) 189 *(.gcc_except_table .gcc_except_table.*) 190 *(.gnu.linkonce.e.*) 191 *(.gnu.version_r) 192 . = (. + 7) & ~ 3; 193 /* 194 * C++ constructor and destructor tables 195 * Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt. 196 * 197 * RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead. 198 * But the init_priority sections will be sorted for iteration in ascending order during startup. 199 * The rest of the init_array sections is sorted for iteration in descending order during startup, however. 200 * Hence a different section is generated for the init_priority functions which is iterated in 201 * ascending order during startup. The corresponding code can be found in startup.c. 202 */ 203 __init_priority_array_start = ABSOLUTE(.); 204 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) 205 __init_priority_array_end = ABSOLUTE(.); 206 __init_array_start = ABSOLUTE(.); 207 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) 208 __init_array_end = ABSOLUTE(.); 209 KEEP (*crtbegin.*(.dtors)) 210 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 211 KEEP (*(SORT(.dtors.*))) 212 KEEP (*(.dtors)) 213 /* C++ exception handlers table: */ 214 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 215 *(.xt_except_desc) 216 *(.gnu.linkonce.h.*) 217 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 218 *(.xt_except_desc_end) 219 *(.dynamic) 220 *(.gnu.version_d) 221 /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ 222 soc_reserved_memory_region_start = ABSOLUTE(.); 223 KEEP (*(.reserved_memory_address)) 224 soc_reserved_memory_region_end = ABSOLUTE(.); 225 /* System init functions registered via ESP_SYSTEM_INIT_FN */ 226 _esp_system_init_fn_array_start = ABSOLUTE(.); 227 KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) 228 _esp_system_init_fn_array_end = ABSOLUTE(.); 229 _rodata_end = ABSOLUTE(.); 230 /* Literals are also RO data. */ 231 _lit4_start = ABSOLUTE(.); 232 *(*.lit4) 233 *(.lit4.*) 234 *(.gnu.linkonce.lit4.*) 235 _lit4_end = ABSOLUTE(.); 236 . = ALIGN(4); 237 _thread_local_start = ABSOLUTE(.); 238 *(.tdata) 239 *(.tdata.*) 240 *(.tbss) 241 *(.tbss.*) 242 _thread_local_end = ABSOLUTE(.); 243 . = ALIGN(ALIGNOF(.eh_frame)); 244 } > default_rodata_seg 245 246 /* Keep this section shall be at least aligned on 4 */ 247 .eh_frame : ALIGN(8) 248 { 249 __eh_frame = ABSOLUTE(.); 250 KEEP (*(.eh_frame)) 251 __eh_frame_end = ABSOLUTE(.); 252 /* Guarantee that this section and the next one will be merged by making 253 * them adjacent. */ 254 . = ALIGN(ALIGNOF(.eh_frame_hdr)); 255 } > default_rodata_seg 256 257 /* To avoid any exception in C++ exception frame unwinding code, this section 258 * shall be aligned on 8. */ 259 .eh_frame_hdr : ALIGN(8) 260 { 261 __eh_frame_hdr = ABSOLUTE(.); 262 KEEP (*(.eh_frame_hdr)) 263 __eh_frame_hdr_end = ABSOLUTE(.); 264 } > default_rodata_seg 265 266 /* 267 This section is a place where we dump all the rodata which aren't used at runtime, 268 so as to avoid binary size increase 269 */ 270 .flash.rodata_noload (NOLOAD) : 271 { 272 /* 273 This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address 274 We don't need to include the noload rodata in this section 275 */ 276 _rodata_reserved_end = ABSOLUTE(.); 277 . = ALIGN (4); 278 mapping[rodata_noload] 279 } > default_rodata_seg 280 281 /* Marks the end of IRAM code segment */ 282 .iram0.text_end (NOLOAD) : 283 { 284 /* ESP32-C2 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ 285 . += _esp_memprot_prefetch_pad_size; 286 . = ALIGN(_esp_memprot_align_size); 287 /* iram_end_test section exists for use by memprot unit tests only */ 288 *(.iram_end_test) 289 _iram_text_end = ABSOLUTE(.); 290 } > iram0_0_seg 291 292 .iram0.data : 293 { 294 . = ALIGN(16); 295 _iram_data_start = ABSOLUTE(.); 296 297 mapping[iram0_data] 298 299 _iram_data_end = ABSOLUTE(.); 300 } > iram0_0_seg 301 302 .iram0.bss (NOLOAD) : 303 { 304 . = ALIGN(16); 305 _iram_bss_start = ABSOLUTE(.); 306 307 mapping[iram0_bss] 308 309 _iram_bss_end = ABSOLUTE(.); 310 } > iram0_0_seg 311 312 /** 313 * This section needs to be placed at the end of the IRAM0, 314 * which will be released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no longer in use 315 */ 316 .iram0.bt.text : 317 { 318 . = ALIGN(16); 319 _iram_bt_text_start = ABSOLUTE(.); 320 mapping[iram0_bt_text] 321 322 . = ALIGN(16); 323 _iram_end = ABSOLUTE(.); 324 } > iram0_0_seg 325 326 /* Marks the end of data, bss and possibly rodata */ 327 .dram0.heap_start (NOLOAD) : 328 { 329 . = ALIGN (16); 330 _heap_start = ABSOLUTE(.); 331 } > dram0_0_seg 332} 333 334ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), 335 "IRAM0 segment data does not fit.") 336 337ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), 338 "DRAM segment data does not fit.") 339