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