[RFCv2] doc: develop: Describe system configuration

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Jul 29 09:03:00 CEST 2022


On 7/28/22 20:53, Tom Rini wrote:
> Start by describing in general the best practices for how to implement
> configuration of some aspect of U-Boot.  This generally means finding
> the right choices for when something should be static or dynamically
> configured and enabled.  Then further document when to use CONFIG or CFG
> namespaces for static configuration.
>
> Signed-off-by: Tom Rini <trini at konsulko.com>
> ---
> RFCv2:
> - Based on Pali's feedback, remove the README section and start a new
>    section in this document to cover when to use each namespace. Try and
>    be clear about when to use "hidden" Kconfig options rather than CFG as
>    well.
> - Based on Heinrich's feedback, rename this to system_configuration.rst
>    and include some introductory remarks on when to use some dynamic or
>    static configuration.  Link to the driver model code for dynamic
>    configuration and then explain the CONFIG vs CFG namespaces for static
>    configuration.
>
> RFCv1:
> - This is essentially my idea on how to better handle the problem of
>    CONFIG values that just don't fit in Kconfig because it makes much
>    more sense to define them statically for a given SoC or calculate them
>    from other values, and so on.  One example here would be to revert
>    c7fad78ec0ee ("Convert CONFIG_SYS_BR0_PRELIM et al to Kconfig") and
>    re-name these to CFG_SYS_.. instead. Another big example here would be
>    a global search-and-replace of 's/CONFIG_HPS_/CFG_HPS_/g' as that's
>    all tool-generated. Not all CONFIG_SYS_ options would get this as
>    boolean choices are well handled in Kconfig, and that may not be clear
>    enough in what I wrote here?
> ---
>   README                               |  21 -----
>   doc/develop/index.rst                |   1 +
>   doc/develop/system_configuration.rst | 121 +++++++++++++++++++++++++++
>   3 files changed, 122 insertions(+), 21 deletions(-)
>   create mode 100644 doc/develop/system_configuration.rst
>
> diff --git a/README b/README
> index 2c4bde0b3297..623f35907217 100644
> --- a/README
> +++ b/README
> @@ -166,27 +166,6 @@ Directory Hierarchy:
>   Software Configuration:
>   =======================
>
> -Configuration is usually done using C preprocessor defines; the
> -rationale behind that is to avoid dead code whenever possible.
> -
> -There are two classes of configuration variables:
> -
> -* Configuration _OPTIONS_:
> -  These are selectable by the user and have names beginning with
> -  "CONFIG_".
> -
> -* Configuration _SETTINGS_:
> -  These depend on the hardware etc. and should not be meddled with if
> -  you don't know what you're doing; they have names beginning with
> -  "CONFIG_SYS_".
> -
> -Previously, all configuration was done by hand, which involved creating
> -symbolic links and editing configuration files manually. More recently,
> -U-Boot has added the Kbuild infrastructure used by the Linux kernel,
> -allowing you to use the "make menuconfig" command to configure your
> -build.
> -
> -
>   Selection of Processor Architecture and Board Type:
>   ---------------------------------------------------
>
> diff --git a/doc/develop/index.rst b/doc/develop/index.rst
> index 73741ceb6a2f..7c41e3f1b6e5 100644
> --- a/doc/develop/index.rst
> +++ b/doc/develop/index.rst
> @@ -13,6 +13,7 @@ General
>      designprinciples
>      process
>      release_cycle
> +   system_configuration
>
>   Implementation
>   --------------
> diff --git a/doc/develop/system_configuration.rst b/doc/develop/system_configuration.rst
> new file mode 100644
> index 000000000000..bb09d1f974d4
> --- /dev/null
> +++ b/doc/develop/system_configuration.rst
> @@ -0,0 +1,121 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +U-Boot system configuration

Thanks Tom for adding this helpful text on configuration. Overall we
should even more move the focus from "namespace" to configuration
mechanism. See below.


%s/U-Boot system/System/

We know that we are talking about U-Boot.

> +===========================
> +
> +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 is preferred over build time. But when making these

%s/run time/run time configuration/
%s/build time/build time configuration/

> +decision, we also need to consider if we're talking about feature that could be

%s/decision/decisions/

%s/feature/a feature/

