1/* 2 * SPDX-FileCopyrightText: 2022 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 /** 13 * RTC fast memory holds RTC wake stub code, 14 * including from any source file named rtc_wake_stub*.c 15 */ 16 .rtc.text : 17 { 18 . = ALIGN(4); 19 _rtc_fast_start = ABSOLUTE(.); 20 _rtc_text_start = ABSOLUTE(.); 21 *(.rtc.entry.text) 22 23 mapping[rtc_text] 24 25 *rtc_wake_stub*.*(.literal .text .literal.* .text.*) 26 *(.rtc_text_end_test) 27 28 /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ 29 . += _esp_memprot_prefetch_pad_size; 30 . = ALIGN(4); 31 32 _rtc_text_end = ABSOLUTE(.); 33 } > lp_ram_seg 34 35 /** 36 * This section located in RTC FAST Memory area. 37 * It holds data marked with RTC_FAST_ATTR attribute. 38 * See the file "esp_attr.h" for more information. 39 */ 40 .rtc.force_fast : 41 { 42 . = ALIGN(4); 43 _rtc_force_fast_start = ABSOLUTE(.); 44 45 mapping[rtc_force_fast] 46 47 *(.rtc.force_fast .rtc.force_fast.*) 48 . = ALIGN(4) ; 49 _rtc_force_fast_end = ABSOLUTE(.); 50 } > lp_ram_seg 51 52 /** 53 * RTC data section holds RTC wake stub 54 * data/rodata, including from any source file 55 * named rtc_wake_stub*.c and the data marked with 56 * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. 57 */ 58 .rtc.data : 59 { 60 _rtc_data_start = ABSOLUTE(.); 61 62 mapping[rtc_data] 63 64 *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*) 65 _rtc_data_end = ABSOLUTE(.); 66 } > lp_ram_seg 67 68 /* RTC bss, from any source file named rtc_wake_stub*.c */ 69 .rtc.bss (NOLOAD) : 70 { 71 _rtc_bss_start = ABSOLUTE(.); 72 *rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*) 73 *rtc_wake_stub*.*(COMMON) 74 75 mapping[rtc_bss] 76 77 _rtc_bss_end = ABSOLUTE(.); 78 } > lp_ram_seg 79 80 /** 81 * This section holds data that should not be initialized at power up 82 * and will be retained during deep sleep. 83 * User data marked with RTC_NOINIT_ATTR will be placed 84 * into this section. See the file "esp_attr.h" for more information. 85 */ 86 .rtc_noinit (NOLOAD): 87 { 88 . = ALIGN(4); 89 _rtc_noinit_start = ABSOLUTE(.); 90 *(.rtc_noinit .rtc_noinit.*) 91 . = ALIGN(4) ; 92 _rtc_noinit_end = ABSOLUTE(.); 93 } > lp_ram_seg 94 95 /** 96 * This section located in RTC SLOW Memory area. 97 * It holds data marked with RTC_SLOW_ATTR attribute. 98 * See the file "esp_attr.h" for more information. 99 */ 100 .rtc.force_slow : 101 { 102 . = ALIGN(4); 103 _rtc_force_slow_start = ABSOLUTE(.); 104 *(.rtc.force_slow .rtc.force_slow.*) 105 . = ALIGN(4) ; 106 _rtc_force_slow_end = ABSOLUTE(.); 107 } > lp_ram_seg 108 109 /** 110 * This section holds RTC data that should have fixed addresses. 111 * The data are not initialized at power-up and are retained during deep sleep. 112 */ 113 .rtc_reserved (NOLOAD): 114 { 115 . = ALIGN(4); 116 _rtc_reserved_start = ABSOLUTE(.); 117 /* New data can only be added here to ensure existing data are not moved. 118 Because data have adhered to the end of the segment and code is relied on it. 119 >> put new data here << */ 120 121 *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) 122 KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) 123 _rtc_reserved_end = ABSOLUTE(.); 124 } > rtc_reserved_seg 125 126 _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; 127 ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), 128 "RTC reserved segment data does not fit.") 129 130 /* Get size of rtc slow data based on rtc_data_location alias */ 131 _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 132 ? (_rtc_force_slow_end - _rtc_data_start) 133 : (_rtc_force_slow_end - _rtc_force_slow_start); 134 135 _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 136 ? (_rtc_force_fast_end - _rtc_fast_start) 137 : (_rtc_noinit_end - _rtc_fast_start); 138 139 ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), 140 "RTC_SLOW segment data does not fit.") 141 142 ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), 143 "RTC_FAST segment data does not fit.") 144 145 .iram0.text : 146 { 147 _iram_start = ABSOLUTE(.); 148 /* Vectors go to start of IRAM */ 149 ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); 150 KEEP(*(.exception_vectors.text)); 151 . = ALIGN(4); 152 153 _invalid_pc_placeholder = ABSOLUTE(.); 154 155 /* Code marked as running out of IRAM */ 156 _iram_text_start = ABSOLUTE(.); 157 158 mapping[iram0_text] 159 160 } > iram0_0_seg 161 162 /* Marks the end of IRAM code segment */ 163 .iram0.text_end (NOLOAD) : 164 { 165 /* ESP32-H2 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ 166 . += _esp_memprot_prefetch_pad_size; 167 . = ALIGN(_esp_memprot_align_size); 168 /* iram_end_test section exists for use by memprot unit tests only */ 169 *(.iram_end_test) 170 _iram_text_end = ABSOLUTE(.); 171 } > iram0_0_seg 172 173 .iram0.data : 174 { 175 . = ALIGN(16); 176 _iram_data_start = ABSOLUTE(.); 177 178 mapping[iram0_data] 179 180 _iram_data_end = ABSOLUTE(.); 181 } > iram0_0_seg 182 183 .iram0.bss (NOLOAD) : 184 { 185 . = ALIGN(16); 186 _iram_bss_start = ABSOLUTE(.); 187 188 mapping[iram0_bss] 189 190 _iram_bss_end = ABSOLUTE(.); 191 . = ALIGN(16); 192 _iram_end = ABSOLUTE(.); 193 } > iram0_0_seg 194 195 /** 196 * This section is required to skip .iram0.text area because iram0_0_seg and 197 * dram0_0_seg reflect the same address space on different buses. 198 */ 199 .dram0.dummy (NOLOAD): 200 { 201 . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; 202 } > dram0_0_seg 203 204 .dram0.data : 205 { 206 _data_start = ABSOLUTE(.); 207 *(.gnu.linkonce.d.*) 208 *(.data1) 209 __global_pointer$ = . + 0x800; 210 *(.sdata) 211 *(.sdata.*) 212 *(.gnu.linkonce.s.*) 213 *(.gnu.linkonce.s2.*) 214 *(.jcr) 215 216 mapping[dram0_data] 217 218 _data_end = ABSOLUTE(.); 219 . = ALIGN(4); 220 } > dram0_0_seg 221 222 /** 223 * This section holds data that should not be initialized at power up. 224 * The section located in Internal SRAM memory region. The macro _NOINIT 225 * can be used as attribute to place data into this section. 226 * See the "esp_attr.h" file for more information. 227 */ 228 .noinit (NOLOAD): 229 { 230 . = ALIGN(4); 231 _noinit_start = ABSOLUTE(.); 232 *(.noinit .noinit.*) 233 . = ALIGN(4) ; 234 _noinit_end = ABSOLUTE(.); 235 } > dram0_0_seg 236 237 /* Shared RAM */ 238 .dram0.bss (NOLOAD) : 239 { 240 . = ALIGN (8); 241 _bss_start = ABSOLUTE(.); 242 243 mapping[dram0_bss] 244 245 *(.dynsbss) 246 *(.sbss) 247 *(.sbss.*) 248 *(.gnu.linkonce.sb.*) 249 *(.scommon) 250 *(.sbss2) 251 *(.sbss2.*) 252 *(.gnu.linkonce.sb2.*) 253 *(.dynbss) 254 *(.share.mem) 255 *(.gnu.linkonce.b.*) 256 257 . = ALIGN (8); 258 _bss_end = ABSOLUTE(.); 259 } > dram0_0_seg 260 261 ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") 262 263 .flash.text : 264 { 265 _stext = .; 266 _instruction_reserved_start = ABSOLUTE(.); 267 _text_start = ABSOLUTE(.); 268 269 mapping[flash_text] 270 271 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 272 *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ 273 *(.fini.literal) 274 *(.fini) 275 *(.gnu.version) 276 277 /** CPU will try to prefetch up to 16 bytes of 278 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 279 * safe access to up to 16 bytes after the last real instruction, add 280 * dummy bytes to ensure this 281 */ 282 . += _esp_flash_mmap_prefetch_pad_size; 283 284 _text_end = ABSOLUTE(.); 285 _instruction_reserved_end = ABSOLUTE(.); 286 _etext = .; 287 288 /** 289 * Similar to _iram_start, this symbol goes here so it is 290 * resolved by addr2line in preference to the first symbol in 291 * the flash.text segment. 292 */ 293 _flash_cache_start = ABSOLUTE(0); 294 } > default_code_seg 295 296 /** 297 * This dummy section represents the .flash.text section but in default_rodata_seg. 298 * Thus, it must have its alignment and (at least) its size. 299 */ 300 .flash_rodata_dummy (NOLOAD): 301 { 302 _flash_rodata_dummy_start = .; 303 /* Start at the same alignment constraint than .flash.text */ 304 . = ALIGN(ALIGNOF(.flash.text)); 305 /* Create an empty gap as big as .flash.text section */ 306 . = . + SIZEOF(.flash.text); 307 /* Prepare the alignment of the section above. Few bytes (0x20) must be 308 * added for the mapping header. */ 309 . = ALIGN(_esp_mmu_block_size) + 0x20; 310 _rodata_reserved_start = .; 311 } > default_rodata_seg 312 313 .flash.appdesc : ALIGN(0x10) 314 { 315 _rodata_start = ABSOLUTE(.); 316 317 *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ 318 *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ 319 320 /* Create an empty gap within this section. Thanks to this, the end of this 321 * section will match .flash.rodata's begin address. Thus, both sections 322 * will be merged when creating the final bin image. */ 323 . = ALIGN(ALIGNOF(.flash.rodata)); 324 } >default_rodata_seg 325 326 .flash.rodata : ALIGN(0x10) 327 { 328 _flash_rodata_start = ABSOLUTE(.); 329 330 mapping[flash_rodata] 331 332 *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ 333 *(.gnu.linkonce.r.*) 334 *(.rodata1) 335 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 336 *(.xt_except_table) 337 *(.gcc_except_table .gcc_except_table.*) 338 *(.gnu.linkonce.e.*) 339 *(.gnu.version_r) 340 . = (. + 7) & ~ 3; 341 /* 342 * C++ constructor and destructor tables 343 * Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt. 344 * 345 * RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead. 346 * But the init_priority sections will be sorted for iteration in ascending order during startup. 347 * The rest of the init_array sections is sorted for iteration in descending order during startup, however. 348 * Hence a different section is generated for the init_priority functions which is iterated in 349 * ascending order during startup. The corresponding code can be found in startup.c. 350 */ 351 __init_priority_array_start = ABSOLUTE(.); 352 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) 353 __init_priority_array_end = ABSOLUTE(.); 354 __init_array_start = ABSOLUTE(.); 355 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) 356 __init_array_end = ABSOLUTE(.); 357 KEEP (*crtbegin.*(.dtors)) 358 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 359 KEEP (*(SORT(.dtors.*))) 360 KEEP (*(.dtors)) 361 /* C++ exception handlers table: */ 362 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 363 *(.xt_except_desc) 364 *(.gnu.linkonce.h.*) 365 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 366 *(.xt_except_desc_end) 367 *(.dynamic) 368 *(.gnu.version_d) 369 /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ 370 soc_reserved_memory_region_start = ABSOLUTE(.); 371 KEEP (*(.reserved_memory_address)) 372 soc_reserved_memory_region_end = ABSOLUTE(.); 373 _esp_system_init_fn_array_start = ABSOLUTE(.); 374 KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*))) 375 _esp_system_init_fn_array_end = ABSOLUTE(.); 376 _rodata_end = ABSOLUTE(.); 377 /* Literals are also RO data. */ 378 _lit4_start = ABSOLUTE(.); 379 *(*.lit4) 380 *(.lit4.*) 381 *(.gnu.linkonce.lit4.*) 382 _lit4_end = ABSOLUTE(.); 383 . = ALIGN(4); 384 _thread_local_start = ABSOLUTE(.); 385 *(.tdata) 386 *(.tdata.*) 387 *(.tbss) 388 *(.tbss.*) 389 _thread_local_end = ABSOLUTE(.); 390 _rodata_reserved_end = ABSOLUTE(.); 391 . = ALIGN(ALIGNOF(.eh_frame)); 392 } > default_rodata_seg 393 394 /* Keep this section shall be at least aligned on 4 */ 395 .eh_frame : ALIGN(8) 396 { 397 __eh_frame = ABSOLUTE(.); 398 KEEP (*(.eh_frame)) 399 __eh_frame_end = ABSOLUTE(.); 400 /* Guarantee that this section and the next one will be merged by making 401 * them adjacent. */ 402 . = ALIGN(ALIGNOF(.eh_frame_hdr)); 403 } > default_rodata_seg 404 405 /* To avoid any exception in C++ exception frame unwinding code, this section 406 * shall be aligned on 8. */ 407 .eh_frame_hdr : ALIGN(8) 408 { 409 __eh_frame_hdr = ABSOLUTE(.); 410 KEEP (*(.eh_frame_hdr)) 411 __eh_frame_hdr_end = ABSOLUTE(.); 412 } > default_rodata_seg 413 414 .flash.rodata_noload (NOLOAD) : 415 { 416 . = ALIGN (4); 417 mapping[rodata_noload] 418 } > default_rodata_seg 419 420 /* Marks the end of data, bss and possibly rodata */ 421 .dram0.heap_start (NOLOAD) : 422 { 423 . = ALIGN (16); 424 _heap_start = ABSOLUTE(.); 425 } > dram0_0_seg 426} 427 428ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), 429 "IRAM0 segment data does not fit.") 430 431ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), 432 "DRAM segment data does not fit.") 433