Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+: |
| 2 | |
| 3 | U-Boot Design Principles |
| 4 | ======================== |
| 5 | |
| 6 | The 10 Golden Rules of U-Boot design |
| 7 | ------------------------------------ |
| 8 | |
| 9 | Keep it Small |
| 10 | ^^^^^^^^^^^^^ |
| 11 | |
| 12 | U-Boot is a Boot Loader, i.e. its primary purpose in the shipping |
| 13 | system is to load some operating system. |
| 14 | That means that U-Boot is |
| 15 | necessary to perform a certain task, but it's nothing you want to |
| 16 | throw any significant resources at. Typically U-Boot is stored in |
| 17 | relatively small NOR flash memory, which is expensive |
| 18 | compared to the much larger NAND devices often used to store the |
| 19 | operating system and the application. |
| 20 | |
| 21 | At the moment, U-Boot supports boards with just 128 KiB ROM or with |
| 22 | 256 KiB NOR flash. We should not easily ignore such configurations - |
| 23 | they may be the exception in among all the other supported boards, |
| 24 | but if a design uses such a resource-constrained hardware setup it is |
| 25 | usually because costs are critical, i. e. because the number of |
| 26 | manufactured boards might be tens or hundreds of thousands or even |
| 27 | millions... |
| 28 | |
| 29 | A usable and useful configuration of U-Boot, including a basic |
| 30 | interactive command interpreter, support for download over Ethernet |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 31 | and the capability to program the flash shall fit in no more than 128 KiB. |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 32 | |
| 33 | Keep it Fast |
| 34 | ^^^^^^^^^^^^ |
| 35 | |
| 36 | The end user is not interested in running U-Boot. In most embedded |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 37 | systems they are not even aware that U-Boot exists. The user wants to |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 38 | run some application code, and that as soon as possible after switching |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 39 | on their device. |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 40 | |
| 41 | It is therefore essential that U-Boot is as fast as possible, |
| 42 | especially that it loads and boots the operating system as fast as possible. |
| 43 | |
| 44 | To 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 | |
| 55 | Also, building of U-Boot shall be as fast as possible. |
| 56 | This makes it easier to run a build for all supported configurations |
| 57 | or at least for all configurations of a specific architecture, |
| 58 | which is essential for quality assurance. |
| 59 | If building is cumbersome and slow, most people will omit |
| 60 | this important step. |
| 61 | |
| 62 | Keep it Simple |
| 63 | ^^^^^^^^^^^^^^ |
| 64 | |
| 65 | U-Boot is a boot loader, but it is also a tool used for board |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 66 | bring-up, for production testing, and for other activities. |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 67 | |
| 68 | Keep it Portable |
| 69 | ^^^^^^^^^^^^^^^^ |
| 70 | |
| 71 | U-Boot is a boot loader, but it is also a tool used for board |
| 72 | bring-up, for production testing, and for other activities that are |
| 73 | very closely related to hardware development. So far, it has been |
| 74 | ported to several hundreds of different boards on about 30 different |
| 75 | processor families - please make sure that any code you add can be |
| 76 | used on as many different platforms as possible. |
| 77 | |
| 78 | Avoid assembly language whenever possible - only the reset code with |
| 79 | basic CPU initialization, maybe a static DRAM initialization and the C |
| 80 | stack setup should be in assembly. |
| 81 | All further initializations should be done in C using assembly/C |
| 82 | subroutines or inline macros. These functions represent some |
| 83 | kind of HAL functionality and should be defined consistently on all |
| 84 | architectures, e.g. basic MMU and cache control, stack pointer manipulation. |
| 85 | Non-existing functions should expand into empty macros or error codes. |
| 86 | |
| 87 | Don't make assumptions about the environment where U-Boot is running. |
| 88 | It may be communicating with a human operator on directly attached |
| 89 | serial console, but it may be through a GSM modem as well, or driven |
| 90 | by some automatic test or control system. So don't output any fancy |
| 91 | control character sequences or similar. |
| 92 | |
| 93 | Keep it Configurable |
| 94 | ^^^^^^^^^^^^^^^^^^^^ |
| 95 | |
| 96 | Section "Keep it Small" already explains about the size restrictions |
| 97 | for U-Boot on one side. On the other side, U-Boot is a powerful tool |
| 98 | with many, many extremely useful features. The maintainer or user of |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 99 | each board will have to decide which features are important to them and |
| 100 | what shall be included with their specific board configuration to meet |
| 101 | their current requirements and restrictions. |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 102 | |
| 103 | Please make sure that it is easy to add or remove features from a |
| 104 | board configuration, so everybody can make the best use of U-Boot on |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 105 | their system. |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 106 | |
| 107 | If a feature is not included, it should not have any residual code |
| 108 | bloating the build. |
| 109 | |
| 110 | Keep it Debuggable |
| 111 | ^^^^^^^^^^^^^^^^^^ |
| 112 | |
| 113 | Of course debuggable code is a big benefit for all of us contributing |
| 114 | in one way or another to the development of the U-Boot project. But |
| 115 | as already mentioned in section "Keep it Portable" above, U-Boot is |
| 116 | not only a tool in itself, it is often also used for hardware |
| 117 | bring-up, so debugging U-Boot often means that we don't know if we are |
| 118 | tracking down a problem in the U-Boot software or in the hardware we |
| 119 | are running on. Code that is clean and easy to understand and to |
| 120 | debug 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 Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 129 | and "256 MB\\n" when done. The purpose of this is that you can always see |
Tom Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 130 | 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 | |
| 139 | Keep it Usable |
| 140 | ^^^^^^^^^^^^^^ |
| 141 | |
| 142 | Please always keep in mind that there are at least three different |
| 143 | groups of users for U-Boot, with completely different expectations |
| 144 | and requirements: |
| 145 | |
Tom Rini | 2180aec | 2022-07-14 08:07:44 -0400 | [diff] [blame] | 146 | * 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 Rini | 528581e | 2022-07-14 08:07:41 -0400 | [diff] [blame] | 148 | 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 | |
| 162 | Please always keep in mind that U-Boot tries to meet all these |
| 163 | different requirements. |
| 164 | |
| 165 | Keep it Maintainable |
| 166 | ^^^^^^^^^^^^^^^^^^^^ |
| 167 | |
| 168 | * Avoid ``#ifdefs`` where possible |
| 169 | |
| 170 | * Use "weak" functions |
| 171 | |
| 172 | * Always follow the :doc:`codingstyle` requirements. |
| 173 | |
| 174 | Keep 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 | |
| 186 | Keep it Open |
| 187 | ^^^^^^^^^^^^ |
| 188 | |
| 189 | Contribute your work back to the whole community. Submit your changes |
| 190 | and extensions as patches to the U-Boot mailing list. |
| 191 | |
| 192 | Lemmas from the golden rules |
| 193 | ---------------------------- |
| 194 | |
| 195 | Generic Code is Good Code |
| 196 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 197 | |
| 198 | New code shall be as generic as possible and added to the U-Boot |
| 199 | abstraction hierarchy as high as possible. As few code as possible shall be |
| 200 | added in board directories as people usually do not expect re-usable code |
| 201 | there. Thus peripheral drivers should be put below |
| 202 | "drivers" even if they start out supporting only one specific |
| 203 | configuration. Note that it is not a requirement for such a first |
| 204 | instance to be generic as genericity generally cannot be extrapolated |
| 205 | from a single data point. |