On Fri, 10 Sept 2021 at 18:44, Heinrich Schuchardt <xypron.g...@gmx.de> wrote:
> > > On 9/10/21 12:08 PM, François Ozog wrote: > > > > > > On Thu, 9 Sept 2021 at 22:10, Simon Glass <s...@chromium.org > > <mailto:s...@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 <s...@chromium.org <mailto: > s...@chromium.org>> > > Reviewed-by: Marcel Ziswiler <marcel.ziswi...@toradex.com > > <mailto:marcel.ziswi...@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 > > //Looks like other parts of the messages have been lost, I may have opened two windows The implementation may be either: - a single device tree that is pruned (remove SerDes) and then adjusted by U-Boot (add PCI lanes) or U-Boot applies an overlay (if we finally agree on that) that corresponds to that profile - or U-Boot is passed two DTBs: the one it needs to deal with SerDes, and the platform one to be handed over to the OS. As a matter of fact, the board builder knows how it actually routed the soc pins. and it knows that the non secure firmware (U-Boot, LinuxBoot...) needs to configure the serdes according desired parameters that can only result in a platform DTB. The way to actually make sure the non-secure firmware programs the Serdes with the right parameters is out of scope and non secure firmware dependent. One could say it is a DTB parameter, compile config option, parameter file... > 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-de...@google.com/ > > < > https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-de...@google.com/ > > > > +.. _bcm_patch: > > > https://patchwork.ozlabs.org/project/uboot/patch/16fc0901f4521d3c399eac950c52a634b2f9473b.1528485916.git.fitz...@fitzsim.org/ > > < > https://patchwork.ozlabs.org/project/uboot/patch/16fc0901f4521d3c399eac950c52a634b2f9473b.1528485916.git.fitz...@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.o...@linaro.org <mailto:francois.o...@linaro.org> > | Skype: ffozog > > > > > -- François-Frédéric Ozog | *Director Business Development* T: +33.67221.6485 francois.o...@linaro.org | Skype: ffozog