> +useful to virtually every platform or something specific to a single hardware
> +platform. The resulting image size is also another important consideration.
> +Finally, the overall requirements of being able to do run time detection will
> +have an impact on if it's possible or not.

I guess you mean that run time detection is not always feasible? How about:

"Run time detection depends on the physical hardware and may not always
be possible."

> +
> +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:
> +
> +#. Simple run time. One example here are chip revision checks. Another is

%s/Simple run time\./Run time feature detection./

> +   knowing that we've checked GPIOs and are on revision B of a platform, rather

Do you mean: "On some boards the revision may be detected by reading
GPIOs."?

> +   than doing a more expensive device tree check. This allows us to use a single
> +   device tree for revision A and B in this case and perform fixups as needed
> +   rather than storing two device trees.
> +
> +#. Making use of our Kconfig infrastructure and the ``CONFIG`` namespace. The
> +   primary method of build time configuration is done via the ``CONFIG``
> +   namespace and Kconfig infrastructure. 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.
> +
> +#. 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 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 the ``CFG`` namespace. This is
> +   useful when for various reasons we cannot get configuration values that we
> +   need from the device tree so instead have them defined in a header and use
> +   the prefix ``CFG_`` in their definition.
> +
> +Dynamic run time configuration methods.
> +---------------------------------------
> +
> +For more information in general on how to make use of this please start with the
> +:doc:`driver model <driver-model/index>` documentation.
> +
> +Static build time configuration methods
> +---------------------------------------
> +
> +There are two namespaces used to control the build time configuration of

The focus on the word 'namespaces' does not provide clarity here. The
choice is between:

* defining configuration variables via Kconfig
* defining configuration variables via headers files

The namespace thing is secondary to this choice.

> +U-Boot, ``CONFIG`` and ``CFG``. 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 first of these, ``CONFIG``` is managed in the `Kconfig language
> +<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ that is
> +most commonly associated with the Linux kernel and the Kconfig files found
> +throughout our sources. Adding options to this namespace 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 second of these, ``CFG`` is implemented directly as C preprocessor values or
> +macros, depending on what they are in turn describing. The nature of U-Boot
> +means that while we have some functionality that is very reasonable to expose to

%s/The nature of U-Boot means that while/While/

The removed words do not add clarity.

> +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,

%s/tree \./tree./

> +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 namespace
> +^^^^^^^^^^^^^^^^^^^^^^^^^^

The paragraphs below are not about namespaces but about when to use
Kconfig and when to use arch/Soc/board specific constants defined in
headers.

> +
> +While there are some cases where it should be fairly obvious where to use each
> +namespace, as for example a command would be ``CONFIG`` 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. In general,
> +configuration *options* should be ``CONFIG`` and configuration *settings* should
> +be ``CFG``. Since it is not always clear however, let us discuss things to
> +keep in mind when adding to either namespace.

Why can't we make this is a hard rule:

If it is in Kconfig it is CONFIG_.
It is is not in Kconfig it is CFG_

Nothing comes to my mind where such a rule cannot be applied.

> +
> +A thing to keep in mind is that we have a strong preference for using the
> +``CONFIG`` namespace first. Options expressed this way let us make use of the

The usage of namespace is irritating me here.

"We prefer to use Kconfig."

Best regards

Heinrich


> +Kconfig language to express dependencies and abstractions. 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 symbol that is ``select``'ed by the SoC symbol which would in turn
> +be ``select``'ed by the board option, which is user visible. This means that
> +hardware features that are either present or not present should be in the
> +``CONFIG`` namespace 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.
> +And for practical reasons, we cannot get this information at run time from the
> +device tree. This is a case where it is reasonable to instead make use of the
> +``CFG`` namespace and that it is pure C preprocessor macros to define that
> +``CFG_SYS_FOO_REG`` is ``(CFG_SYS_FOO_BASE + 0x200)`` and have blocks of those
> +under ``#if defined(CONFIG_SOC_FOO1) ... #elif defined(CONFIG_SOC_FOO2) ...
> +#endif`` in a system header file. Another example here is register values. Often
> +it will make the most sense to construct these from other values and then using
> +masks and shifts to turn a list of "magic values" in to something that is easier
> +for humans to parse as well.
> +
> +When it has been determined that the practical solution for where to have
> +something is in the ``CFG`` namespace, 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.



More information about the U-Boot mailing list