1/*
2 * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#include <zephyr/devicetree.h>
7#include <zephyr/linker/sections.h>
8#include <zephyr/linker/linker-defs.h>
9#include <zephyr/linker/linker-tool.h>
10
11#include "memory.h"
12
13/* Disable all romable LMA */
14#undef GROUP_DATA_LINK_IN
15#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion
16
17/* Aliases for zephyr scripts */
18#define RAMABLE_REGION    dram_seg
19#define RODATA_REGION     dram_seg
20#define ROMABLE_REGION    dram_seg
21
22_bootloader_dram_seg_start = BOOTLOADER_DRAM_SEG_START;
23_bootloader_iram_loader_seg_start = BOOTLOADER_IRAM_LOADER_SEG_START;
24
25MEMORY
26{
27  iram_seg (RWX) :        org = BOOTLOADER_IRAM_SEG_START,
28                          len = BOOTLOADER_IRAM_SEG_LEN
29  iram_loader_seg (RWX) : org = BOOTLOADER_IRAM_LOADER_SEG_START,
30                          len = BOOTLOADER_IRAM_LOADER_SEG_LEN
31  dram_seg (RW) :         org = BOOTLOADER_DRAM_SEG_START,
32                          len = BOOTLOADER_DRAM_SEG_LEN
33
34#ifdef CONFIG_GEN_ISR_TABLES
35  IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
36#endif
37}
38
39/*  Default entry point:  */
40ENTRY(CONFIG_KERNEL_ENTRY)
41
42SECTIONS
43{
44  .iram0.loader_text :
45  {
46    _loader_text_start = ABSOLUTE(.);
47    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
48
49    *libarch__xtensa__core.a:xtensa_asm2_util.*(.literal .text .literal.* .text.*)
50    *liblib__libc__common.a:abort.*(.literal .text .literal.* .text.*)
51    *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*)
52    *libarch__common.a:dynamic_isr.*(.literal .text .literal.* .text.*)
53    *libarch__common.a:sw_isr_common.*(.literal .text .literal.* .text.*)
54
55    *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*)
56    *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out)
57    *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*)
58    *libzephyr.a:cpu.*(.literal .text .literal.* .text.*)
59    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
60    *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*)
61    *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*)
62
63    *libzephyr.a:heap.*(.literal .text .literal.* .text.*)
64
65    *libkernel.a:kheap.*(.literal .text .literal.* .text.*)
66    *libkernel.a:mempool.*(.literal .text .literal.* .text.*)
67    *libkernel.a:device.*(.literal .text .literal.* .text.*)
68    *libkernel.a:timeout.*(.literal .text .literal.* .text.*)
69
70    *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*)
71    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
72
73    *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*)
74    *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler)
75    *(.literal.esp_log_timestamp .text.esp_log_timestamp)
76    *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp)
77    *(.literal.esp_system_abort .text.esp_system_abort)
78
79    *(.fini.literal)
80    *(.fini)
81    *(.gnu.version)
82
83    /* CPU will try to prefetch up to 16 bytes of
84     * of instructions. This means that any configuration (e.g. MMU, PMS) must allow
85     * safe access to up to 16 bytes after the last real instruction, add
86     * dummy bytes to ensure this
87     */
88    . += 16;
89
90    _text_end = ABSOLUTE(.);
91    _etext = .;
92    . = ALIGN(4);
93    _loader_text_end = ABSOLUTE(.);
94    _iram_text_end = ABSOLUTE(.);
95    _iram_end = ABSOLUTE(.);
96  } > iram_loader_seg
97
98  .iram0.vectors : ALIGN(4)
99  {
100    /* Vectors go to IRAM */
101    _init_start = ABSOLUTE(.);
102    /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
103    . = 0x0;
104    KEEP(*(.WindowVectors.text));
105    . = 0x180;
106    KEEP(*(.Level2InterruptVector.text));
107    . = 0x1c0;
108    KEEP(*(.Level3InterruptVector.text));
109    . = 0x200;
110    KEEP(*(.Level4InterruptVector.text));
111    . = 0x240;
112    KEEP(*(.Level5InterruptVector.text));
113    . = 0x280;
114    KEEP(*(.DebugExceptionVector.text));
115    . = 0x2c0;
116    KEEP(*(.NMIExceptionVector.text));
117    . = 0x300;
118    KEEP(*(.KernelExceptionVector.text));
119    . = 0x340;
120    KEEP(*(.UserExceptionVector.text));
121    . = 0x3C0;
122    KEEP(*(.DoubleExceptionVector.text));
123    . = 0x400;
124    _invalid_pc_placeholder = ABSOLUTE(.);
125    *(.*Vector.literal)
126
127    *(.UserEnter.literal);
128    *(.UserEnter.text);
129    . = ALIGN (16);
130    *(.entry.text)
131    *(.init.literal)
132    *(.init)
133    . = ALIGN (4);
134    _init_end = ABSOLUTE(.);
135
136    /* This goes here, not at top of linker script, so addr2line finds it last,
137     * and uses it in preference to the first symbol in IRAM
138     */
139    _iram_start = ABSOLUTE(.);
140  } > iram_seg
141
142  .iram0.text :
143  {
144    . = ALIGN(4);
145
146    *(.iram1 .iram1.*)
147    *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
148
149    *(.literal .text .literal.* .text.*)
150    . = ALIGN(4);
151
152    *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
153    . = ALIGN(4);
154  } > iram_seg
155
156  .dram0.data : ALIGN(16)
157  {
158    . = ALIGN(4);
159    __data_start = ABSOLUTE(.);
160
161    #include <snippets-rodata.ld>
162
163    . = ALIGN(4);
164    #include <snippets-rwdata.ld>
165    . = ALIGN(4);
166
167    *(.data)
168    *(.data.*)
169    *(.gnu.linkonce.d.*)
170    *(.data1)
171    *(.sdata)
172    *(.sdata.*)
173    *(.gnu.linkonce.s.*)
174    *(.sdata2)
175    *(.sdata2.*)
176    *(.gnu.linkonce.s2.*)
177    *libzephyr.a:mmu_hal.*(.rodata .rodata.*)
178    *libzephyr.a:rtc_clk.*(.rodata .rodata.*)
179
180    KEEP(*(.jcr))
181    *(.dram1 .dram1.*)
182    . = ALIGN(4);
183    *(.rodata)
184    *(.rodata.*)
185
186    *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
187    *(.gnu.linkonce.r.*)
188    *(.rodata1)
189    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
190    *(.xt_except_table)
191    *(.gcc_except_table .gcc_except_table.*)
192    *(.gnu.linkonce.e.*)
193    *(.gnu.version_r)
194    . = (. + 3) & ~ 3;
195    __eh_frame = ABSOLUTE(.);
196    KEEP(*(.eh_frame))
197    . = (. + 7) & ~ 3;
198
199    /*  C++ exception handlers table:  */
200    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
201    *(.xt_except_desc)
202    *(.gnu.linkonce.h.*)
203    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
204    *(.xt_except_desc_end)
205    *(.dynamic)
206    *(.gnu.version_d)
207    . = ALIGN(4);
208    __rodata_region_end = ABSOLUTE(.);
209    /* Literals are also RO data. */
210    _lit4_start = ABSOLUTE(.);
211    *(*.lit4)
212    *(.lit4.*)
213    *(.gnu.linkonce.lit4.*)
214    _lit4_end = ABSOLUTE(.);
215    . = ALIGN(4);
216    *(.rodata_wlog)
217    *(.rodata_wlog*)
218    _thread_local_end = ABSOLUTE(.);
219    . = ALIGN(4);
220  } > dram_seg
221
222  #include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
223  #include <zephyr/linker/common-rom/common-rom-debug.ld>
224  #include <zephyr/linker/common-rom/common-rom-misc.ld>
225  #include <snippets-sections.ld>
226
227  #include <zephyr/linker/cplusplus-rom.ld>
228  #include <snippets-data-sections.ld>
229  #include <zephyr/linker/common-ram.ld>
230  #include <snippets-ram-sections.ld>
231  #include <zephyr/linker/cplusplus-ram.ld>
232  #include <zephyr/linker/common-rom/common-rom-logging.ld>
233
234  .noinit (NOLOAD):
235  {
236    . = ALIGN(8);
237    *(.noinit)
238    *(.noinit.*)
239    . = ALIGN(8) ;
240  } > dram_seg
241
242  /* Shared RAM */
243  .bss (NOLOAD):
244  {
245    . = ALIGN (8);
246    _bss_start = ABSOLUTE(.); /* required by bluetooth library */
247    __bss_start = ABSOLUTE(.);
248
249    *(.dynsbss)
250    *(.sbss)
251    *(.sbss.*)
252    *(.gnu.linkonce.sb.*)
253    *(.scommon)
254    *(.sbss2)
255    *(.sbss2.*)
256    *(.gnu.linkonce.sb2.*)
257    *(.dynbss)
258    *(.bss)
259    *(.bss.*)
260    *(.share.mem)
261    *(.gnu.linkonce.b.*)
262    *(COMMON)
263    . = ALIGN (8);
264    __bss_end = ABSOLUTE(.);
265    _bss_end = ABSOLUTE(.);
266    _end = ABSOLUTE(.);
267  } > dram_seg
268
269  ASSERT(((__bss_end - ORIGIN(dram_seg)) <= LENGTH(dram_seg)), "DRAM segment data does not fit.")
270
271#include <zephyr/linker/debug-sections.ld>
272
273  .xtensa.info  0 :  { *(.xtensa.info) }
274  .xt.insn 0 :
275  {
276    KEEP (*(.xt.insn))
277    KEEP (*(.gnu.linkonce.x.*))
278  }
279  .xt.prop 0 :
280  {
281    KEEP (*(.xt.prop))
282    KEEP (*(.xt.prop.*))
283    KEEP (*(.gnu.linkonce.prop.*))
284  }
285  .xt.lit 0 :
286  {
287    KEEP (*(.xt.lit))
288    KEEP (*(.xt.lit.*))
289    KEEP (*(.gnu.linkonce.p.*))
290  }
291  .xt.profile_range 0 :
292  {
293    KEEP (*(.xt.profile_range))
294    KEEP (*(.gnu.linkonce.profile_range.*))
295  }
296  .xt.profile_ranges 0 :
297  {
298    KEEP (*(.xt.profile_ranges))
299    KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
300  }
301  .xt.profile_files 0 :
302  {
303    KEEP (*(.xt.profile_files))
304    KEEP (*(.gnu.linkonce.xt.profile_files.*))
305  }
306
307#ifdef CONFIG_GEN_ISR_TABLES
308#include <zephyr/linker/intlist.ld>
309#endif
310}
311