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