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