mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-11-04 10:21:25 +01:00 
			
		
		
		
	Fix a few typos spot during a first read of the contribution process. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
		
			
				
	
	
		
			133 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
.. SPDX-License-Identifier: GPL-2.0+
 | 
						|
 | 
						|
System configuration
 | 
						|
====================
 | 
						|
 | 
						|
There are a number of different aspects to configuring U-Boot to build and then
 | 
						|
run on a given platform or set of platforms. Broadly speaking, some aspects of
 | 
						|
the world can be configured at run time and others must be done at build time.
 | 
						|
In general run time configuration is preferred over build time configuration.
 | 
						|
But when making these decisions, we also need to consider if we're talking about
 | 
						|
a feature that could be useful to virtually every platform or something specific
 | 
						|
to a single hardware platform. The resulting image size is also another
 | 
						|
important consideration. Finally, run time configuration has additional overhead
 | 
						|
both in terms of resource requirements and wall clock time. All of this means
 | 
						|
that care must be taken when writing new code to select the most appropriate
 | 
						|
configuration mechanism.
 | 
						|
 | 
						|
When adding new features to U-Boot, be they a new subsystem or SoC support or
 | 
						|
new platform for an existing supported SoC, the preferred configuration order
 | 
						|
is:
 | 
						|
 | 
						|
#. Hardware based run time configuration. Examples of this include reading
 | 
						|
   processor specific registers, or a set of board specific GPIOs or an EEPROM
 | 
						|
   with a known format to it. These are the cases where we either cannot or
 | 
						|
   should not be relying on device tree checks. We use this for cases such as
 | 
						|
   optimized boot time or starting with a generic device tree and then enabling
 | 
						|
   or disabling features as we boot.
 | 
						|
 | 
						|
#. Making use of our Kconfig infrastructure and C preprocessor macros that have
 | 
						|
   the prefix ``CONFIG``. This is the primary method of build time
 | 
						|
   configuration. This is generally the best fit for when we want to enable or
 | 
						|
   disable some sort of feature, such as the SoC or network support. The
 | 
						|
   ``CONFIG`` prefix for C preprocessor macros is strictly reserved for Kconfig
 | 
						|
   usage only.
 | 
						|
 | 
						|
#. Making use of the :doc:`device tree <devicetree/control>` to determine at
 | 
						|
   run time how to configure a feature that we have enabled via Kconfig. For
 | 
						|
   example, we would use Kconfig to enable an I2C chip driver, but use the device
 | 
						|
   tree to know where the I2C chip resides in memory and other details we need
 | 
						|
   in order to configure the bus.
 | 
						|
 | 
						|
#. Making use of C header files directly and defining C preprocessor macros that
 | 
						|
   have the ``CFG`` prefix. While the ``CFG`` prefix is reserved for this build
 | 
						|
   time configuration mechanism, the usage is ad hoc. This is to be used when the
 | 
						|
   previously mentioned mechanisms are not possible, or for legacy code that has
 | 
						|
   not been converted.
 | 
						|
 | 
						|
Dynamic run time configuration methods.
 | 
						|
---------------------------------------
 | 
						|
 | 
						|
Details of hardware specific run time configuration methods are found within the
 | 
						|
documentation for a given processor family or board.
 | 
						|
 | 
						|
Details of how to use run time configuration based on :doc:`driver model
 | 
						|
<driver-model/index>` are covered in that documentation section.
 | 
						|
 | 
						|
Static build time configuration methods
 | 
						|
---------------------------------------
 | 
						|
 | 
						|
There are two mechanisms used to control the build time configuration of U-Boot.
 | 
						|
One is utilizing Kconfig and ``CONFIG`` prefixed macros and the other is ad hoc
 | 
						|
usage of ``CFG`` prefixed macros. Both of these are used when it is either not
 | 
						|
possible or not practical to make a run time determination about some
 | 
						|
functionality of the hardware or a required software feature or similar. Each of
 | 
						|
these has their own places where they are better suited than the other for use.
 | 
						|
 | 
						|
