[PATCH v3 3/3] RFC: doc: Add documentation about devicetree usage

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Sep 10 18:44:12 CEST 2021



On 9/10/21 12:08 PM, François Ozog wrote:
>
>
> On Thu, 9 Sept 2021 at 22:10, Simon Glass <sjg at chromium.org
> <mailto:sjg at chromium.org>> wrote:
>
>     At present some of the ideas and techniques behind devicetree in U-Boot
>     are assumed, implied or unsaid. Add some documentation to cover how
>     devicetree is build, how it can be modified and the rules about using
>     the various CONFIG_OF_... options.
>
>     Signed-off-by: Simon Glass <sjg at chromium.org <mailto:sjg at chromium.org>>
>     Reviewed-by: Marcel Ziswiler <marcel.ziswiler at toradex.com
>     <mailto:marcel.ziswiler at toradex.com>>
>     ---
>
>     Changes in v3:
>     - Fix typos linst suppled receive EFL
>     - Drop 'and' before 'self-defeating'
>     - Reword mention of control of QEMU's devicetree generation
>     - Add mention of dropping CONFIG_OF_BOARD
>     - Clarify the 'Once this bug is fixed' paragraph a bit
>     - Expand ways that CONFIG_OF_PRIOR_STAGE can support the U-Boot
>     devicetree
>     - Add a note at the top explaining that his patch covers 'now', not
>     'future'
>     - Add note 'Note: Some boards use a devicetree in U-Boot which does
>     not match'
>
>     Changes in v2:
>     - Fix typos per Sean (thank you!) and a few others
>     - Add a 'Use of U-Boot /config node' section
>     - Drop mention of dm-verity since that actually uses the kernel cmdline
>     - Explain that OF_BOARD will still work after these changes (in
>        'Once this bug is fixed...' paragraph)
>     - Expand a bit on the reason why the 'Current situation' is bad
>     - Clarify in a second place that Linux and U-Boot use the same
>     devicetree
>        in 'To be clear, while U-Boot...'
>     - Expand on why we should have rules for other projects in
>        'Devicetree in another project'
>     - Add a comment as to why devicetree in U-Boot is not 'bad design'
>     - Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot'
>     - Rewrite 'Devicetree generated on-the-fly in another project' to cover
>        points raised on v1
>     - Add 'Why does U-Boot have its nodes and properties?'
>     - Add 'Why not have two devicetrees?'
>
>       doc/develop/index.rst              |   1 +
>       doc/develop/package/devicetree.rst | 583 +++++++++++++++++++++++++++++
>       doc/develop/package/index.rst      |   1 +
>       3 files changed, 585 insertions(+)
>       create mode 100644 doc/develop/package/devicetree.rst
>
>     diff --git a/doc/develop/index.rst b/doc/develop/index.rst
>     index 83c929babda..d5ad8f9fe53 100644
>     --- a/doc/develop/index.rst
>     +++ b/doc/develop/index.rst
>     @@ -36,6 +36,7 @@ Packaging
>          :maxdepth: 1
>
>          package/index
>     +   package/devicetree
>
>       Testing
>       -------
>     diff --git a/doc/develop/package/devicetree.rst
>     b/doc/develop/package/devicetree.rst
>     new file mode 100644
>     index 00000000000..b1bd310d906
>     --- /dev/null
>     +++ b/doc/develop/package/devicetree.rst
>     @@ -0,0 +1,583 @@
>     +.. SPDX-License-Identifier: GPL-2.0+
>     +
>     +Updating the devicetree
>     +=======================
>     +
>     +Note: This documentation describes how things are today, mostly,
>     with some
>     +mention of things that need to be fixed. It is not intended to
>     point the way to
>     +what might be done in the future. That should be the subject of
>     discussions on
>     +the mailing list.
>     +
>
> Some text about device tree usage and standardization may be good.
> What about something along the lines:
>
> Device Tree defines a source language, a serialized binary format and
> bindings.
> The power of device tree is that it can be leveraged by applications
> to store self describing rich data out of the context of hardware
> description.
> This power led to abuse in hardware description and device drivers
> started to
> leverage that to store parameters instead of using the operating system
> provided
> capabilities to do so.
> The current state of standardization is such that source and binary
> formats are
> fully defined but unfortunately bindings standardization is split
> between devicetree.org <http://devicetree.org>,
> IEEE1475 and Linux kernel Documentation tree.
> A platform may have multiple device trees attached to it:
> - there can be a System Device Tree covering compute elements outside
> scope of
> U-Boot and subsequent payloads
> - pre-U-Boot firmware components may have their specific ones to deal
> with power
> and clock distribution infrastructure
> - U-Boot may have a richer/different vision of the hardware than the
> booted payload,
> for instance U-Boot may have to view SerDes hardware to configure lines
> into PCI
> or MDIO lanes to match actual board physical routing. The booted payload
> (say Linux)
> should only see the PCI ports or Ethernet ports, not the Serdes. For
> boot-time control
> one may want to limit the hardware vision of U-Boot to just what is
> necessary to boot
> - U-Boot is in the best position to assemble the full device view that
> can result from
> connected capes or hats.
> - The booted payload should just consume what U-Boot hands over
>
>     +U-Boot uses devicetree for runtime configuration and storing
>     required blobs or
>     +any other information it needs to operate.
>
> Those elements shall not be visible to the booted payload. They may be
> stored in a
> separate device tree binary. The bindings for this tree are out of scope
> for projects other
> than U-Boot. U-Boot shall define its own bindings, even if it means
> referring to external
> ones.
>
>     It is possible to update the
>     +devicetree separately from actually building U-Boot. This provides
>     a good degree
>     +of control and flexibility for firmware that uses U-Boot in
>     conjunction with
>     +other project.
>     +
>     +There are many reasons why it is useful to modify the devicetree
>     after building
>     +it:
>     +
>     +- Configuration can be changed, e.g. which UART to use
>     +- A serial number can be added
>     +- Public keys can be added to allow image verification
>     +- Console output can be changed (e.g. to select serial or vidconsole)
>
> Console control is still in its infancy and has many problems. For
> instance, Linux leverages
> stdout *only* with earlyconsole, there is no way to state console=dt/stdout
> in the command line so that the console is directed to firmware provided
> source.
>
>     +
>     +This section describes how to work with devicetree to accomplish
>     your goals.
>     +
>     +See also :doc:`../devicetree/control` for a basic summary of the
>     available
>     +features.
>     +
>     +
>     +Devicetree source
>     +-----------------
>     +
>     +Every board in U-Boot must include a devicetree sufficient to build
>     and boot
>     +that board on suitable hardware (or emulation).
>
>
> That should be noted as current situation, not a *must* that will last
> forever
> U-Boot plays a central role in "massaging" the device tree that is
> handed over
> to the booted payload. But it is certainly not the "authoritative"
> entity that defines
> the board. It may even control only a portion of the entire board
> (covered by System
> Device Tree).
>
>
>     This is specified using the
>     +`CONFIG DEFAULT_DEVICE_TREE` option.
>     +
>     +
>     +Current situation (August 2021)
>     +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     +
>     +As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE`
>     to be empty,
>     +e.g. if `CONFIG_OF_BOARD` or `CONFIG_OF_PRIOR_STAGE` are used. This has
>     +unfortunately created an enormous amount of confusion and some
>     wasted effort.
>     +This was not intended and this bug will be fixed soon.
>     +
>     +Some of the problems created are:
>     +
>     +- It is not obvious that the devicetree is coming from another project
>     +
>     +- There is no way to see even a sample devicetree for these
>     platform in U-Boot,
>     +  so it is hard to know what is going on, e.g. which devices are
>     typically
>     +  present
>     +
>     +- The other project may not provide a way to support U-Boot's
>     requirements for
>     +  devicetree, such as the /config node. Note: On the U-Boot mailing
>     list, this
>     +  was only discovered after weeks of discussion and confusion
>     +
>     +- For QEMU specifically, consulting two QEMU source files is
>     required, for which
>     +  there are no references in U-Boot documentation. The code is
>     generating a
>     +  devicetree, with some control from command-line args, but it is
>     not clear
>     +  how to add properties required by U-Boot.
>     +
>     +Specifically on the changes in U-Boot:
>     +
>     +- `CONFIG_OF_BOARD` was added in rpi_patch_ for Raspberry Pi, which
>     does have
>     +  an in-tree devicetree, but this feature has since been used for
>     boards that
>     +  don't
>     +- `CONFIG_OF_PRIOR_STAGE` was added in bcm_patch_ as part of a
>     larger Broadcom
>     +  change with a tag indicating it only affected one board, so the
>     change in
>     +  behaviour was not noticed at the time. It has since been used by
>     RISC-V qemu
>     +  boards.
>     +
>     +Note: It is not clear that we actually need both of these. Possibly
>     +`CONFIG_OF_BOARD` can be dropped.
>     +
>     +Once this bug is fixed, CONFIG_OF_BOARD and CONFIG_OF_PRIOR_STAGE
>     will override
>     +(at runtime) the devicetree supplied with U-Boot, but will
>     otherwise use
>     +CONFIG_OF_SEPARATE for the in-tree build. So these two will become
>     options,
>     +moving out of the 'choice' in `dts/Kconfig`. To be clear, the
>     devicetree in the
>     +U-Boot tree may be largely for documentation and build-testing
>     purposes, if at
>     +runtime the devicetree if provided by another project. But the in-tree
>     +devicetree is packaged with U-Boot as a fallback if it does not get
>     one from a
>     +prior stage at runtime. This does not create two devicetrees that
>     need to be
>     +merged, or anything like that. If the prior stage provides one, it
>     is used as
>     +is, with the one provided by U-Boot being ignored.
>     +
>     +This means that there is a basic devicetree build in the U-Boot
>     tree, for
>     +build-testing, consistency and documentation purposes, but at
>     runtime U-Boot can
>     +accept its devicetree from another source.
>     +
>     +To be clear, while U-Boot has its own copy of the devicetree source
>     for each
>     +board, this must match the Linux source, perhaps with some u-boot.dtsi
>     +additions. The intent here is not to create a separate binding,
>     just to provide
>     +a representative devicetree in U-Boot.
>     +
>
>     +Note: Some boards use a devicetree in U-Boot which does not match
>     that in Linux.
>     +This is a significant problem which needs to be fixed.
>
>
> That may not be a problem. The requirement is that the generated Device
> Tree is
> conformant to the spec and complete and accurate. U-Boot may further
> amend it.
> Should Qemu change PSCI implementation (new version of API...), U-Boot
> shall
> not have a different vision of this in a separately maintained device tree,
> that just make no sense. For CI/CD, you just use different Qemu runtime
>   parameters rather than use fake static device trees.
>
>     +
>     +Offending boards are:
>     +
>     +- bcm7260
>     +- bcm7445
>     +- qemu_arm64
>     +- qemu_arm
>     +- qemu-ppce500
>     +- qemu-riscv32
>     +- qemu-riscv32_smode
>     +- qemu-riscv64
>     +- qemu-riscv64_smode
>     +
>     +All of these need to have a devicetree added in-tree. This is
>     targeted to be
>     +fixed in the 2022.01 release.
>     +
>     +
>     +Building the devicetree
>     +-----------------------
>     +
>     +U-Boot automatically builds the devicetree for a board, from the
>     +`arch/<arch>/dts` directory. The Makefile in those directories has
>     rules for
>     +building devicetree files. It is preferable to avoid
>     target-specific rules in
>     +those files: i.e. all boards for a particular SoC should be built
>     at once,
>     +where practical. Apart from simplifying the Makefile, this helps to
>     efficiently
>     +(and immediately) ensure that changes in one board's DT do not
>     break others that
>     +are related. Building devicetrees is fast, so performance is seldom
>     a concern
>     +here.
>     +
>     +
>     +Overriding the default devicetree
>     +---------------------------------
>     +
>     +When building U-Boot, the `DEVICE_TREE` environment variable allows the
>     +default devicetree file to be overridden at build time. This can be
>     useful if
>     +modifications have to be made to the in-tree devicetree file, for
>     the benefit
>     +of a downstream build system. Note that the in-tree devicetree must be
>     +sufficient to build and boot, so this is not a way to bypass that
>     requirement.
>     +
>     +
>     +Modifying the devicetree after building
>     +---------------------------------------
>     +
>     +While it is generally painful and hacky to modify the code or
>     rodata of a
>     +program after it is built, in many cases it is useful to do so,
>     e.g. to add
>     +configuration information like serial numbers, enabling/disabling
>     features, etc.
>     +
>     +Devicetree provides a very nice solution to these problems since it is
>     +structured data and it is relatively easy to change it, even in
>     binary form
>     +(see fdtput).
>     +
>     +U-Boot takes care that the devicetree is easily accessible after
>     the build
>     +process. In fact it is placed in a separate file called
>     `u-boot.dtb`. If the
>     +build system wants to modify or replace that file, it can do so.
>     Then all that
>     +is needed is to run `binman update` to update the file inside the
>     image. If
>     +binman is not used, then `u-boot-nodtb.bin` and the new
>     `u-boot.dtb` can simply
>     +be concatenated to achieve the desired result. U-Boot happily copes
>     with the
>     +devicetree growing or shrinking.
>     +
>     +The `u-boot.bin` image contains both pieces. While it is possible
>     to locate the
>     +devicetree within the image using the signature at the start of the
>     file, this
>     +is a bit messy.
>     +
>     +This is why `CONFIG_OF_SEPARATE` should always be used when
>     building U-Boot.
>     +The `CONFIG_OF_EMBED` option embeds the devicetree somewhere in the
>     U-Boot ELF
>     +image as rodata, meaning that it is hard to find it and it cannot
>     increase in
>     +size.
>     +
>     +When modifying the devicetree, the different cases to consider are
>     as follows:
>     +
>     +- CONFIG_OF_SEPARATE
>     +    This is easy, described above. Just change, replace or rebuild the
>     +    devicetree so it suits your needs, then rerun binman or redo
>     the `cat`
>     +    operation to join `u-boot-nodtb.bin` and the new `u-boot.dtb`
>     +
>     +- CONFIG_OF_EMBED
>     +    This is tricky, since the devicetree cannot easily be located.
>     If the ELF
>     +    file is available, then the _dtb_dt_begin and __dtb_dt_end
>     symbols can be
>     +    examined to find it. While it is possible to contract the file,
>     it is not
>     +    possible to expand the file since that would involve re-linking
>     +
>     +- CONFIG_OF_PRIOR_STAGE
>     +    In this case the devicetree must be modified in the project
>     which provides
>     +    it, as described below. This can be achieved by copying the
>     devicetree from
>     +    the U-Boot tree, for example, or by providing an option to (at
>     build-time)
>     +    merge U-Boot's version with the one provided by the project.
>     +
>     +- CONFIG_OF_BOARD
>     +    This is a board-specific situation, so needs to be considered on a
>     +    case-by-case base. The devicetree must be modified so that the
>     correct
>     +    one is provided to U-Boot. How this is done depends entirely on the
>     +    implementation of this option for the board. It might require
>     injecting the
>     +    changes into a different project somehow using tooling
>     available there, or
>     +    it might involve merging an overlay file at runtime to obtain
>     the desired
>     +    result.
>     +
>     +
>     +Use of U-Boot /config node
>     +--------------------------
>     +
>     +A common problem with firmware is that many builds are needed to
>     deal with the
>     +slight variations between different, related models. For example,
>     one model may
>     +have a TPM and another may not. Devicetree provides an excellent
>     solution to
>     +this problem, in that the devicetree to actually use on a platform
>     can be
>     +injected in the factory based on which model is being manufactured
>     at the time.
>     +
>     +A related problem causing build proliferation is dealing with the
>     differences
>     +between development firmware, developer-friendly firmware (e.g.
>     with all
>     +security features present but with the ability to access the
>     command line),
>     +test firmware (which runs tests used in the factory), final
>     production firmware
>     +(before signing), signed firmware (where the signatures have been
>     inserted) and
>     +the like. Ideally all or most of these should use the same U-Boot
>     build, with
>     +just some options to determine the features available. For example,
>     being able
>     +to control whether the UART console or JTAG are available, on any
>     image, is a
>     +great debugging aid.
>     +
>     +When the firmware consists of multiple parts, it is helpful that
>     all operate
>     +the same way at runtime, regardless of how they were built. This
>     can be achieved
>     +by passing the runtime configuration (e.g. 'enable UART console)
>     along the chain
>     +through each firmware stage. It is frustrating to have to replicate
>     a bug on
>     +production firmware which does happen on developer firmware,
>     because they are
>     +completely different builds.
>     +
>     +The /config node provides useful functionality for this. It allows
>     the different
>     +controls to be 'factored out' of the U-Boot binary, so they can be
>     controlled
>     +separately from the initial source-code build. The node can be
>     easily updated by
>     +a build or factory tool and can control various features in U-Boot.
>     It is
>     +similar in concept to a Kconfig option, except that it can be
>     changed after
>     +U-Boot is built.
>     +
>     +The /config node is similar in concept to the `/chosen node`_
>     except that it is
>     +for passing information *into* firmware instead of from firmware to the
>     +Operating System. Also, while Linux has a (sometimes extremely
>     long) command
>     +line, U-Boot does not support this. The devicetree provides a more
>     structured
>     +approach in any case.
>     +
>     +
>     +Devicetree in another project
>     +-----------------------------
>     +
>     +In some cases U-Boot receives its devicetree at runtime from a
>     program that
>     +calls it. For example ARM's Trusted Firmware A (`TF-A`_) may have a
>     devicetree
>     +that it passes to U-Boot. This overrides any devicetree build by
>     U-Boot. When
>     +packaging the firmware, the U-Boot devicetree may in fact be left
>     out if it can
>     +be guaranteed that it will receive one from another project.
>     +
>     +In this case, the devicetree in the other project must track
>     U-Boot's use of
>     +device tree, for the following reasons:
>
>
> STRONG NO. there shall be a platform device tree that is "massaged" by
> different
> firmware components before reaching the booted payload.
> TF-A shall ignore *entirely* if the non secure firmware is U-Boot or
> LinuxBoot or EDK2.
> It shall do what it has authority to do on the platform DT and that's all.
>
>     +
>     +- U-Boot only has one devicetree.
>
>
> U-Boot has vision on hardware that the booted payload shall not even see,
> U-Boot builder for the platform may decide to only consider a hardware
> subset
> for booting purposes. The implementation may be either a single

Hello Francois,

some part of your the message got lost here. Could you, please resend
with the missing part.

Best regards

Heinrich

>
>     See `Why not have two devicetrees?`_.
>     +- For a consistent firmware build, decisions made in early stages
>     should be
>     +  communicated to later ones at runtime. For example, if the serial
>     console is
>     +  enabled in an early stage, it should be enabled in U-Boot too.
>     +- U-Boot is quite capable of managing its own copy of the
>     devicetree. If
>     +  another project wants to bypass this (often for good reason), it
>     is reasonable
>     +  that it should take on the (fairly small) requirements that
>     U-Boot features
>     +  that rely on devicetree are still available
>     +- The point here is not that *U-Boot needs this extra node*, or
>     *U-Boot needs
>     +  to have this public key*. These features are present in U-Boot in
>     service of
>     +  the entire firmware system. If the U-Boot features are used, but
>     cannot be
>     +  supported in the normal way, then there is pressure to implement
>     these
>     +  features in other ways. In the end, we would have a different
>     mechanism for
>     +  every other project that uses U-Boot. This introduces duplicate
>     ways of doing
>     +  the same thing, needlessly increases the complexity of the U-Boot
>     source code,
>     +  forces authors to consider parallel implementations when writing
>     new features,
>     +  makes U-Boot harder to test, complicates documentation and
>     confuses the
>     +  runtime flow of U-Boot. If every board did things its own way
>     rather than
>     +  contributing to the common code, U-Boot would lose a lot of its
>     cross-platform
>     +  value.
>     +
>     +The above does not indicate *bad design* within U-Boot. Devicetree
>     is a core
>     +component of U-Boot and U-Boot makes use of it to the full. It
>     solves a myriad
>     +of problems that would otherwise need their own special C struct,
>     binary format,
>     +special property, tooling for viewing and updating, etc.
>     +
>     +Specifically, the other project must provide a way to add
>     configuration and
>     +other information to the devicetree for use by U-Boot, such as the
>     /config node.
>     +Note that the U-Boot in-tree devicetree source must be sufficient
>     to build and
>     +boot, so this is not a way to bypass that requirement.
>     +
>     +If binman is used, the devicetree source in U-Boot must contain the
>     binman
>     +definition so that a valid image can be build. This helps people
>     discover what
>     +other firmware components are needed and seek out appropriate
>     documentation.
>     +
>     +If verified boot is used, the project must provide a way to inject
>     a public key,
>     +certificate or other material into the U-Boot devicetree so that it
>     is available
>     +to U-Boot at runtime. See `Signing with U-Boot devicetree`_. This
>     may be
>     +through tooling in the project itself or by making use of U-Boot's
>     tooling.
>     +
>     +
>     +Devicetree generated on-the-fly in another project
>     +--------------------------------------------------
>     +
>     +In some rare cases, another project may wish to create a devicetree
>     for U-Boot
>     +entirely on-the-fly, then pass it to U-Boot at runtime. The only
>     known example
>     +of this at the time of writing (2021) is qemu, for ARM (`QEMU
>     ARM`_) and
>     +RISC-V (`QEMU RISC-V`_).
>     +
>     +In effect, when the board boots, U-Boot is *downstream* of the
>     other project.
>     +It is entirely reliant on that project for its correct operation.
>     +
>     +This does not mean to imply that the other project is creating its own,
>     +incompatible devicetree. In fact QEMU generates a valid devicetree
>     which is
>     +suitable for both U-Boot and Linux. It is quite normal for a
>     devicetree to be
>     +present in flash and be made available to U-Boot at runtime. What
>     matters is
>     +where the devicetree comes from. If the other project builds a
>     devicetree for
>     +U-Boot then it needs to support adding the things needed by U-Boot
>     features.
>     +Without them, for example:
>     +
>     +- U-Boot may not boot because too many devices are enabled before
>     relocation
>     +- U-Boot may not have access to the developer or production public
>     keys used for
>     +  signing
>     +- U-Boot may not support controlling whether the console is enabled
>     +- U-Boot may not be know which MMC device to boot from
>     +- U-Boot may not be able to find other firmware components that it
>     needs to load
>     +
>     +Normally, supporting U-Boot's features is trivial, since the
>     devicetree compiler
>     +(dtc) can compile the source, including any U-Boot pieces. So the
>     burden is
>     +extremely low.
>     +
>     +In this case, the devicetree in the other project must track
>     U-Boot's use of
>     +device tree, so that it remains compatible. See `Devicetree in
>     another project`_
>     +for reasons why.
>     +
>     +If a particular version of the project is needed for a particular
>     version of
>     +U-Boot, that must be documented in both projects.
>     +
>     +Further, it must provide a way to add configuration and other
>     information to
>     +the devicetree for use by U-Boot, such as the `/config` node and
>     the tags used
>     +by driver model. Note that the U-Boot in-tree devicetree must be
>     sufficient to
>     +build and boot, so this is not a way to bypass that requirement.
>     +
>     +More specifically, tooling or command-line arguments must provide a
>     way to
>     +add a `/config` node or items within that node, so that U-Boot can
>     receive a
>     +suitable configuration. It must provide a way of adding
>     `u-boot,dm-...` tags for
>     +correct operation of driver model. These options can then be used
>     as part of the
>     +build process, which puts the firmware image together. For binman,
>     a way must be
>     +provided to add the binman definition into the devicetree in the
>     same way.
>     +
>     +One way to do this is to allow a .dtsi file to be merged in with
>     the generated
>     +devicetree.
>     +
>     +Note that the burden goes both ways. If a new feature is added to
>     U-Boot which
>     +needs support in another project, then the author of the U-Boot
>     patch must add
>     +any required support to the other project.
>     +
>     +
>     +Passing the devicetree through to Linux
>     +---------------------------------------
>     +
>     +Ideally U-Boot and Linux use the same devicetree source, even
>     though it is
>     +hosted in separate projects. U-Boot adds some extra pieces, such as the
>     +`config/` node and tags like `u-boot,dm-spl`. Linux adds some extra
>     pieces, such
>     +as `linux,default-trigger` and `linux,code`. This should not
>     interfere with
>     +each other.
>     +
>     +In principle it is possible for U-Boot's control devicetree to be
>     passed to
>     +Linux. This is, after all, one of the goals of devicetree and the
>     original
>     +Open Firmware project, to have the firmware provide the hardware
>     description to
>     +the Operating System.
>     +
>     +For boards where this approach is used, care must be taken. U-Boot
>     typically
>     +needs to 'fix up' the devicetree before passing it to Linux, e.g.
>     to add
>     +information about the memory map, about which serial console is
>     used, provide
>     +the kernel address space layout randomization (KASLR) seed or
>     select whether the
>     +console should be silenced for a faster boot.
>     +
>     +Fix-ups involve modifying the devicetree. If the control devicetree
>     is used,
>     +that means the control devicetree could be modified, while U-Boot
>     is using it.
>     +Removing a device and reinserting it can cause problems if the
>     devicetree offset
>     +has changed, for example, since the device will be unable to
>     locates its
>     +devicetree properties at the expected devicetree offset, which is a
>     fixed
>     +integer.
>     +
>     +To deal with this, it is recommended to employ one or more of the
>     following
>     +approaches:
>     +
>     +- Make a copy of the devicetree and 'fix up' the copy, leaving the
>     control
>     +  devicetree alone
>     +- Enable `CONFIG_OF_LIVE` so that U-Boot makes its own copy of the
>     devicetree
>     +  during relocation; fixups then happen on the original flat tree
>     +- Ensure that fix-ups happen after all loading has happened and
>     U-Boot has
>     +  completed image verification
>     +
>     +In practice,the last point is typically observed, since
>     boot_prep_linux() is
>     +called just before jumping to Linux, long after signature
>     verification, for
>     +example. But it is important to make sure that this line is not
>     blurred,
>     +particularly if untrusted user data is involved.
>     +
>     +
>     +Devicetree use cases that must be supported
>     +-------------------------------------------
>     +
>     +Regardless of how the devicetree is provided to U-Boot at runtime,
>     various
>     +U-Boot features must be fully supported. This section describes
>     some of these
>     +features and the implications for other projects.
>     +
>     +If U-Boot uses its own in-tree devicetree these features are supported
>     +automatically.
>     +
>     +
>     +Signing with U-Boot devicetree
>     +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     +
>     +U-Boot supports signing a payload so that it can be verified to
>     have been
>     +created by a party owning a private key. This is called verified
>     boot in U-Boot
>     +(see doc/uImage.FIT/verified-boot.txt).
>     +
>     +Typically this works by creating a FIT and then running the
>     `mkimage` tool to
>     +add signatures for particular images. As part of this process,
>     `mkimage` writes
>     +a public key to the U-Boot devicetree, although this can be done
>     separately.
>     +See fdt_add_pubkey_ for patches for a suitable tool, for example.
>     +
>     +As with all configuration information, if another project is
>     providing the
>     +devicetree to U-Boot, it must provide a way to add this public key
>     into the
>     +devicetree it passes to U-Boot. This could be via a tooling option,
>     making use
>     +of `mkimage`, or allowing a .dtsi file to be merged in with what is
>     generated in
>     +the other project.
>     +
>     +
>     +Providing the binman image definition
>     +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     +
>     +In complex systems U-Boot must locate and make use of other
>     firmware components,
>     +such as images for the user interface, files containing peripheral
>     firmware,
>     +multiple copies of U-Boot for use with A/B boot, etc. U-Boot uses
>     +:doc:`Binman <binman>` as a standard way of putting an image together.
>     +
>     +Typically this works by running binman with the devicetree as an
>     input, to
>     +create the file image. Binman then outputs an updated devicetree
>     which is
>     +packed in the firmware image, so U-Boot can access the binman
>     definition and
>     +locate all the components.
>     +
>     +As with all configuration information, if another project is
>     providing the
>     +devicetree to U-Boot, it must provide a way to add this binman
>     definition into
>     +the devicetree it passes to U-Boot. This could be via a tooling
>     option, making
>     +use of `binman`, or alowing a .dtsi file to be merged in with what
>     is generated
>     +in the other project.
>     +
>     +
>     +Protecting the devicetree
>     +-------------------------
>     +
>     +U-Boot relies heavily on devicetree for correct operation. A
>     corrupt or invalid
>     +device can cause U-Boot to fail to start, behave incorrectly, crash
>     (e.g. if
>     +`CONFIG_OF_LIBFDT_ASSUME_MASK` is adjusted, or fail to boot an
>     Operating System.
>     +Within U-Boot, the devicetree is as important as any other part of
>     the source
>     +code. At ruuntime, the devicetree can be considered to be
>     structured rodata.
>     +
>     +With secure systems, care must be taken that the devicetree is valid:
>     +
>     +- If the code / rodata has a hash or signature, the devicetree
>     should also, if
>     +  they are packaged separately.
>     +- If the code / rodata is write-protected when running, the
>     devicetree should be
>     +  also. Note that U-Boot relocates its code and devicetree, so this
>     is not as
>     +  simple as it sounds. U-Boot must write-protect these items after
>     relocating.
>     +
>     +
>     +Why does U-Boot have its nodes and properties?
>     +----------------------------------------------
>     +
>     +See also :doc:`../devicetree/intro`.
>     +
>     +There has been pushback at the concept that U-Boot dares have its
>     own nodes and
>     +properties in the devicetree.
>     +
>     +Apart from these nodes and properties, U-Boot uses the same
>     bindings as Linux.
>     +A `u-boot.dtsi` file helps to keep U-Boot-specific changes in
>     separate files,
>     +making it easier to keep devicetree source files in U-Boot in sync
>     with Linux.
>     +
>     +As a counter-example, the Zephyr OS project takes a different
>     approach. It uses
>     +entirely different bindings, in general, making no effort to sync
>     devicetree
>     +source files with Linux. U-Boot strives to be compatible with Linux
>     in a number
>     +of ways, such as source code style and common APIs, to aid porting
>     of code
>     +between the projects. Devicetree is another way where U-Boot and
>     Linux follow a
>     +similar approach.
>     +
>     +Fundamentally, the idea that U-Boot cannot have its own tags flies
>     in the face
>     +of the devicetree specification (see dtspec_), which says:
>     +
>     +  Nonstandard property names should specify a **unique string
>     prefix**, such as
>     +  a stock ticker symbol, identifying the name of the company **or
>     organization**
>     +  that defined the property. Examples:
>     +
>     +  - fsl,channel-fifo-len
>     +  - ibm,ppc-interrupt-server#s
>     +  - **linux**,network-index
>     +
>     +It is also fundamentally unbalanced. Linux has many tags of its own
>     (some 36 in
>     +version 5.13) and at least one Linux-specific node, even if you
>     ignore things
>     +like flash partitions which clearly provide configuration
>     information to Linux.
>     +
>     +Practically speaking there are many reasons why U-Boot has its own
>     nodes and
>     +properties. Some examples:
>     +
>     +- Binding every device before relocation even if it won't be used,
>     consumes time
>     +  and memory: tags on each node can specify which are needed in SPL
>     or before
>     +  relocation. Linux has no such constraints.
>     +
>     +- Requiring the full clock tree to be up and running just to get
>     the debug UART
>     +  running is inefficient. It is also and self-defeating, since if
>     that much
>     +  code is working properly, you probably don't need the debug UART.
>     A devicetree
>     +  property to provide the UART input-clock frequency is a simple
>     solution.
>     +
>     +- U-Boot does not have a user space to provide policy and
>     configuration. It
>     +  cannot do what Linux does and run programs and look up
>     filesystems to figure
>     +  out how to boot.
>     +
>     +
>     +Why not have two devicetrees?
>     +-----------------------------
>     +
>     +Setting aside the argument for restricting U-Boot from having its
>     own nodes and
>     +properties, another idea proposed is to have two devicetrees, one
>     for the
>     +U-Boot-specific bits (here called `special`) and one for everything
>     else (here
>     +called `linux`).
>     +
>     +On the positive side, it might quieten the discussion alluded to in
>     the section
>     +above. But there are many negatives to consider and many open
>     questions to
>     +resolve.
>     +
>     +- **Bindings** - Presumably the special devicetree would have its
>     own bindings.
>     +  It would not be necessary to put a `u-boot,` prefix on anything.
>     People coming
>     +  across the devicetree source would wonder how it fits in with the
>     Linux
>     +  devicetree.
>     +
>     +- **Access** - U-Boot has a nice `ofnode` API for accessing the
>     devicetree. This
>     +  would need to be expanded to support two trees. Features which
>     need to access
>     +  both (such as a device driver which reads the special devicetree
>     to get some
>     +  configuration info) could become quite confusing to read and write.
>     +
>     +- **Merging** - Can the two devicetree be merged if a platform
>     desires it? If
>     +  so, how is this managed in tooling? Does it happen during the
>     build, in which
>     +  case they are not really separate at all. Or does U-Boot merge
>     them at
>     +  runtime, in which case this adds time and memory?
>     +
>     +- **Efficiency** - A second device tree adds more code and more
>     code paths. It
>     +  requires that both be made available to the code in U-Boot, e.g.
>     via a
>     +  separate pointer or argument or API. Overall the separation would
>     certainly
>     +  not speed up U-Boot, nor decrease its size.
>     +
>     +- **Source code** - At present `u-boot.dtsi` files provide the
>     pieces needed for
>     +  U-Boot for a particular board. Would we use these same files for
>     the special
>     +  devicetree?
>     +
>     +- **Complexity** - Two devicetrees complicates the build system
>     since it must
>     +  build and package them both. Errors must be reported in such a
>     way that it
>     +  is obvious which one is failing.
>     +
>     +- **Referencing each other** - The `u-boot,dm-xxx` tags used by
>     driver model
>     +  are currently placed in the nodes they relate to. How would these
>     tags
>     +  reference a node that is in a separate devicetree? What extra
>     validation would
>     +  be needed?
>     +
>     +- **Storage** - How would the two devicetrees be stored in the
>     image? At present
>     +  we simply concatenate the U-Boot binary and the devicetree. We
>     could add the
>     +  special devicetree before the Linux one, so two are concatenated,
>     but it is
>     +  not pretty. We could use binman to support more complex
>     arrangements, but only
>     +  some boards use this at present, so it would be a big change.
>     +
>     +- **API** - How would another project provide two devicetree files
>     to U-Boot at
>     +  runtime? Presumably this would just be too painful. But if it
>     doesn't, it
>     +  would be unable to configure run-time features of U-Boot during
>     the boot.
>     +
>     +- **Confusion** - No other project has two devicetrees. U-Boot
>     would be in the
>     +  unfortunate position of having to describe this fact to new
>     users, along with
>     +  the (arguably contrived) reason for the arrangement.
>     +
>     +- **Signing flow** - The current signing flow is simple as it
>     involves running
>     +  `mkimage` with the U-Boot devicetree. This would have to be
>     updated to use the
>     +  special devicetree. Some way of telling the user that they have
>     done it wrong
>     +  would have to be invented.
>     +
>     +Overall, adding a second devicetree would create enormous confusion and
>     +complexity. It seems a lot cheaper to solve this by a change of
>     attitude.
>     +
>     +
>     +.. _rpi_patch:
>     https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deymo@google.com/
>     <https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deymo@google.com/>
>     +.. _bcm_patch:
>     https://patchwork.ozlabs.org/project/uboot/patch/16fc0901f4521d3c399eac950c52a634b2f9473b.1528485916.git.fitzsim@fitzsim.org/
>     <https://patchwork.ozlabs.org/project/uboot/patch/16fc0901f4521d3c399eac950c52a634b2f9473b.1528485916.git.fitzsim@fitzsim.org/>
>     +.. _`TF-A`: https://www.trustedfirmware.org/projects/tf-a
>     <https://www.trustedfirmware.org/projects/tf-a>
>     +.. _`QEMU ARM`:
>     https://github.com/qemu/qemu/blob/master/hw/arm/virt.c
>     <https://github.com/qemu/qemu/blob/master/hw/arm/virt.c>
>     +.. _`QEMU RISC-V`:
>     https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c
>     <https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c>
>     +.. _`/chosen node`:
>     https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt
>     <https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt>
>     +.. _fdt_add_pubkey:
>     https://patchwork.ozlabs.org/project/uboot/list/?series=157843&state=*
>     <https://patchwork.ozlabs.org/project/uboot/list/?series=157843&state=*>
>     +.. _dtspec: https://www.devicetree.org/specifications/
>     <https://www.devicetree.org/specifications/>
>     diff --git a/doc/develop/package/index.rst
>     b/doc/develop/package/index.rst
>     index 9374be2e62c..188c376950e 100644
>     --- a/doc/develop/package/index.rst
>     +++ b/doc/develop/package/index.rst
>     @@ -17,3 +17,4 @@ SPI flash.
>          :maxdepth: 2
>
>          binman
>     +   devicetree
>     --
>     2.33.0.309.g3052b89438-goog
>
>
>
> --
>
> François-Frédéric Ozog | /Director Business Development/
> T: +33.67221.6485
> francois.ozog at linaro.org <mailto:francois.ozog at linaro.org> | Skype: ffozog
>
>


More information about the U-Boot mailing list