blob: f01d562d6f007099bc7937705c549c19d7941efd [file] [log] [blame]
Tom Rini528581e2022-07-14 08:07:41 -04001.. SPDX-License-Identifier: GPL-2.0+:
2
3U-Boot Design Principles
4========================
5
6The 10 Golden Rules of U-Boot design
7------------------------------------
8
9Keep it Small
10^^^^^^^^^^^^^
11
12U-Boot is a Boot Loader, i.e. its primary purpose in the shipping
13system is to load some operating system.
14That means that U-Boot is
15necessary to perform a certain task, but it's nothing you want to
16throw any significant resources at. Typically U-Boot is stored in
17relatively small NOR flash memory, which is expensive
18compared to the much larger NAND devices often used to store the
19operating system and the application.
20
21At the moment, U-Boot supports boards with just 128 KiB ROM or with
22256 KiB NOR flash. We should not easily ignore such configurations -
23they may be the exception in among all the other supported boards,
24but if a design uses such a resource-constrained hardware setup it is
25usually because costs are critical, i. e. because the number of
26manufactured boards might be tens or hundreds of thousands or even
27millions...
28
29A usable and useful configuration of U-Boot, including a basic
30interactive command interpreter, support for download over Ethernet
Tom Rini2180aec2022-07-14 08:07:44 -040031and the capability to program the flash shall fit in no more than 128 KiB.
Tom Rini528581e2022-07-14 08:07:41 -040032
33Keep it Fast
34^^^^^^^^^^^^
35
36The end user is not interested in running U-Boot. In most embedded
Tom Rini2180aec2022-07-14 08:07:44 -040037systems they are not even aware that U-Boot exists. The user wants to
Tom Rini528581e2022-07-14 08:07:41 -040038run some application code, and that as soon as possible after switching
Tom Rini2180aec2022-07-14 08:07:44 -040039on their device.
Tom Rini528581e2022-07-14 08:07:41 -040040
41It is therefore essential that U-Boot is as fast as possible,
42especially that it loads and boots the operating system as fast as possible.
43
44To achieve this, the following design principles shall be followed:
45
46* Enable caches as soon and whenever possible
47
48* Initialize devices only when they are needed within U-Boot, i.e. don't
49 initialize the Ethernet interface(s) unless U-Boot performs a download over
50 Ethernet; don't initialize any IDE or USB devices unless U-Boot actually
51 tries to load files from these, etc. (and don't forget to shut down these
52 devices after using them - otherwise nasty things may happen when you try to
53 boot your OS).
54
55Also, building of U-Boot shall be as fast as possible.
56This makes it easier to run a build for all supported configurations
57or at least for all configurations of a specific architecture,
58which is essential for quality assurance.
59If building is cumbersome and slow, most people will omit
60this important step.
61
62Keep it Simple
63^^^^^^^^^^^^^^
64
65U-Boot is a boot loader, but it is also a tool used for board
Tom Rini2180aec2022-07-14 08:07:44 -040066bring-up, for production testing, and for other activities.
Tom Rini528581e2022-07-14 08:07:41 -040067
68Keep it Portable
69^^^^^^^^^^^^^^^^
70
71U-Boot is a boot loader, but it is also a tool used for board
72bring-up, for production testing, and for other activities that are
73very closely related to hardware development. So far, it has been
74ported to several hundreds of different boards on about 30 different
75processor families - please make sure that any code you add can be
76used on as many different platforms as possible.
77
78Avoid assembly language whenever possible - only the reset code with
79basic CPU initialization, maybe a static DRAM initialization and the C
80stack setup should be in assembly.
81All further initializations should be done in C using assembly/C
82subroutines or inline macros. These functions represent some
83kind of HAL functionality and should be defined consistently on all
84architectures, e.g. basic MMU and cache control, stack pointer manipulation.
85Non-existing functions should expand into empty macros or error codes.
86
87Don't make assumptions about the environment where U-Boot is running.
88It may be communicating with a human operator on directly attached
89serial console, but it may be through a GSM modem as well, or driven
90by some automatic test or control system. So don't output any fancy
91control character sequences or similar.
92
93Keep it Configurable
94^^^^^^^^^^^^^^^^^^^^
95
96Section "Keep it Small" already explains about the size restrictions
97for U-Boot on one side. On the other side, U-Boot is a powerful tool
98with many, many extremely useful features. The maintainer or user of
Tom Rini2180aec2022-07-14 08:07:44 -040099each board will have to decide which features are important to them and
100what shall be included with their specific board configuration to meet
101their current requirements and restrictions.
Tom Rini528581e2022-07-14 08:07:41 -0400102
103Please make sure that it is easy to add or remove features from a
104board configuration, so everybody can make the best use of U-Boot on
Tom Rini2180aec2022-07-14 08:07:44 -0400105their system.
Tom Rini528581e2022-07-14 08:07:41 -0400106
107If a feature is not included, it should not have any residual code
108bloating the build.
109
110Keep it Debuggable
111^^^^^^^^^^^^^^^^^^
112
113Of course debuggable code is a big benefit for all of us contributing
114in one way or another to the development of the U-Boot project. But
115as already mentioned in section "Keep it Portable" above, U-Boot is
116not only a tool in itself, it is often also used for hardware
117bring-up, so debugging U-Boot often means that we don't know if we are
118tracking down a problem in the U-Boot software or in the hardware we
119are running on. Code that is clean and easy to understand and to
120debug is all the more important to many of us.
121
122* One important feature of U-Boot is to enable output to the (usually serial)
123 console as soon as possible in the boot process, even if this causes
124 tradeoffs in other areas like memory footprint.
125
126* All initialization steps shall print some "begin doing this" message before
127 they actually start, and some "done" message when they complete. For example,
128 RAM initialization and size detection may print a "RAM: " before they start,
Tom Rini2180aec2022-07-14 08:07:44 -0400129 and "256 MB\\n" when done. The purpose of this is that you can always see
Tom Rini528581e2022-07-14 08:07:41 -0400130 which initialization step was running if there should be any problem. This
131 is important not only during software development, but also for the service
132 people dealing with broken hardware in the field.
133
134* U-Boot should be debuggable with simple JTAG or BDM equipment. It shall use
135 a simple, single-threaded execution model. Avoid any magic, which could
136 prevent easy debugging even when only 1 or 2 hardware breakpoints are
137 available.
138
139Keep it Usable
140^^^^^^^^^^^^^^
141
142Please always keep in mind that there are at least three different
143groups of users for U-Boot, with completely different expectations
144and requirements:
145
Tom Rini2180aec2022-07-14 08:07:44 -0400146* The end user of an embedded device just wants to run some application; they
147 do not even want to know that U-Boot exists and only rarely interacts with
Tom Rini528581e2022-07-14 08:07:41 -0400148 it (for example to perform a reset to factory default settings etc.)
149
150* System designers and engineers working on the development of the application
151 and/or the operating system want a powerful tool that can boot from any boot
152 device they can imagine, they want it fast and scriptable and whatever - in
153 short, they want as many features supported as possible. And some more.
154
155* The engineer who ports U-Boot to a new board and the board maintainer want
156 U-Boot to be as simple as possible so porting it to and maintaining it on
157 their hardware is easy for them.
158
159* Make it easy to test. Add debug code (but don't re-invent the wheel - use
160 existing macros like log_debug() or debug() depending on context).
161
162Please always keep in mind that U-Boot tries to meet all these
163different requirements.
164
165Keep it Maintainable
166^^^^^^^^^^^^^^^^^^^^
167
168* Avoid ``#ifdefs`` where possible
169
170* Use "weak" functions
171
172* Always follow the :doc:`codingstyle` requirements.
173
174Keep it Beautiful
175^^^^^^^^^^^^^^^^^
176
177* Keep the source code clean: strictly follow the :doc:`codingstyle`,
178 keep lists (target names in the Makefiles, board names, etc.)
179 alphabetically sorted, etc.
180
181* Keep U-Boot console output clean: output only really necessary information,
182 be terse but precise, keep output vertically aligned, do not use control
183 character sequences (e.g. backspaces or \\r to do "spinning wheel" activity
184 indicators), etc.
185
186Keep it Open
187^^^^^^^^^^^^
188
189Contribute your work back to the whole community. Submit your changes
190and extensions as patches to the U-Boot mailing list.
191
192Lemmas from the golden rules
193----------------------------
194
195Generic Code is Good Code
196^^^^^^^^^^^^^^^^^^^^^^^^^
197
198New code shall be as generic as possible and added to the U-Boot
199abstraction hierarchy as high as possible. As few code as possible shall be
200added in board directories as people usually do not expect re-usable code
201there. Thus peripheral drivers should be put below
202"drivers" even if they start out supporting only one specific
203configuration. Note that it is not a requirement for such a first
204instance to be generic as genericity generally cannot be extrapolated
205from a single data point.