1/*
2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6/** Simplified memory map for the bootloader.
7 *  Make sure the bootloader can load into main memory without overwriting itself.
8 *
9 *  ESP32-S3 ROM static data usage is as follows:
10 *  - 0x3fcd7e00 - 0x3fce9704: Shared buffers, used in UART/USB/SPI download mode only
11 *  - 0x3fce9710 - 0x3fceb710: PRO CPU stack, can be reclaimed as heap after RTOS startup
12 *  - 0x3fceb710 - 0x3fced710: APP CPU stack, can be reclaimed as heap after RTOS startup
13 *  - 0x3fced710 - 0x3fcf0000: ROM .bss and .data (not easily reclaimable)
14 *
15 *  The 2nd stage bootloader can take space up to the end of ROM shared
16 *  buffers area (0x3fce9704). For alignment purpose we shall use value (0x3fce9700).
17 */
18
19/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
20iram_dram_offset = 0x6f0000;
21
22/* We consider 0x3fce9700 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
23 * and work out iram_seg and iram_loader_seg addresses from there, backwards.
24 */
25
26/* These lengths can be adjusted, if necessary: */
27bootloader_usable_dram_end = 0x3fce9700;
28bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
29bootloader_dram_seg_len = 0x4000;
30bootloader_iram_loader_seg_len = 0x7000;
31bootloader_iram_seg_len = 0x3000;
32
33/* Start of the lower region is determined by region size and the end of the higher region */
34bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
35bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
36bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset;
37bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
38
39MEMORY
40{
41  iram_seg (RWX) :                  org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
42  iram_loader_seg (RWX) :           org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
43  dram_seg (RW) :                   org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
44}
45
46/* The app may use RAM for static allocations up to the start of iram_loader_seg.
47 * If you have changed something above and this assert fails:
48 * 1. Check what the new value of bootloader_iram_loader_seg start is.
49 * 2. Update the value in this assert.
50 * 3. Update SRAM_IRAM_END in components/esp_system/ld/esp32s3/memory.ld.in to the same value.
51 */
52ASSERT(bootloader_iram_loader_seg_start == 0x403cc700, "bootloader_iram_loader_seg_start inconsistent with SRAM_IRAM_END");
53
54/* Default entry point: */
55ENTRY(call_start_cpu0);
56
57SECTIONS
58{
59
60  .iram_loader.text :
61  {
62    . = ALIGN (16);
63    _loader_text_start = ABSOLUTE(.);
64    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
65     *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
66    *liblog.a:(.literal .text .literal.* .text.*)
67    *libgcc.a:(.literal .text .literal.* .text.*)
68    *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
69    *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
70    *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
71    *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
72    *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable)
73    *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random)
74    *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*)
75    *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
76    *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
77    *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
78    *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
79    *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
80    *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
81    *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
82    *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
83    *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
84    *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
85    *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*)
86    *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
87    *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
88    *libspi_flash.a:*.*(.literal .text .literal.* .text.*)
89    *libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
90    *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*)
91    *libhal.a:cache_hal.*(.literal .text .literal.* .text.*)
92    *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*)
93    *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*)
94    *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*)
95    *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*)
96    *libefuse.a:*.*(.literal .text .literal.* .text.*)
97    *(.fini.literal)
98    *(.fini)
99    *(.gnu.version)
100    _loader_text_end = ABSOLUTE(.);
101  } > iram_loader_seg
102
103  .iram.text :
104  {
105    . = ALIGN (16);
106    *(.entry.text)
107    *(.init.literal)
108    *(.init)
109  } > iram_seg
110
111
112  /* Shared RAM */
113  .dram0.bss (NOLOAD) :
114  {
115    . = ALIGN (8);
116    _dram_start = ABSOLUTE(.);
117    _bss_start = ABSOLUTE(.);
118    *(.dynsbss)
119    *(.sbss)
120    *(.sbss.*)
121    *(.gnu.linkonce.sb.*)
122    *(.scommon)
123    *(.sbss2)
124    *(.sbss2.*)
125    *(.gnu.linkonce.sb2.*)
126    *(.dynbss)
127    *(.bss)
128    *(.bss.*)
129    *(.gnu.linkonce.b.*)
130    *(COMMON)
131    . = ALIGN (8);
132    _bss_end = ABSOLUTE(.);
133  } > dram_seg
134
135  .dram0.data :
136  {
137    _data_start = ABSOLUTE(.);
138    *(.data)
139    *(.data.*)
140    *(.gnu.linkonce.d.*)
141    *(.data1)
142    *(.sdata)
143    *(.sdata.*)
144    *(.gnu.linkonce.s.*)
145    *(.gnu.linkonce.s2.*)
146    *(.jcr)
147    _data_end = ABSOLUTE(.);
148  } > dram_seg
149
150  .dram0.rodata :
151  {
152    _rodata_start = ABSOLUTE(.);
153    *(.rodata)
154    *(.rodata.*)
155    *(.gnu.linkonce.r.*)
156    *(.rodata1)
157    *(.sdata2 .sdata2.*)
158    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
159    *(.xt_except_table)
160    *(.gcc_except_table)
161    *(.gnu.linkonce.e.*)
162    *(.gnu.version_r)
163    *(.eh_frame)
164    . = (. + 3) & ~ 3;
165    /* C++ constructor and destructor tables, properly ordered: */
166    __init_array_start = ABSOLUTE(.);
167    KEEP (*crtbegin.*(.ctors))
168    KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
169    KEEP (*(SORT(.ctors.*)))
170    KEEP (*(.ctors))
171    __init_array_end = ABSOLUTE(.);
172    KEEP (*crtbegin.*(.dtors))
173    KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
174    KEEP (*(SORT(.dtors.*)))
175    KEEP (*(.dtors))
176    /*  C++ exception handlers table:  */
177    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
178    *(.xt_except_desc)
179    *(.gnu.linkonce.h.*)
180    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
181    *(.xt_except_desc_end)
182    *(.dynamic)
183    *(.gnu.version_d)
184    _rodata_end = ABSOLUTE(.);
185	  /* Literals are also RO data. */
186    _lit4_start = ABSOLUTE(.);
187    *(*.lit4)
188    *(.lit4.*)
189    *(.gnu.linkonce.lit4.*)
190    _lit4_end = ABSOLUTE(.);
191    . = ALIGN(4);
192    _dram_end = ABSOLUTE(.);
193  } > dram_seg
194
195  .iram.text :
196  {
197    _stext = .;
198    _text_start = ABSOLUTE(.);
199    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
200    *(.iram .iram.*) /* catch stray IRAM_ATTR */
201    *(.fini.literal)
202    *(.fini)
203    *(.gnu.version)
204
205    /** CPU will try to prefetch up to 16 bytes of
206      * of instructions. This means that any configuration (e.g. MMU, PMS) must allow
207      * safe access to up to 16 bytes after the last real instruction, add
208      * dummy bytes to ensure this
209      */
210    . += 16;
211
212    _text_end = ABSOLUTE(.);
213    _etext = .;
214  } > iram_seg
215
216  /** This section will be used by the debugger and disassembler to get more information
217   * about raw data present in the code.
218   * Indeed, it may be required to add some padding at some points in the code
219   * in order to align a branch/jump destination on a particular bound.
220   * Padding these instructions will generate null bytes that shall be
221   * interpreted as data, and not code by the debugger or disassembler.
222   * This section will only be present in the ELF file, not in the final binary
223   * For more details, check GCC-212
224   */
225  .xt.prop 0 :
226  {
227    KEEP (*(.xt.prop .gnu.linkonce.prop.*))
228  }
229
230  .xt.lit 0 :
231  {
232    KEEP (*(.xt.lit .gnu.linkonce.p.*))
233  }
234
235}
236
237/**
238 *  Appendix: Memory Usage of ROM bootloader
239 *
240 * 0x3fcd7e00 ------------------> _dram0_0_start
241 *            |               |
242 *            |               |
243 *            |               |   1. Large buffers that are only used in certain boot modes, see shared_buffers.h
244 *            |               |
245 *            |               |
246 * 0x3fce9710 ------------------> __stack_sentry
247 *            |               |
248 *            |               |   2. Startup pro cpu stack (freed when IDF app is running)
249 *            |               |
250 * 0x3fceb710 ------------------> __stack (pro cpu)
251 *            |               |
252 *            |               |      Startup app cpu stack
253 *            |               |
254 * 0x3fced710 ------------------> __stack_app (app cpu)
255 *            |               |
256 *            |               |
257 *            |               |   3. Shared memory only used in startup code or nonos/early boot*
258 *            |               |      (can be freed when IDF runs)
259 *            |               |
260 *            |               |
261 * 0x3fceee34 ------------------> _dram0_rtos_reserved_start
262 *            |               |
263 *            |               |
264 *            |               |   4. Shared memory used in startup code and when IDF runs
265 *            |               |
266 *            |               |
267 * 0x3fcef770 ------------------> _dram0_rtos_reserved_end
268 *            |               |
269 * 0x3fcef81c ------------------> _data_start_interface
270 *            |               |
271 *            |               |   5. End of DRAM is the 'interface' data with constant addresses (ECO compatible)
272 *            |               |
273 * 0x3fcf0000 ------------------> _data_end_interface
274 */
275