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-C6 ROM static data usage is as follows:
11 *  - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only
12 *  - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup
13 *  - 0x4087e610 - 0x40880000: 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 (0x4087c610).
17 */
18
19/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
20 * and work out iram_seg and iram_loader_seg addresses from there, backwards.
21 */
22
23/* These lengths can be adjusted, if necessary: */
24bootloader_usable_dram_end = 0x4087c610;
25bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
26bootloader_dram_seg_len = 0xA000;
27bootloader_iram_loader_seg_len = 0x7000;
28bootloader_iram_seg_len = 0x9000;
29
30/* Start of the lower region is determined by region size and the end of the higher region */
31bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; /* 0x4087c610 - 0x2000 = 0x4087a610 */
32bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; /* 0x4087a610 - 0x5000 = 0x40875610 */
33bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; /* 0x40875610 - 0x7000 = 0x4086e610 */
34bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; /* 0x4086e610 - 0x3000 = 0x4086b610 */
35
36MEMORY
37{
38  iram_seg (RWX) :                  org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
39  iram_loader_seg (RWX) :           org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
40  dram_seg (RW) :                   org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
41}
42
43/* The app may use RAM for static allocations up to the start of iram_loader_seg.
44 * If you have changed something above and this assert fails:
45 * 1. Check what the new value of bootloader_iram_loader_seg start is.
46 * 2. Update the value in this assert.
47 * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c6/memory.ld.in to the same value.
48 */
49ASSERT(bootloader_iram_loader_seg_start == 0x40869610, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
50
51/*  Default entry point:  */
52ENTRY(main);
53
54SECTIONS
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    *libhal.a:*.*(.literal .text .literal.* .text.*)
63    *esp_mcuboot.*(.literal .text .literal.* .text.*)
64    *esp_loader.*(.literal .text .literal.* .text.*)
65    *main.*(.literal .text .literal.* .text.*)
66    *(.fini.literal)
67    *(.fini)
68    *(.gnu.version)
69    _loader_text_end = ABSOLUTE(.);
70  } > iram_loader_seg
71
72  .iram.text :
73  {
74    . = ALIGN (16);
75    *(.entry.text)
76    *(.init.literal)
77    *(.init)
78  } > iram_seg
79
80  /* Shared RAM */
81  .dram0.bss (NOLOAD) :
82  {
83    . = ALIGN (8);
84    _dram_start = ABSOLUTE(.);
85    _bss_start = ABSOLUTE(.);
86    *(.dynsbss)
87    *(.sbss)
88    *(.sbss.*)
89    *(.gnu.linkonce.sb.*)
90    *(.scommon)
91    *(.sbss2)
92    *(.sbss2.*)
93    *(.gnu.linkonce.sb2.*)
94    *(.dynbss)
95    *(.bss)
96    *(.bss.*)
97    *(.gnu.linkonce.b.*)
98    *(COMMON)
99    . = ALIGN (8);
100    _bss_end = ABSOLUTE(.);
101  } >dram_seg
102
103  .dram0.data :
104  {
105    _data_start = ABSOLUTE(.);
106    *(.data)
107    *(.data.*)
108    *(.gnu.linkonce.d.*)
109    *(.data1)
110    *(.sdata)
111    *(.sdata.*)
112    *(.gnu.linkonce.s.*)
113    *(.sdata2)
114    *(.sdata2.*)
115    *(.gnu.linkonce.s2.*)
116    *(.jcr)
117    _data_end = ABSOLUTE(.);
118  } >dram_seg
119
120  .dram0.rodata :
121  {
122    _rodata_start = ABSOLUTE(.);
123    *(.rodata)
124    *(.rodata.*)
125    *(.gnu.linkonce.r.*)
126    *(.rodata1)
127    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
128    *(.xt_except_table)
129    *(.gcc_except_table)
130    *(.gnu.linkonce.e.*)
131    *(.gnu.version_r)
132    *(.eh_frame)
133    . = (. + 3) & ~ 3;
134    /*  C++ constructor and destructor tables, properly ordered:  */
135    __init_array_start = ABSOLUTE(.);
136    KEEP (*crtbegin.*(.ctors))
137    KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
138    KEEP (*(SORT(.ctors.*)))
139    KEEP (*(.ctors))
140    __init_array_end = ABSOLUTE(.);
141    KEEP (*crtbegin.*(.dtors))
142    KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
143    KEEP (*(SORT(.dtors.*)))
144    KEEP (*(.dtors))
145    /*  C++ exception handlers table:  */
146    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
147    *(.xt_except_desc)
148    *(.gnu.linkonce.h.*)
149    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
150    *(.xt_except_desc_end)
151    *(.dynamic)
152    *(.gnu.version_d)
153    _rodata_end = ABSOLUTE(.);
154    /* Literals are also RO data. */
155    _lit4_start = ABSOLUTE(.);
156    *(*.lit4)
157    *(.lit4.*)
158    *(.gnu.linkonce.lit4.*)
159    _lit4_end = ABSOLUTE(.);
160    . = ALIGN(4);
161    _dram_end = ABSOLUTE(.);
162  } >dram_seg
163
164  .iram.text :
165  {
166    _stext = .;
167    _text_start = ABSOLUTE(.);
168    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
169    *(.iram .iram.*) /* catch stray IRAM_ATTR */
170    *(.fini.literal)
171    *(.fini)
172    *(.gnu.version)
173    _text_end = ABSOLUTE(.);
174    _etext = .;
175  } > iram_seg
176
177}
178