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
22MEMORY
23{
24  iram_seg (RWX) :        org = BOOTLOADER_IRAM_SEG_START,
25                          len = BOOTLOADER_IRAM_SEG_LEN
26  iram_loader_seg (RWX) : org = BOOTLOADER_IRAM_LOADER_SEG_START,
27                          len = BOOTLOADER_IRAM_LOADER_SEG_LEN
28  dram_seg (RW) :         org = BOOTLOADER_DRAM_SEG_START,
29                          len = BOOTLOADER_DRAM_SEG_LEN
30
31#ifdef CONFIG_GEN_ISR_TABLES
32  IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
33#endif
34}
35
36/*  Default entry point:  */
37ENTRY(CONFIG_KERNEL_ENTRY)
38
39SECTIONS
40{
41  .iram0.loader_text :
42  {
43    _loader_text_start = ABSOLUTE(.);
44    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
45
46    *libarch__xtensa__core.a:xtensa_asm2_util.*(.literal .text .literal.* .text.*)
47    *liblib__libc__common.a:abort.*(.literal .text .literal.* .text.*)
48    *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*)
49    *libarch__common.a:dynamic_isr.*(.literal .text .literal.* .text.*)
50    *libarch__common.a:sw_isr_common.*(.literal .text .literal.* .text.*)
51
52    *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*)
53    *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out)
54    *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*)
55    *libzephyr.a:cpu.*(.literal .text .literal.* .text.*)
56    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
57    *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*)
58    *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*)
59    *libzephyr.a:heap.*(.literal .text .literal.* .text.*)
60    *libkernel.a:kheap.*(.literal .text .literal.* .text.*)
61    *libkernel.a:mempool.*(.literal .text .literal.* .text.*)
62    *libkernel.a:device.*(.literal .text .literal.* .text.*)
63    *libkernel.a:timeout.*(.literal .text .literal.* .text.*)
64    *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*)
65    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
66    *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*)
67    *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*)
68    *libzephyr.a:rtc_clk_init.*(.literal .literal.* .text .text.*)
69
70    *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*)
71    *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler)
72    *(.literal.esp_log_timestamp .text.esp_log_timestamp)
73    *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp)
74    *(.literal.esp_system_abort .text.esp_system_abort)
75
76    *(.fini.literal)
77    *(.fini)
78    *(.gnu.version)
79
80    /* CPU will try to prefetch up to 16 bytes of
81     * of instructions. This means that any configuration (e.g. MMU, PMS) must allow
82     * safe access to up to 16 bytes after the last real instruction, add
83     * dummy bytes to ensure this
84     */
85    . = ALIGN(4) + 16;
86  } > iram_loader_seg
87
88  .iram0.vectors : ALIGN(4)
89  {
90    _iram_start = ABSOLUTE(.);
91    /* Vectors go to IRAM */
92    _init_start = ABSOLUTE(.);
93    /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
94    . = 0x0;
95    KEEP(*(.WindowVectors.text));
96    . = 0x180;
97    KEEP(*(.Level2InterruptVector.text));
98    . = 0x1c0;
99    KEEP(*(.Level3InterruptVector.text));
100    . = 0x200;
101    KEEP(*(.Level4InterruptVector.text));
102    . = 0x240;
103    KEEP(*(.Level5InterruptVector.text));
104    . = 0x280;
105    KEEP(*(.DebugExceptionVector.text));
106    . = 0x2c0;
107    KEEP(*(.NMIExceptionVector.text));
108    . = 0x300;
109    KEEP(*(.KernelExceptionVector.text));
110    . = 0x340;
111    KEEP(*(.UserExceptionVector.text));
112    . = 0x3C0;
113    KEEP(*(.DoubleExceptionVector.text));
114    . = 0x400;
115    _invalid_pc_placeholder = ABSOLUTE(.);
116    *(.*Vector.literal)
117
118    *(.UserEnter.literal);
119    *(.UserEnter.text);
120    . = ALIGN (16);
121    *(.entry.text)
122    *(.init.literal)
123    *(.init)
124    _init_end = ABSOLUTE(.);
125
126    _iram_start = ABSOLUTE(.);
127  } > iram_seg
128
129  .iram0.text :
130  {
131    . = ALIGN(4);
132
133    *(.iram1 .iram1.*)
134    *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
135
136    *(.literal .text .literal.* .text.*)
137    . = ALIGN(4);
138
139    *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
140    . = ALIGN(4);
141  } > iram_seg
142
143  .dram.rodata :
144  {
145    __rodata_region_start = ABSOLUTE(.);
146
147    . = ALIGN(4);
148    #include <snippets-rodata.ld>
149    . = ALIGN(4);
150
151    *(.rodata)
152    *(.rodata.*)
153
154    *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
155    *(.gnu.linkonce.r.*)
156    *(.rodata1)
157    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
158    *(.xt_except_table)
159    *(.gcc_except_table .gcc_except_table.*)
160    *(.gnu.linkonce.e.*)
161    *(.gnu.version_r)
162    . = (. + 3) & ~ 3;
163    __eh_frame = ABSOLUTE(.);
164    KEEP(*(.eh_frame))
165    . = (. + 7) & ~ 3;
166
167    /*  C++ exception handlers table:  */
168    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
169    *(.xt_except_desc)
170    *(.gnu.linkonce.h.*)
171    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
172    *(.xt_except_desc_end)
173    *(.dynamic)
174    *(.gnu.version_d)
175    . = ALIGN(4);
176    __rodata_region_end = ABSOLUTE(.);
177    /* Literals are also RO data. */
178    _lit4_start = ABSOLUTE(.);
179    *(*.lit4)
180    *(.lit4.*)
181    *(.gnu.linkonce.lit4.*)
182    _lit4_end = ABSOLUTE(.);
183    . = ALIGN(4);
184    _thread_local_start = ABSOLUTE(.);
185    *(.tdata)
186    *(.tdata.*)
187    *(.tbss)
188    *(.tbss.*)
189    *(.rodata_wlog)
190    *(.rodata_wlog*)
191    _thread_local_end = ABSOLUTE(.);
192    . = ALIGN(4);
193  } > dram_seg
194
195  #include <zephyr/linker/common-rom/common-rom-init.ld>
196  #include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
197  #include <zephyr/linker/common-rom/common-rom-debug.ld>
198  #include <zephyr/linker/common-rom/common-rom-misc.ld>
199  #include <snippets-sections.ld>
200
201  .dram0.data :
202  {
203    __data_start = ABSOLUTE(.);
204
205    . = ALIGN(4);
206    #include <snippets-rwdata.ld>
207    . = ALIGN(4);
208
209    *(.data)
210    *(.data.*)
211    *(.gnu.linkonce.d.*)
212    *(.data1)
213    *(.sdata)
214    *(.sdata.*)
215    *(.gnu.linkonce.s.*)
216    *(.sdata2)
217    *(.sdata2.*)
218    *(.gnu.linkonce.s2.*)
219    *libzephyr.a:mmu_hal.*(.rodata .rodata.*)
220    *libzephyr.a:rtc_clk.*(.rodata .rodata.*)
221
222    KEEP(*(.jcr))
223    *(.dram1 .dram1.*)
224    . = ALIGN(4);
225  } > dram_seg
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(.);
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