1/*
2 * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/** Simplified memory map for the bootloader.
8 *  Make sure the bootloader can load into main memory without overwriting itself.
9 *
10 *  ESP32-C2 ROM static data usage is as follows:
11 *  - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only
12 *  - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup
13 *  - 0x3fcdeb70 - 0x3fce0000: 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 (0x3fcdcb70).
17 */
18
19/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
20iram_dram_offset = 0x6e0000;
21
22/* We consider 0x3fcdcb70 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 = 0x3fcdcb70;
28bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
29bootloader_dram_seg_len = 0xA000;
30bootloader_iram_loader_seg_len = 0x7000;
31bootloader_iram_seg_len = 0x8800;
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_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value.
51 */
52ASSERT(bootloader_iram_loader_seg_start == 0x403a9b70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
53
54/*  Default entry point:  */
55ENTRY(main);
56
57SECTIONS
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    *libhal.a:*.*(.literal .text .literal.* .text.*)
66    *esp_mcuboot.*(.literal .text .literal.* .text.*)
67    *esp_loader.*(.literal .text .literal.* .text.*)
68    *main.*(.literal .text .literal.* .text.*)
69    *(.fini.literal)
70    *(.fini)
71    *(.gnu.version)
72    _loader_text_end = ABSOLUTE(.);
73  } > iram_loader_seg
74
75  .iram.text :
76  {
77    . = ALIGN (16);
78    *(.entry.text)
79    *(.init.literal)
80    *(.init)
81  } > iram_seg
82
83
84  /* Shared RAM */
85  .dram0.bss (NOLOAD) :
86  {
87    . = ALIGN (8);
88    _dram_start = ABSOLUTE(.);
89    _bss_start = ABSOLUTE(.);
90    *(.dynsbss)
91    *(.sbss)
92    *(.sbss.*)
93    *(.gnu.linkonce.sb.*)
94    *(.scommon)
95    *(.sbss2)
96    *(.sbss2.*)
97    *(.gnu.linkonce.sb2.*)
98    *(.dynbss)
99    *(.bss)
100    *(.bss.*)
101    *(.gnu.linkonce.b.*)
102    *(COMMON)
103    . = ALIGN (8);
104    _bss_end = ABSOLUTE(.);
105  } >dram_seg
106
107  .dram0.data :
108  {
109    _data_start = ABSOLUTE(.);
110    *(.data)
111    *(.data.*)
112    *(.gnu.linkonce.d.*)
113    *(.data1)
114    *(.sdata)
115    *(.sdata.*)
116    *(.gnu.linkonce.s.*)
117    *(.sdata2)
118    *(.sdata2.*)
119    *(.gnu.linkonce.s2.*)
120    *(.jcr)
121    _data_end = ABSOLUTE(.);
122  } >dram_seg
123
124  .dram0.rodata :
125  {
126    _rodata_start = ABSOLUTE(.);
127    *(.rodata)
128    *(.rodata.*)
129    *(.gnu.linkonce.r.*)
130    *(.rodata1)
131    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
132    *(.xt_except_table)
133    *(.gcc_except_table)
134    *(.gnu.linkonce.e.*)
135    *(.gnu.version_r)
136    *(.eh_frame)
137    . = (. + 3) & ~ 3;
138    /*  C++ constructor and destructor tables, properly ordered:  */
139    __init_array_start = ABSOLUTE(.);
140    KEEP (*crtbegin.*(.ctors))
141    KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
142    KEEP (*(SORT(.ctors.*)))
143    KEEP (*(.ctors))
144    __init_array_end = ABSOLUTE(.);
145    KEEP (*crtbegin.*(.dtors))
146    KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
147    KEEP (*(SORT(.dtors.*)))
148    KEEP (*(.dtors))
149    /*  C++ exception handlers table:  */
150    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
151    *(.xt_except_desc)
152    *(.gnu.linkonce.h.*)
153    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
154    *(.xt_except_desc_end)
155    *(.dynamic)
156    *(.gnu.version_d)
157    _rodata_end = ABSOLUTE(.);
158    /* Literals are also RO data. */
159    _lit4_start = ABSOLUTE(.);
160    *(*.lit4)
161    *(.lit4.*)
162    *(.gnu.linkonce.lit4.*)
163    _lit4_end = ABSOLUTE(.);
164    . = ALIGN(4);
165    _dram_end = ABSOLUTE(.);
166  } >dram_seg
167
168  .iram.text :
169  {
170    _stext = .;
171    _text_start = ABSOLUTE(.);
172    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
173    *(.iram .iram.*) /* catch stray IRAM_ATTR */
174    *(.fini.literal)
175    *(.fini)
176    *(.gnu.version)
177    _text_end = ABSOLUTE(.);
178    _etext = .;
179  } > iram_seg
180
181}
182