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.* .bss .bss.*) 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 /* Get size of rtc slow data based on rtc_data_location alias */ 113 _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 114 ? (_rtc_force_slow_end - _rtc_data_start) 115 : (_rtc_force_slow_end - _rtc_force_slow_start); 116 117 _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) 118 ? (_rtc_force_fast_end - _rtc_fast_start) 119 : (_rtc_noinit_end - _rtc_fast_start); 120 121 ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), 122 "RTC_SLOW segment data does not fit.") 123 124 ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), 125 "RTC_FAST segment data does not fit.") 126 127 /* Send .iram0 code to iram */ 128 .iram0.vectors : 129 { 130 _iram_start = ABSOLUTE(.); 131 /* Vectors go to IRAM */ 132 _vector_table = ABSOLUTE(.); 133 /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ 134 . = 0x0; 135 KEEP(*(.WindowVectors.text)); 136 . = 0x180; 137 KEEP(*(.Level2InterruptVector.text)); 138 . = 0x1c0; 139 KEEP(*(.Level3InterruptVector.text)); 140 . = 0x200; 141 KEEP(*(.Level4InterruptVector.text)); 142 . = 0x240; 143 KEEP(*(.Level5InterruptVector.text)); 144 . = 0x280; 145 KEEP(*(.DebugExceptionVector.text)); 146 . = 0x2c0; 147 KEEP(*(.NMIExceptionVector.text)); 148 . = 0x300; 149 KEEP(*(.KernelExceptionVector.text)); 150 . = 0x340; 151 KEEP(*(.UserExceptionVector.text)); 152 . = 0x3C0; 153 KEEP(*(.DoubleExceptionVector.text)); 154 . = 0x400; 155 _invalid_pc_placeholder = ABSOLUTE(.); 156 *(.*Vector.literal) 157 158 *(.UserEnter.literal); 159 *(.UserEnter.text); 160 . = ALIGN (16); 161 *(.entry.text) 162 *(.init.literal) 163 *(.init) 164 165 _init_end = ABSOLUTE(.); 166 } > iram0_0_seg 167 168 .iram0.text : 169 { 170 /* Code marked as runnning out of IRAM */ 171 _iram_text_start = ABSOLUTE(.); 172 173 mapping[iram0_text] 174 175 } > iram0_0_seg 176 177 .dram0.data : 178 { 179 _data_start = ABSOLUTE(.); 180 *(.gnu.linkonce.d.*) 181 *(.data1) 182 *(.sdata) 183 *(.sdata.*) 184 *(.gnu.linkonce.s.*) 185 *(.sdata2) 186 *(.sdata2.*) 187 *(.gnu.linkonce.s2.*) 188 *(.jcr) 189 190 _esp_system_init_fn_array_start = ABSOLUTE(.); 191 KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*))) 192 _esp_system_init_fn_array_end = ABSOLUTE(.); 193 194 mapping[dram0_data] 195 196 _data_end = ABSOLUTE(.); 197 . = ALIGN(4); 198 } > dram0_0_seg 199 200 /** 201 * This section holds data that won't be initialised when startup. 202 * This section locates in External RAM region. 203 */ 204 .ext_ram_noinit (NOLOAD) : 205 { 206 _ext_ram_noinit_start = ABSOLUTE(.); 207 *(.ext_ram_noinit*) 208 . = ALIGN(4); 209 _ext_ram_noinit_end = ABSOLUTE(.); 210 } > extern_ram_seg 211 212 /*This section holds data that should not be initialized at power up. 213 The section located in Internal SRAM memory region. The macro _NOINIT 214 can be used as attribute to place data into this section. 215 See the esp_attr.h file for more information. 216 */ 217 .noinit (NOLOAD): 218 { 219 . = ALIGN(4); 220 _noinit_start = ABSOLUTE(.); 221 *(.noinit .noinit.*) 222 . = ALIGN(4) ; 223 _noinit_end = ABSOLUTE(.); 224 } > dram0_0_seg 225 226 /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ 227 .ext_ram.bss (NOLOAD) : 228 { 229 _ext_ram_bss_start = ABSOLUTE(.); 230 231 mapping[extern_ram] 232 233 . = ALIGN(4); 234 _ext_ram_bss_end = ABSOLUTE(.); 235 } > extern_ram_seg 236 237 /* Shared RAM */ 238 .dram0.bss (NOLOAD) : 239 { 240 . = ALIGN (8); 241 _bss_start = ABSOLUTE(.); 242 243 mapping[dram0_bss] 244 245 . = ALIGN (8); 246 _bss_end = ABSOLUTE(.); 247 } > dram0_0_seg 248 249 ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), 250 "DRAM segment data does not fit.") 251 252 .flash.appdesc : ALIGN(0x10) 253 { 254 _rodata_start = ABSOLUTE(.); 255 256 *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ 257 *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ 258 259 /* Create an empty gap within this section. Thanks to this, the end of this 260 * section will match .flah.rodata's begin address. Thus, both sections 261 * will be merged when creating the final bin image. */ 262 . = ALIGN(ALIGNOF(.flash.rodata)); 263 } >default_rodata_seg 264 265 .flash.rodata : ALIGN(0x10) 266 { 267 _flash_rodata_start = ABSOLUTE(.); 268 269 mapping[flash_rodata] 270 271 272 *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ 273 *(.gnu.linkonce.r.*) 274 *(.rodata1) 275 __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); 276 *(.xt_except_table) 277 *(.gcc_except_table .gcc_except_table.*) 278 *(.gnu.linkonce.e.*) 279 *(.gnu.version_r) 280 . = (. + 3) & ~ 3; 281 __eh_frame = ABSOLUTE(.); 282 KEEP(*(.eh_frame)) 283 . = (. + 7) & ~ 3; 284 /* C++ constructor and destructor tables 285 286 Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt 287 */ 288 __init_array_start = ABSOLUTE(.); 289 KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) 290 __init_array_end = ABSOLUTE(.); 291 292 KEEP (*crtbegin.*(.dtors)) 293 KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) 294 KEEP (*(SORT(.dtors.*))) 295 KEEP (*(.dtors)) 296 /* C++ exception handlers table: */ 297 __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); 298 *(.xt_except_desc) 299 *(.gnu.linkonce.h.*) 300 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 301 *(.xt_except_desc_end) 302 *(.dynamic) 303 *(.gnu.version_d) 304 /* Addresses of memory regions reserved via 305 SOC_RESERVE_MEMORY_REGION() */ 306 soc_reserved_memory_region_start = ABSOLUTE(.); 307 KEEP (*(.reserved_memory_address)) 308 soc_reserved_memory_region_end = ABSOLUTE(.); 309 _rodata_end = ABSOLUTE(.); 310 /* Literals are also RO data. */ 311 _lit4_start = ABSOLUTE(.); 312 *(*.lit4) 313 *(.lit4.*) 314 *(.gnu.linkonce.lit4.*) 315 _lit4_end = ABSOLUTE(.); 316 . = ALIGN(4); 317 _thread_local_start = ABSOLUTE(.); 318 *(.tdata) 319 *(.tdata.*) 320 *(.tbss) 321 *(.tbss.*) 322 _thread_local_end = ABSOLUTE(.); 323 . = ALIGN(4); 324 } >default_rodata_seg 325 326 _flash_rodata_align = ALIGNOF(.flash.rodata); 327 328 .flash.rodata_noload (NOLOAD) : 329 { 330 . = ALIGN (4); 331 mapping[rodata_noload] 332 } > default_rodata_seg 333 334 .flash.text : 335 { 336 _stext = .; 337 _text_start = ABSOLUTE(.); 338 339 mapping[flash_text] 340 341 *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 342 *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ 343 *(.fini.literal) 344 *(.fini) 345 *(.gnu.version) 346 347 /** CPU will try to prefetch up to 16 bytes of 348 * of instructions. This means that any configuration (e.g. MMU, PMS) must allow 349 * safe access to up to 16 bytes after the last real instruction, add 350 * dummy bytes to ensure this 351 */ 352 . += _esp_flash_mmap_prefetch_pad_size; 353 354 _text_end = ABSOLUTE(.); 355 _etext = .; 356 357 /* Similar to _iram_start, this symbol goes here so it is 358 resolved by addr2line in preference to the first symbol in 359 the flash.text segment. 360 */ 361 _flash_cache_start = ABSOLUTE(0); 362 } >default_code_seg 363 364 /* Marks the end of IRAM code segment */ 365 .iram0.text_end (NOLOAD) : 366 { 367 . = ALIGN (4); 368 _iram_text_end = ABSOLUTE(.); 369 } > iram0_0_seg 370 371 .iram0.data : 372 { 373 . = ALIGN(4); 374 _iram_data_start = ABSOLUTE(.); 375 376 mapping[iram0_data] 377 378 _iram_data_end = ABSOLUTE(.); 379 } > iram0_0_seg 380 381 .iram0.bss (NOLOAD) : 382 { 383 . = ALIGN(4); 384 _iram_bss_start = ABSOLUTE(.); 385 386 mapping[iram0_bss] 387 388 _iram_bss_end = ABSOLUTE(.); 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_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), 402 "IRAM0 segment data does not fit.") 403 404ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), 405 "DRAM segment data does not fit.") 406