designprinciples.rst 8.4 KB

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