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 10_diram_i_start = 0x40378000; 11 12SECTIONS 13{ 14 /** 15 * RTC fast memory holds RTC wake stub code, 16 * including from any source file named rtc_wake_stub*.c 17 */ 18 .rtc.text : 19 { 20 . = ALIGN(4); 21 _rtc_fast_start = ABSOLUTE(.); 22 _rtc_text_start = ABSOLUTE(.); 23 *(.rtc.entry.text) 24 25 mapping[rtc_text] 26 27 *rtc_wake_stub*.*(.literal .text .literal.* .text.*) 28 *(.rtc_text_end_test) 29 30 /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ 31 . += _esp_memprot_prefetch_pad_size; 32 . = ALIGN(4); 33 34 _rtc_text_end = ABSOLUTE(.); 35 } > rtc_iram_seg 36 37 /** 38 * This section located in RTC FAST Memory area. 39 * It holds data marked with RTC_FAST_ATTR attribute. 40 * See the file "esp_attr.h" for more information. 41 */ 42 .rtc.force_fast : 43 { 44 . = ALIGN(4); 45 _rtc_force_fast_start = ABSOLUTE(.); 46 47 mapping[rtc_force_fast] 48 49 *(.rtc.force_fast .rtc.force_fast.*) 50 . = ALIGN(4) ; 51 _rtc_force_fast_end = ABSOLUTE(.); 52 } > rtc_data_seg 53 54 /** 55 * RTC data section holds RTC wake stub 56 * data/rodata, including from any source file 57 * named rtc_wake_stub*.c and the data marked with 58 * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. 59 * The memory location of the data is dependent on 60 * CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM option. 61 */ 62 .rtc.data : 63 { 64 _rtc_data_start = ABSOLUTE(.); 65 66 mapping[rtc_data] 67 68 *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) 69 _rtc_data_end = ABSOLUTE(.); 70 } > rtc_data_location 71 72 /* RTC bss, from any source file named rtc_wake_stub*.c */ 73 .rtc.bss (NOLOAD) : 74 { 75 _rtc_bss_start = ABSOLUTE(.); 76 *rtc_wake_stub*.*(.bss .bss.*) 77 *rtc_wake_stub*.*(COMMON) 78 79 mapping[rtc_bss] 80 81 _rtc_bss_end = ABSOLUTE(.); 82 } > rtc_data_location 83 84 /** 85 * This section holds data that should not be initialized at power up 86 * and will be retained during deep sleep. 87 * User data marked with RTC_NOINIT_ATTR will be placed 88 * into this section. See the file "esp_attr.h" for more information. 89 * The memory location of the data is dependent on CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM option. 90 */ 91 .rtc_noinit (NOLOAD): 92 { 93 . = ALIGN(4); 94 _rtc_noinit_start = ABSOLUTE(.); 95 *(.rtc_noinit .rtc_noinit.*) 96 . = ALIGN(4) ; 97 _rtc_noinit_end = ABSOLUTE(.); 98 } > rtc_data_location 99 100 /** 101 * This section located in RTC SLOW Memory area. 102 * It holds data marked with RTC_SLOW_ATTR attribute. 103 * See the file "esp_attr.h" for more information. 104 */ 105 .rtc.force_slow : 106 { 107 . = ALIGN(4); 108 _rtc_force_slow_start = ABSOLUTE(.); 109 *(.rtc.force_slow .rtc.force_slow.*) 110 . = ALIGN(4) ; 111 _rtc_force_slow_end = ABSOLUTE(.); 112 } > rtc_slow_seg 113 114 /** 115 * This section holds RTC data that should have fixed addresses. 116 * The data are not initialized at power-up and are retained during deep sleep. 117 */ 118 .rtc_reserved (NOLOAD): 119 { 120 . = ALIGN(4); 121 _rtc_reserved_start = ABSOLUTE(.); 122 /* New data can only be added here to ensure existing data are not moved. 123 Because data have adhered to the end of the segment and code is relied on it. 124 >> put new data here << */ 125 126 *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) 127 KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) 128 _rtc_reserved_end = ABSOLUTE(.); 129 } > rtc_reserved_seg 130 131 _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; 132 ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), 133 "RTC reserved segment data does not fit.") 134 135 /* Get size of rtc slow data based on rtc_data_location alias */ 136 _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 137 ? (_rtc_force_slow_end - _rtc_data_start) 138 : (_rtc_force_slow_end - _rtc_force_slow_start); 139 140 _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 141 ? (_rtc_force_fast_end - _rtc_fast_start) 142 : (_rtc_noinit_end - _rtc_fast_start); 143 144 ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), 145 "RTC_SLOW segment data does not fit.") 146 147 ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), 148 "RTC_FAST segment data does not fit.") 149 150 /* Send .iram0 code to iram */ 151 .iram0.vectors : 152 { 153 _iram_start = ABSOLUTE(.); 154 /* Vectors go to IRAM */ 155 _vector_table = ABSOLUTE(.); 156 . = 0x0; 157 KEEP(*(.WindowVectors.text)); 158 . = 0x180; 159 KEEP(*(.Level2InterruptVector.text)); 160 . = 0x1c0; 161 KEEP(*(.Level3InterruptVector.text)); 162 . = 0x200; 163 KEEP(*(.Level4InterruptVector.text)); 164 . = 0x240; 165 KEEP(*(.Level5InterruptVector.text)); 166 . = 0x280; 167 KEEP(*(.DebugExceptionVector.text)); 168 . = 0x2c0; 169 KEEP(*(.NMIExceptionVector.text)); 170 . = 0x300; 171 KEEP(*(.KernelExceptionVector.text)); 172 . = 0x340; 173 KEEP(*(.UserExceptionVector.text)); 174 . = 0x3C0; 175 KEEP(*(.DoubleExceptionVector.text)); 176 . = 0x400; 177 _invalid_pc_placeholder = ABSOLUTE(.); 178 *(.*Vector.literal) 179 180 *(.UserEnter.literal); 181 *(.UserEnter.text); 182 . = ALIGN (16); 183 *(.entry.text) 184 *(.init.literal) 185 *(.init) 186 _init_end = ABSOLUTE(.); 187 } > iram0_0_seg 188 189 .iram0.text : 190 { 191 /* Code marked as running out of IRAM */ 192 _iram_text_start = ABSOLUTE(.); 193 194 mapping[iram0_text] 195 196 } > iram0_0_seg 197 198 /** 199 * This section is required to skip .iram0.text area because iram0_0_seg and 200 * dram0_0_seg reflect the same address space on different buses. 201 */ 202 .dram0.dummy (NOLOAD): 203 { 204 . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start, 0); 205 } > dram0_0_seg 206 207 .dram0.data : 208 { 209 _data_start = ABSOLUTE(.); 210 *(.gnu.linkonce.d.*) 211 *(.data1) 212 *(.sdata) 213 *(.sdata.*) 214 *(.gnu.linkonce.s.*) 215 *(.gnu.linkonce.s2.*) 216 *(.jcr) 217 218 mapping[dram0_data] 219 220 _data_end = ABSOLUTE(.); 221 . = ALIGN(4); 222 } > dram0_0_seg 223 224 /** 225 * This section holds data that should not be initialized at power up. 226 * The section located in Internal SRAM memory region. The macro _NOINIT 227 * can be used as attribute to place data into this section. 228 * See the "esp_attr.h" file for more information. 229 */ 230 .noinit (NOLOAD): 231 { 232 . = ALIGN(4); 233 _noinit_start = ABSOLUTE(.); 234 *(.noinit .noinit.*) 235 . = ALIGN(4) ; 236 _noinit_end = ABSOLUTE(.); 237 } > dram0_0_seg 238 239 /* Shared RAM */ 240 .dram0.bss (NOLOAD) : 241 { 242 . = ALIGN (8); 243 _bss_start = ABSOLUTE(.); 244 245 mapping[dram0_bss] 246 247 *(.dynsbss) 248 *(.sbss) 249 *(.sbss.*) 250 *(.gnu.linkonce.sb.*) 251 *(.scommon) 252 *(.sbss2) 253 *(.sbss2.*) 254 *(.gnu.linkonce.sb2.*) 255 *(.dynbss) 256 *(.share.mem) 257 *(.gnu.linkonce.b.*) 258 259 . = ALIGN (8); 260 _bss_end = ABSOLUTE(.); 261 } > dram0_0_seg 262 263 ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") 264 265 .flash.text : 266 { 267 _stext = .; 268 _instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */ 269 _text_start = ABSOLUTE(.); 270 271 mapping[flash_text] 272 273 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 274 *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ 275 *(.fini.literal) 276 *(.fini) 277 *(.gnu.version) 278 279 /** CPU will try to prefetch up to 16 bytes of 280 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 281 * safe access to up to 16 bytes after the last real instruction, add 282 * dummy bytes to ensure this 283 */ 284 . += _esp_flash_mmap_prefetch_pad_size; 285 286 _text_end = ABSOLUTE(.); 287 _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ 288 _etext = .; 289 290 /** 291 * Similar to _iram_start, this symbol goes here so it is 292 * resolved by addr2line in preference to the first symbol in 293 * the flash.text segment. 294 */ 295 _flash_cache_start = ABSOLUTE(0); 296 } > default_code_seg 297 298 /** 299 * This dummy section represents the .flash.text section but in default_rodata_seg. 300 * Thus, it must have its alignment and (at least) its size. 301 */ 302 .flash_rodata_dummy (NOLOAD): 303 { 304 _flash_rodata_dummy_start = ABSOLUTE(.); 305 /* Start at the same alignment constraint than .flash.text */ 306 . = ALIGN(ALIGNOF(.flash.text)); 307 /* Create an empty gap as big as .flash.text section */ 308 . = . + SIZEOF(.flash.text); 309 /* Prepare the alignment of the section above. Few bytes (0x20) must be 310 * added for the mapping header. */ 311 . = ALIGN(_esp_mmu_block_size) + 0x20; 312 } > default_rodata_seg 313 314 .flash.appdesc : ALIGN(0x10) 315 { 316 _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ 317 _rodata_start = ABSOLUTE(.); 318 319 *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ 320 *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ 321 322 /* Create an empty gap within this section. Thanks to this, the end of this 323 * section will match .flah.rodata's begin address. Thus, both sections 324 * will be merged when creating the final bin image. */ 325 . = ALIGN(ALIGNOF(.flash.rodata)); 326 } >default_rodata_seg 327 328 .flash.rodata : ALIGN(0x10) 329 { 330 _flash_rodata_start = ABSOLUTE(.); 331 332 mapping[flash_rodata] 333 334 *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ 335 *(.gnu.linkonce.r.*) 336 *(.rodata1) 337 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 338 *(.xt_except_table) 339 *(.gcc_except_table .gcc_except_table.*) 340 *(.gnu.linkonce.e.*) 341 *(.gnu.version_r) 342 . = (. + 3) & ~ 3; 343 __eh_frame = ABSOLUTE(.); 344 KEEP(*(.eh_frame)) 345 . = (. + 7) & ~ 3; 346 /* C++ constructor and destructor tables */ 347 /* Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt */ 348 __init_array_start = ABSOLUTE(.); 349 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) 350 __init_array_end = ABSOLUTE(.); 351 KEEP (*crtbegin.*(.dtors)) 352 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 353 KEEP (*(SORT(.dtors.*))) 354 KEEP (*(.dtors)) 355 /* C++ exception handlers table: */ 356 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 357 *(.xt_except_desc) 358 *(.gnu.linkonce.h.*) 359 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 360 *(.xt_except_desc_end) 361 *(.dynamic) 362 *(.gnu.version_d) 363 /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ 364 soc_reserved_memory_region_start = ABSOLUTE(.); 365 KEEP (*(.reserved_memory_address)) 366 soc_reserved_memory_region_end = ABSOLUTE(.); 367 /* System init functions registered via ESP_SYSTEM_INIT_FN */ 368 _esp_system_init_fn_array_start = ABSOLUTE(.); 369 KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) 370 _esp_system_init_fn_array_end = ABSOLUTE(.); 371 _rodata_end = ABSOLUTE(.); 372 /* Literals are also RO data. */ 373 _lit4_start = ABSOLUTE(.); 374 *(*.lit4) 375 *(.lit4.*) 376 *(.gnu.linkonce.lit4.*) 377 _lit4_end = ABSOLUTE(.); 378 . = ALIGN(4); 379 _thread_local_start = ABSOLUTE(.); 380 *(.tdata) 381 *(.tdata.*) 382 *(.tbss) 383 *(.tbss.*) 384 _thread_local_end = ABSOLUTE(.); 385 . = ALIGN(4); 386 } > default_rodata_seg 387 388 _flash_rodata_align = ALIGNOF(.flash.rodata); 389 390 /* 391 This section is a place where we dump all the rodata which aren't used at runtime, 392 so as to avoid binary size increase 393 */ 394 .flash.rodata_noload (NOLOAD) : 395 { 396 /* 397 This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address 398 We don't need to include the noload rodata in this section 399 */ 400 _rodata_reserved_end = ABSOLUTE(.); 401 . = ALIGN (4); 402 mapping[rodata_noload] 403 } > default_rodata_seg 404 405 /** 406 * This section is required to skip flash rodata sections, because `extern_ram_seg` 407 * and `drom0_0_seg` are on the same bus 408 */ 409 .ext_ram.dummy (NOLOAD): 410 { 411 . = ORIGIN(extern_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); 412 . = ALIGN (0x10000); 413 } > extern_ram_seg 414 415 /* This section holds .ext_ram.bss data, and will be put in PSRAM */ 416 .ext_ram.bss (NOLOAD) : 417 { 418 _ext_ram_bss_start = ABSOLUTE(.); 419 mapping[extern_ram] 420 . = ALIGN(4); 421 _ext_ram_bss_end = ABSOLUTE(.); 422 } > extern_ram_seg 423 424 /** 425 * This section holds data that won't be initialised when startup. 426 * This section locates in External RAM region. 427 */ 428 .ext_ram_noinit (NOLOAD) : 429 { 430 _ext_ram_noinit_start = ABSOLUTE(.); 431 432 *(.ext_ram_noinit*) 433 434 . = ALIGN(4); 435 _ext_ram_noinit_end = ABSOLUTE(.); 436 } > extern_ram_seg 437 438 /* Marks the end of IRAM code segment */ 439 .iram0.text_end (NOLOAD) : 440 { 441 /* iram_end_test section exists for use by memprot unit tests only */ 442 *(.iram_end_test) 443 /* ESP32-S3 memprot requires 16B padding for possible CPU prefetch and 256B alignment for PMS split lines */ 444 . += _esp_memprot_prefetch_pad_size; 445 . = ALIGN(_esp_memprot_align_size); 446 _iram_text_end = ABSOLUTE(.); 447 } > iram0_0_seg 448 449 .iram0.data : 450 { 451 . = ALIGN(4); 452 _iram_data_start = ABSOLUTE(.); 453 454 mapping[iram0_data] 455 456 _iram_data_end = ABSOLUTE(.); 457 } > iram0_0_seg 458 459 .iram0.bss (NOLOAD) : 460 { 461 . = ALIGN(4); 462 _iram_bss_start = ABSOLUTE(.); 463 464 mapping[iram0_bss] 465 466 _iram_bss_end = ABSOLUTE(.); 467 . = ALIGN(4); 468 _iram_end = ABSOLUTE(.); 469 } > iram0_0_seg 470 471 /* Marks the end of data, bss and possibly rodata */ 472 .dram0.heap_start (NOLOAD) : 473 { 474 . = ALIGN (8); 475 /* Lowest possible start address for the heap */ 476 _heap_low_start = ABSOLUTE(.); 477 } > dram0_0_seg 478 479 /** This section will be used by the debugger and disassembler to get more information 480 * about raw data present in the code. 481 * Indeed, it may be required to add some padding at some points in the code 482 * in order to align a branch/jump destination on a particular bound. 483 * Padding these instructions will generate null bytes that shall be 484 * interpreted as data, and not code by the debugger or disassembler. 485 * This section will only be present in the ELF file, not in the final binary 486 * For more details, check GCC-212 487 */ 488 .xt.prop 0 : 489 { 490 KEEP (*(.xt.prop .gnu.linkonce.prop.*)) 491 } 492 493 .xt.lit 0 : 494 { 495 KEEP (*(.xt.lit .gnu.linkonce.p.*)) 496 } 497} 498 499ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), 500 "IRAM0 segment data does not fit.") 501 502ASSERT(((_heap_low_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), 503 "DRAM segment data does not fit.") 504