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 /* RTC fast memory holds RTC wake stub code, 13 including from any source file named rtc_wake_stub*.c 14 */ 15 .rtc.text : 16 { 17 _rtc_text_start = ABSOLUTE(.); 18 . = ALIGN(4); 19 20 _rtc_code_start = .; 21 22 mapping[rtc_text] 23 24 *rtc_wake_stub*.*(.literal .text .literal.* .text.*) 25 _rtc_code_end = .; 26 27 /* possibly align + add 16B for CPU dummy speculative instr. fetch */ 28 . = ((_rtc_code_end - _rtc_code_start) == 0) ? ALIGN(0) : ALIGN(4) + 16; 29 30 _rtc_text_end = ABSOLUTE(.); 31 } > rtc_iram_seg 32 33 /* 34 This section is required to skip rtc.text area because rtc_iram_seg and 35 rtc_data_seg are reflect the same address space on different buses. 36 */ 37 .rtc.dummy : 38 { 39 _rtc_dummy_start = ABSOLUTE(.); 40 _rtc_fast_start = ABSOLUTE(.); 41 . = SIZEOF(.rtc.text); 42 _rtc_dummy_end = ABSOLUTE(.); 43 } > rtc_data_seg 44 45 /* This section located in RTC FAST Memory area. 46 It holds data marked with RTC_FAST_ATTR attribute. 47 See the file "esp_attr.h" for more information. 48 */ 49 .rtc.force_fast : 50 { 51 . = ALIGN(4); 52 _rtc_force_fast_start = ABSOLUTE(.); 53 54 mapping[rtc_force_fast] 55 56 *(.rtc.force_fast .rtc.force_fast.*) 57 . = ALIGN(4) ; 58 _rtc_force_fast_end = ABSOLUTE(.); 59 } > rtc_data_seg 60 61 /* RTC data section holds RTC wake stub 62 data/rodata, including from any source file 63 named rtc_wake_stub*.c and the data marked with 64 RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. 65 The memory location of the data is dependent on 66 CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option. 67 */ 68 .rtc.data : 69 { 70 _rtc_data_start = ABSOLUTE(.); 71 72 mapping[rtc_data] 73 74 *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*) 75 _rtc_data_end = ABSOLUTE(.); 76 } > rtc_data_location 77 78 /* RTC bss, from any source file named rtc_wake_stub*.c */ 79 .rtc.bss (NOLOAD) : 80 { 81 _rtc_bss_start = ABSOLUTE(.); 82 *rtc_wake_stub*.*(.bss .bss.*) 83 *rtc_wake_stub*.*(COMMON) 84 85 mapping[rtc_bss] 86 87 _rtc_bss_end = ABSOLUTE(.); 88 } > rtc_data_location 89 90 /* This section holds data that should not be initialized at power up 91 and will be retained during deep sleep. 92 User data marked with RTC_NOINIT_ATTR will be placed 93 into this section. See the file "esp_attr.h" for more information. 94 The memory location of the data is dependent on 95 CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM option. 96 */ 97 .rtc_noinit (NOLOAD): 98 { 99 . = ALIGN(4); 100 _rtc_noinit_start = ABSOLUTE(.); 101 *(.rtc_noinit .rtc_noinit.*) 102 . = ALIGN(4) ; 103 _rtc_noinit_end = ABSOLUTE(.); 104 } > rtc_data_location 105 106 /* This section located in RTC SLOW Memory area. 107 It holds data marked with RTC_SLOW_ATTR attribute. 108 See the file "esp_attr.h" for more information. 109 */ 110 .rtc.force_slow : 111 { 112 . = ALIGN(4); 113 _rtc_force_slow_start = ABSOLUTE(.); 114 *(.rtc.force_slow .rtc.force_slow.*) 115 . = ALIGN(4) ; 116 _rtc_force_slow_end = ABSOLUTE(.); 117 } > rtc_slow_seg 118 119 /* Get size of rtc slow data based on rtc_data_location alias */ 120 _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 121 ? (_rtc_force_slow_end - _rtc_data_start) 122 : (_rtc_force_slow_end - _rtc_force_slow_start); 123 124 _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 125 ? (_rtc_force_fast_end - _rtc_fast_start) 126 : (_rtc_noinit_end - _rtc_fast_start); 127 128 ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), 129 "RTC_SLOW segment data does not fit.") 130 131 ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), 132 "RTC_FAST segment data does not fit.") 133 134 /* Send .iram0 code to iram */ 135 .iram0.vectors : 136 { 137 _iram_start = ABSOLUTE(.); 138 /* Vectors go to IRAM */ 139 _vector_table = ABSOLUTE(.); 140 /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ 141 . = 0x0; 142 KEEP(*(.WindowVectors.text)); 143 . = 0x180; 144 KEEP(*(.Level2InterruptVector.text)); 145 . = 0x1c0; 146 KEEP(*(.Level3InterruptVector.text)); 147 . = 0x200; 148 KEEP(*(.Level4InterruptVector.text)); 149 . = 0x240; 150 KEEP(*(.Level5InterruptVector.text)); 151 . = 0x280; 152 KEEP(*(.DebugExceptionVector.text)); 153 . = 0x2c0; 154 KEEP(*(.NMIExceptionVector.text)); 155 . = 0x300; 156 KEEP(*(.KernelExceptionVector.text)); 157 . = 0x340; 158 KEEP(*(.UserExceptionVector.text)); 159 . = 0x3C0; 160 KEEP(*(.DoubleExceptionVector.text)); 161 . = 0x400; 162 _invalid_pc_placeholder = ABSOLUTE(.); 163 *(.*Vector.literal) 164 165 *(.UserEnter.literal); 166 *(.UserEnter.text); 167 . = ALIGN (16); 168 *(.entry.text) 169 *(.init.literal) 170 *(.init) 171 _init_end = ABSOLUTE(.); 172 } > iram0_0_seg 173 174 .iram0.text : 175 { 176 /* Code marked as runnning out of IRAM */ 177 _iram_text_start = ABSOLUTE(.); 178 179 mapping[iram0_text] 180 181 /* Added to maintain compability, there are no iram0 data section to put 182 * sections:iram_coredump entry defined in espcoredump's linker.lf file */ 183 _coredump_iram_start = 0; 184 _coredump_iram_end = 0; 185 186 /* align + add 16B for CPU dummy speculative instr. fetch */ 187 . = ALIGN(_esp_memprot_align_size) + _esp_memprot_prefetch_pad_size; 188 /* iram_end_test section exists for use by memprot unit tests only */ 189 *(.iram_end_test) 190 _iram_text_end = ABSOLUTE(.); 191 _iram_end = ABSOLUTE(.); 192 } > iram0_0_seg 193 194 .dram0_reserved_for_iram (NOLOAD): 195 { 196 . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; 197 } > dram0_0_seg 198 199 .dram0.data : 200 { 201 _data_start = ABSOLUTE(.); 202 *(.gnu.linkonce.d.*) 203 *(.data1) 204 *(.sdata) 205 *(.sdata.*) 206 *(.gnu.linkonce.s.*) 207 *(.sdata2) 208 *(.sdata2.*) 209 *(.gnu.linkonce.s2.*) 210 *(.jcr) 211 212 _esp_system_init_fn_array_start = ABSOLUTE(.); 213 KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*))) 214 _esp_system_init_fn_array_end = ABSOLUTE(.); 215 216 mapping[dram0_data] 217 218 _data_end = ABSOLUTE(.); 219 . = ALIGN(4); 220 } > dram0_0_seg 221 222 /*This section holds data that should not be initialized at power up. 223 The section located in Internal SRAM memory region. The macro _NOINIT 224 can be used as attribute to place data into this section. 225 See the esp_attr.h file for more information. 226 */ 227 .noinit (NOLOAD): 228 { 229 . = ALIGN(4); 230 _noinit_start = ABSOLUTE(.); 231 *(.noinit .noinit.*) 232 . = ALIGN(4) ; 233 _noinit_end = ABSOLUTE(.); 234 } > dram0_0_seg 235 236 /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ 237 .ext_ram.bss (NOLOAD) : 238 { 239 _ext_ram_bss_start = ABSOLUTE(.); 240 241 mapping[extern_ram] 242 243 . = ALIGN(4); 244 _ext_ram_bss_end = ABSOLUTE(.); 245 } > extern_ram_seg 246 247 /* Shared RAM */ 248 .dram0.bss (NOLOAD) : 249 { 250 . = ALIGN (8); 251 _bss_start = ABSOLUTE(.); 252 *(.ext_ram.bss*) 253 254 mapping[dram0_bss] 255 256 *(.dynsbss) 257 *(.sbss) 258 *(.sbss.*) 259 *(.gnu.linkonce.sb.*) 260 *(.scommon) 261 *(.sbss2) 262 *(.sbss2.*) 263 *(.gnu.linkonce.sb2.*) 264 *(.dynbss) 265 *(.share.mem) 266 *(.gnu.linkonce.b.*) 267 268 . = ALIGN (8); 269 _bss_end = ABSOLUTE(.); 270 } > dram0_0_seg 271 272 .flash.appdesc : ALIGN(0x10) 273 { 274 _rodata_reserved_start = ABSOLUTE(.); 275 _rodata_start = ABSOLUTE(.); 276 277 *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ 278 *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ 279 280 /* Create an empty gap within this section. Thanks to this, the end of this 281 * section will match .flah.rodata's begin address. Thus, both sections 282 * will be merged when creating the final bin image. */ 283 . = ALIGN(ALIGNOF(.flash.rodata)); 284 } >default_rodata_seg 285 286 .flash.rodata : ALIGN(0x10) 287 { 288 _flash_rodata_start = ABSOLUTE(.); 289 290 mapping[flash_rodata] 291 292 *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ 293 *(.gnu.linkonce.r.*) 294 *(.rodata1) 295 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 296 *(.xt_except_table) 297 *(.gcc_except_table .gcc_except_table.*) 298 *(.gnu.linkonce.e.*) 299 *(.gnu.version_r) 300 . = (. + 3) & ~ 3; 301 __eh_frame = ABSOLUTE(.); 302 KEEP(*(.eh_frame)) 303 . = (. + 7) & ~ 3; 304 /* C++ constructor and destructor tables 305 306 Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt 307 */ 308 __init_array_start = ABSOLUTE(.); 309 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) 310 __init_array_end = ABSOLUTE(.); 311 KEEP (*crtbegin.*(.dtors)) 312 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 313 KEEP (*(SORT(.dtors.*))) 314 KEEP (*(.dtors)) 315 /* C++ exception handlers table: */ 316 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 317 *(.xt_except_desc) 318 *(.gnu.linkonce.h.*) 319 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 320 *(.xt_except_desc_end) 321 *(.dynamic) 322 *(.gnu.version_d) 323 /* Addresses of memory regions reserved via 324 SOC_RESERVE_MEMORY_REGION() */ 325 soc_reserved_memory_region_start = ABSOLUTE(.); 326 KEEP (*(.reserved_memory_address)) 327 soc_reserved_memory_region_end = ABSOLUTE(.); 328 _rodata_end = ABSOLUTE(.); 329 /* Literals are also RO data. */ 330 _lit4_start = ABSOLUTE(.); 331 *(*.lit4) 332 *(.lit4.*) 333 *(.gnu.linkonce.lit4.*) 334 _lit4_end = ABSOLUTE(.); 335 . = ALIGN(4); 336 _thread_local_start = ABSOLUTE(.); 337 *(.tdata) 338 *(.tdata.*) 339 *(.tbss) 340 *(.tbss.*) 341 _thread_local_end = ABSOLUTE(.); 342 _rodata_reserved_end = ABSOLUTE(.); 343 . = ALIGN(4); 344 } >default_rodata_seg 345 346 _flash_rodata_align = ALIGNOF(.flash.rodata); 347 348 .flash.rodata_noload (NOLOAD) : 349 { 350 . = ALIGN (4); 351 mapping[rodata_noload] 352 } > default_rodata_seg 353 354 .flash.text : 355 { 356 _stext = .; 357 _instruction_reserved_start = ABSOLUTE(.); 358 _text_start = ABSOLUTE(.); 359 360 mapping[flash_text] 361 362 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 363 *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ 364 *(.fini.literal) 365 *(.fini) 366 *(.gnu.version) 367 368 /** CPU will try to prefetch up to 16 bytes of 369 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 370 * safe access to up to 16 bytes after the last real instruction, add 371 * dummy bytes to ensure this 372 */ 373 . += _esp_flash_mmap_prefetch_pad_size; 374 375 _text_end = ABSOLUTE(.); 376 _instruction_reserved_end = ABSOLUTE(.); 377 _etext = .; 378 379 /* Similar to _iram_start, this symbol goes here so it is 380 resolved by addr2line in preference to the first symbol in 381 the flash.text segment. 382 */ 383 _flash_cache_start = ABSOLUTE(0); 384 } >default_code_seg 385 386 /* Marks the end of IRAM code segment */ 387 .iram0.text_end (NOLOAD) : 388 { 389 . = ALIGN (4); 390 _iram_end = ABSOLUTE(.); 391 } > iram0_0_seg 392 393 /* Marks the end of data, bss and possibly rodata */ 394 .dram0.heap_start (NOLOAD) : 395 { 396 . = ALIGN (8); 397 _heap_start = ABSOLUTE(.); 398 } > dram0_0_seg 399} 400 401ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), 402 "IRAM0 segment data does not fit.") 403 404ASSERT(((_heap_start - _data_start) <= LENGTH(dram0_0_seg)), 405 "DRAM segment data does not fit.") 406