The `Kconfig language
 | 
						|
<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ is well
 | 
						|
documented and used in a number of projects, including the Linux kernel. We
 | 
						|
implement this with the Kconfig files found throughout our sources. This
 | 
						|
mechanism is the preferred way of exposing new configuration options as there
 | 
						|
are a number of ways for both users and system integrators to manage and change
 | 
						|
these options. Some common examples here are to enable a specific command within
 | 
						|
U-Boot or even a whole subsystem such as NAND flash or network connectivity.
 | 
						|
 | 
						|
The ``CFG`` mechanism is implemented directly as C preprocessor values or
 | 
						|
macros, depending on what they are in turn describing. While we have some
 | 
						|
functionality that is very reasonable to expose to the end user to enable or
 | 
						|
disable we have other places where we need to describe things such as register
 | 
						|
locations or values, memory map ranges and so on. When practical, we should be
 | 
						|
getting these values from the device tree. However, there are cases where this
 | 
						|
is either not practical due to when we need the information and may not have a
 | 
						|
device tree yet or due to legacy reasons code has not been rewritten.
 | 
						|
 | 
						|
When to use each mechanism
 | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
						|
 | 
						|
While there are some cases where it should be fairly obvious where to use each
 | 
						|
mechanism, as for example a command would be done via Kconfig, a new I2C driver
 | 
						|
should use Kconfig and be configured via driver model and a header of values
 | 
						|
generated by an external tool should be ``CFG``, there will be cases where it's
 | 
						|
less clear and one needs to take care when implementing it. In general,
 | 
						|
configuration *options* should be done in Kconfig and configuration *settings*
 | 
						|
should be done in driver model or ``CFG``. Let us discuss things to keep in mind
 | 
						|
when picking the appropriate mechanism.
 | 
						|
 | 
						|
A thing to keep in mind is that we have a strong preference for using Kconfig as
 | 
						|
the primary build time configuration mechanism. Options expressed this way let
 | 
						|
us easily express dependencies and abstractions. In addition, given that many
 | 
						|
projects use this mechanism means it has a broad set of tooling and existing
 | 
						|
knowledge base.
 | 
						|
 | 
						|
Consider the example of a SHA256 hardware acceleration engine. This would be a
 | 
						|
feature of the SoC and so something to not ask the user if it exists, but we
 | 
						|
would want to have our generic framework for such engines be optionally
 | 
						|
available and depend on knowing we have this engine on a given hardware
 | 
						|
platform. Expressing this should be done as a hidden Kconfig symbol that is
 | 
						|
``select``'ed by the SoC symbol which would in turn be ``select``'ed by the
 | 
						|
board option, which is user visible. Hardware features that are either present
 | 
						|
or not present should be expressed in Kconfig and in a similar manner, features
 | 
						|
which will always have a constant value such as "this SoC always has 4 cores and
 | 
						|
4 threads per core" should be as well.
 | 
						|
 | 
						|
This brings us to differentiating between a configuration *setting* versus a
 | 
						|
hardware feature. To build on the previous example, while we may know the number
 | 
						|
of cores and threads, it's possible that within a given family of SoCs the base
 | 
						|
addresses of peripherals has changed, but the register offsets within have not.
 | 
						|
The preference in this case is to get our information from the device tree and
 | 
						|
perform run time configuration. However, this is not always practical and in
 | 
						|
those cases we instead rely on the ``CFG`` mechanism. While it would be possible
 | 
						|
to use Kconfig in this case, it would result in using calculated rather than
 | 
						|
constructed values, resulting in less clear code. Consider the example of a set
 | 
						|
of register values for a memory controller. Defining this as a series of logical
 | 
						|
ORs and shifts based on other defines is more clear than the Kconfig entry that
 | 
						|
sets the calculated value alone.
 | 
						|
 | 
						|
When it has been determined that the practical solution is to utilize the
 | 
						|
``CFG`` mechanism, the next decision is where to place these settings. It is
 | 
						|
strongly encouraged to place these in the architecture header files, if they are
 | 
						|
generic to a given SoC, or under the board directory if board specific. Placing
 | 
						|
them under the board.h file in the *include/configs/* directory should be seen
 | 
						|
as a last resort.
 |