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