blob: 5177229630d1ddbf066034a4994d29b852ae4264 [file] [log] [blame]
Simon Glass67aadc12024-09-26 14:28:51 +02001.. SPDX-License-Identifier: GPL-2.0-or-later
2
3Memory Management
Neha Malcom Francis5a560512025-03-19 19:33:27 +05304=================
Simon Glass67aadc12024-09-26 14:28:51 +02005
6.. note::
7
8 This information is outdated and needs to be updated.
9
10U-Boot runs in system state and uses physical addresses, i.e. the
11MMU is not used either for address mapping nor for memory protection.
12
13The available memory is mapped to fixed addresses using the
14memory-controller. In this process, a contiguous block is formed for each
15memory type (Flash, SDRAM, SRAM), even when it consists of several
16physical-memory banks.
17
18U-Boot is installed in XIP flash memory, or may be loaded into a lower region of
19RAM by a secondary program loader (SPL). After
20booting and sizing and initialising DRAM, the code relocates itself
21to the upper end of DRAM. Immediately below the U-Boot code some
22memory is reserved for use by malloc() [see CONFIG_SYS_MALLOC_LEN
23configuration setting]. Below that, a structure with global Board-Info
24data is placed, followed by the stack (growing downward).
25
26Additionally, some exception handler code may be copied to the low 8 kB
27of DRAM (0x00000000 ... 0x00001fff).
28
29So a typical memory configuration with 16 MB of DRAM could look like
30this::
31
32 0x0000 0000 Exception Vector code
33 :
34 0x0000 1fff
35 0x0000 2000 Free for Application Use
36 :
37 :
38
39 :
40 :
41 0x00fb ff20 Monitor Stack (Growing downward)
42 0x00fb ffac Board Info Data and permanent copy of global data
43 0x00fc 0000 Malloc Arena
44 :
45 0x00fd ffff
46 0x00fe 0000 RAM Copy of Monitor Code
47 ... eventually: LCD or video framebuffer
48 ... eventually: pRAM (Protected RAM - unchanged by reset)
49 0x00ff ffff [End of RAM]
Neha Malcom Francis5a560512025-03-19 19:33:27 +053050
51System RAM Utilization in U-Boot in ARM
52---------------------------------------
53
54Let us break down the relevant parts of the execution sequence where system RAM
55comes into play. Please note that these are individual pieces of the entire
56boot sequence. It is not exhaustive, rather it aims to show only the pieces
57where the system RAM is modified. See arch/arm/lib/crt0* to understand the
58complete execution sequence.
59
60Also note that the below sequence is not a hard and fast rule on how DRAM usage
61would be and an architecture and board specific analysis is required for the
62exact flow.
63
64SPL Flow
65........
66
67 #. Pre-DRAM
68
69 Prior to setting up of the DRAM, the stack, malloc is defined as below
70 possibly sitting on a smaller readily available memory (SRAM etc.):
71
72 .. image:: pics/spl_before_reloc.svg
73 :alt: contents of ready RAM before relocation in SPL
74
75 Please see CONFIG_SPL_EARLY_BSS if BSS initialization is needed prior
76 to entering board_init_f().
77
78
79 #. DRAM Initialization
80
81 This is typically triggered by board_init_f prior to relocating the stack
82 and the GD (optionally) to the system RAM. DRAM drivers reside in
83 drivers/ram/. Their probe/configuration can be done either via placing the
84 logic in dram_init() or wherever deemed applicable within board_init_f.
85
86 Post board_init_f, spl_relocate_stack_gd() is called to relocate the stack
87 and the GD to the newly initialized DRAM. If CONFIG_SPL_SYS_MALLOC_SIMPLE
88 is set it is also possible to use some amount of this DRAM stack as memory
89 pool for malloc_simple.
90
91 Both of which are an optional move at this point in the sequence. This is
92 still an intermediate environment.
93
94 #. Final Environment Set Up
95
96 The final environment is setup and the system RAM now looks like this:
97
98 .. image:: pics/spl_after_reloc.svg
99 :alt: contents of DRAM after relocation in SPL
100
101 Again stack and gd are an optional move and may still remain in the
102 available RAM (SRAM, locked cache etc.)
103
104U-Boot Proper Flow
105..................
106
107 TODO: this section is still under progress
108
109 #. DRAM Initialization
110
111 This follows the same as in SPL flow. In board_init_f(), a part of memory
112 is reserved at the end of RAM (see reserve_* functions in init_sequence_f)
113
114 #. Code Relocation
115
116 relocate_code() is called which relocates U-Boot code from the current
117 location into the relocation destination in system RAM. Typically it is
118 relocated to the upper portion of the memory. So DRAM now has:
119 * stack
120 * gd
121 * code
122
123 The code relocation happens to the upper portion of the memory after certain
124 portion of memory is reserved. This is memory that is intended to not be
125 "touched" by U-Boot.
126
127 #. Final Environment Set Up
128
129 At this stage we are completely running out of the system RAM with:
130 * stack
131 * gd
132 * code
133 * bss
134 * initialized non-const data
135 * initialized const data
136
137 It is better to do a complete analysis to visualize the layers the system
138 RAM is composed of at the end of this flow. This is entirely dependent on
139 CPU/SoC architecture.
140
141Getting information about system RAM
142....................................
143
144 At boot:
145
146 The prints given by announce_dram_init() and show_dram_config() come up in the
147 boot banner like so::
148
149 DRAM: 2 GiB (total 32 GiB)
150
151 U-Boot supports addressing upto 39-bit. To avoid trying to access higher
152 addresses in systems with > 39-bit addresses, U-Boot caps itself (gd->ram_size)
153 to the first bank. This is also inline with philosophy that U-Boot is a
154 bootloader and not a full-fledged operating system. The first value represents
155 this memory that is available for U-Boot while the "total" value represents the
156 total system RAM available on the device.
157
158 Getting the most basic information on how system RAM has been set up is by
159 running `bdinfo` at U-Boot prompt::
160
161 => bdinfo
162 boot_params = 0x0000000000000000
163 DRAM bank = 0x0000000000000000
164 -> start = 0x0000000080000000
165 -> size = 0x0000000080000000
166 DRAM bank = 0x0000000000000001
167 -> start = 0x0000000880000000
168 -> size = 0x0000000780000000
169 flashstart = 0x0000000000000000
170 flashsize = 0x0000000000000000
171 flashoffset = 0x0000000000000000
172 baudrate = 115200 bps
173 relocaddr = 0x00000000ffec1000
174 reloc off = 0x000000007f6c1000
175 Build = 64-bit
176 current eth = ethernet@46000000port@1
177 ethaddr = 3c:e0:64:62:4b:4e
178 IP addr = <NULL>
179 fdt_blob = 0x00000000fde7df60
180 lmb_dump_all:
181 memory.count = 0x1
182 memory[0] [0x80000000-0xffffffff], 0x80000000 bytes flags: none
183 reserved.count = 0x2
184 reserved[0] [0x9e800000-0xabffffff], 0x0d800000 bytes flags: no-map
185 reserved[1] [0xfce79f50-0xffffffff], 0x031860b0 bytes flags: no-overwrite
186 devicetree = separate
187 serial addr = 0x0000000002880000
188 width = 0x0000000000000000
189 shift = 0x0000000000000002
190 offset = 0x0000000000000000
191 clock = 0x0000000002dc6c00
192 arch_number = 0x0000000000000000
193 TLB addr = 0x00000000ffff0000
194 irq_sp = 0x00000000fde7df50
195 sp start = 0x00000000fde7df50
196 Early malloc usage: 3288 / 8000
197
198
199 Here you are able to see the banks of DDR that have been set up in DRAM bank
200 -> start and -> size as well as the reserved memories in lmb_dump_all.
201
202Testing Memory
203--------------
204
205 Please see doc/README.memory-test