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 <s...@chromium.org>
---
doc/develop/index.rst | 1 +
doc/develop/package/devicetree.rst | 315 +++++++++++++++++++++++++++++
doc/develop/package/index.rst | 1 +
3 files changed, 317 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..fccbb182f3e
--- /dev/null
+++ b/doc/develop/package/devicetree.rst
@@ -0,0 +1,315 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Updating the devicetree
+=======================
+
+U-Boot uses devicetree for runtime configuration and storing required blobs or
+any other information it needs to operate. 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)
+
+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). 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. Specifically:
+
+- `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.
+
+Once this bug is fixed, CONFIG_OF_BOARD and CONFIG_OF_PRIOR_STAGE will override
+(at runtime) the devicetree suppled 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`
+
+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 useul 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_EMBD
+ This is tricky, since the devicetree cannot easily be located. If the EFL
+ 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
+
+- 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.
+
+
+Devicetree in another project
+-----------------------------
+
+In some cases U-Boot receive 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. It must provide a way to add configuration and other information
to