"Das U-Boot" Source Tree
at master 345 lines 14 kB view raw
1.. SPDX-License-Identifier: GPL-2.0+ 2.. sectionauthor:: Copyright 2011 The Chromium OS Authors 3.. Copyright 2023-2024 Linaro Ltd. 4 5Devicetree Control in U-Boot 6============================ 7 8This feature provides for run-time configuration of U-Boot via a flattened 9devicetree (fdt). 10 11This feature aims to make it possible for a single U-Boot binary to support 12multiple boards, with the exact configuration of each board controlled by 13a flattened devicetree (fdt). This is the approach taken by Linux kernel for 14ARM and RISC-V and has been used by PowerPC for some time. 15 16The fdt is a convenient vehicle for implementing run-time configuration 17for three reasons: 18 19- There is already excellent infrastructure for the fdt: a compiler checks 20 the text file and converts it to a compact binary format, and a library 21 is already available in U-Boot (libfdt) for handling this format 22- It is extensible since it consists of nodes and properties in a nice 23 hierarchical format 24- It is fairly efficient to read incrementally 25 26The U-Boot Makefile infrastructure allows for building the devicetree blob 27and embedding it in the U-Boot image. This is useful since it allows U-Boot 28to configure itself according to what it finds there. If you have a number 29of similar boards with different peripherals, you can describe the features 30of each board in the devicetree file, and have a single generic source base. 31 32To enable this feature, select `OF_CONTROL` via Kconfig. 33 34 35What is a Flattened Devicetree? 36------------------------------- 37 38An fdt can be specified in source format as a text file. To read about 39the fdt syntax, take a look at `the devicetree specification`_. 40 41There is also a `devicetree compiler mailing list`_ for the compiler and 42associated tools. 43 44In case you are wondering, OF stands for Open Firmware. This follows the 45convention used in Linux. 46 47 48Tools 49----- 50 51To create flattened device trees the device tree compiler is used. This is 52provided by U-Boot automatically. If you have a system version of dtc 53(typically in the 'device-tree-compiler' package), that system version is 54currently not used. 55 56If you want to build your own dtc, it is kept here:: 57 58 git://git.kernel.org/pub/scm/utils/dtc/dtc.git 59 60You can decode a binary file with:: 61 62 dtc -I dtb -O dts <filename.dtb> 63 64That repo also includes `fdtget`/`fdtput` for reading and writing properties in 65a binary file. U-Boot adds its own `fdtgrep` for creating subsets of the file. 66 67 68Where do I get a devicetree file for my board? 69---------------------------------------------- 70 71The devicetree files and devicetree bindings are maintained as part of the Linux 72kernel git repository. Traditionally, U-Boot placed copies of devicetree source 73files from the Linux kernel into `arch/<arch>/dts/<name>.dts`. However, this 74required each board maintainer to manually keep their devicetree in sync with 75the Linux kernel and often led to divergence between these copies. 76 77U-Boot rather maintains a Git subtree as `dts/upstream/` sub-directory. It is 78regularly synced with the Linux kernel and hence no need for manual devicetree 79sync. You may find that the `dts/upstream/` already has a suitable devicetree 80file for your board. Look in `dts/upstream/src/<arch>/<vendor>`. 81 82If not you might find other boards with suitable files that you can 83modify to your needs. Look in the board directories for files with a 84.dts extension. 85 86Failing that, you could write one from scratch yourself! 87 88 89Resyncing with devicetree-rebasing 90---------------------------------- 91 92The `devicetree-rebasing repository`_ maintains a mirror copy of 93devicetree files along with the bindings synced at every Linux kernel major 94release or intermediate release candidates. The U-Boot maintainers regularly 95sync the `dts/upstream/` subtree from the devicetree-rebasing repo whenever 96the next branch opens (refer: :doc:`../release_cycle`) with the latest mainline 97Linux kernel release. To sync the `dts/upstream/` subtree, run:: 98 99 ./tools/update-subtree.sh pull dts <devicetree-rebasing-release-tag> 100 101If required it is also possible to cherry-pick fixes from the 102devicetree-rebasing repository prior to next sync, usage:: 103 104 ./tools/update-subtree.sh pick dts <devicetree-rebasing-commit-id> 105 106 107Configuration 108------------- 109 110SoC/board maintainers are encouraged to migrate to use synced copies from 111`dts/upstream/src/<arch>/<vendor>`. To do that add `imply OF_UPSTREAM` for the 112SoC being used via Kconfig and set `DEFAULT_DEVICE_TREE=<vendor>/<name>` when 113prompted by Kconfig. 114 115However, if `dts/upstream/` hasn't yet received devicetree source file for your 116newly added board support then one option is that you can add the corresponding 117devicetree source file as `arch/<arch>/dts/<name>.dts`. To select that add `# 118CONFIG_OF_UPSTREAM is not set` and set `DEFAULT_DEVICE_TREE=<name>` when 119prompted by Kconfig. Another option is that you can use the "pick" option of 120`tools/update-subtree.sh` mentioned above to bring in the commits that you 121need. 122 123This should include your CPU or SoC's devicetree file. On top of that any U-Boot 124specific tweaks (see: :ref:`dttweaks`) can be made for your board. 125 126If `OF_EMBED` is selected by Kconfig, then it will be picked up and built into 127the U-Boot image (including u-boot.bin). This is suitable for debugging 128and development only and is not recommended for production devices. 129 130If `OF_SEPARATE` is selected by Kconfig, then it will be built and placed in 131a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed 132in u-boot.bin so you can still just flash u-boot.bin onto your board. If Kconfig 133option `SPL_FRAMEWORK` is enabled, then u-boot.img will be built to include the 134device tree binary. 135 136If `OF_BOARD` is selected by Kconfig, a board-specific routine will provide the 137devicetree at runtime, for example if an earlier bootloader stage creates 138it and passes it to U-Boot. 139 140If `BLOBLIST` is selected by Kconfig, the devicetree may come from a bloblist 141passed from a previous stage, if present. 142 143If `SANDBOX` is selected by Kconfig, then it will be read from a file on 144startup. Use the -d flag to U-Boot to specify the file to read, -D for the 145default and -T for the test devicetree, used to run sandbox unit tests. 146 147You cannot use more than one of these options at the same time. 148 149To use a devicetree file that you have compiled yourself, pass 150EXT_DTB=<filename> to 'make', as in:: 151 152 make EXT_DTB=boot/am335x-boneblack-pubkey.dtb 153 154Then U-Boot will copy that file to u-boot.dtb, put it in the .img file 155if used, and u-boot-dtb.bin. 156 157If you wish to put the fdt at a different address in memory, you can 158define the "fdtcontroladdr" environment variable. This is the hex 159address of the fdt binary blob, and will override either of the options. 160Be aware that this environment variable is checked prior to relocation, 161when only the compiled-in environment is available. Therefore it is not 162possible to define this variable in the saved SPI/NAND flash 163environment, for example (it will be ignored). After relocation, this 164variable will be set to the address of the newly relocated fdt blob. 165It is read-only and cannot be changed. It can optionally be used to 166control the boot process of Linux with bootm/bootz commands. 167 168To use this, put something like this in your board header file:: 169 170 #define CFG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0" 171 172Build: 173 174After the board configuration is done, fdt supported u-boot can be built in two 175ways: 176 177# build the default dts which is selected by DEFAULT_DEVICE_TREE Kconfig:: 178 179 $ make 180 181# build the user specified dts file:: 182 183 $ make DEVICE_TREE=<dts-file-name> 184 185 186.. _dttweaks: 187 188Adding tweaks for U-Boot 189------------------------ 190 191With `dts/upstream` Git subtree, it is ensured that devicetree files in U-Boot 192are an exact copy of those in Linux kernel available under 193`dts/upstream/src/<arch>/<vendor>`. 194 195U-Boot is of course a very different project from Linux, e.g. it operates under 196much more restrictive memory and code-size constraints. Where Linux may use a 197full clock driver with Common Clock Format (CCF) to find the input clock to the 198UART, U-Boot typically wants to output a banner as early as possible before too 199much code has run. 200 201A second difference is that U-Boot includes different phases. For SPL, 202constraints are even more extreme and the devicetree is shrunk to remove 203unwanted nodes, or even turned into C code to avoid access overhead. 204 205U-Boot automatically looks for and includes a file with updates to the standard 206devicetree for your board, searching for them in `arch/<arch>/dts/` in this 207order:: 208 209 <orig_filename>-u-boot.dtsi 210 <CONFIG_SYS_SOC>-u-boot.dtsi 211 <CONFIG_SYS_CPU>-u-boot.dtsi 212 <CONFIG_SYS_VENDOR>-u-boot.dtsi 213 u-boot.dtsi 214 215Only one of these is selected but of course you can #include another one within 216that file, to create a hierarchy of shared files. 217 218 219External .dtsi fragments 220------------------------ 221 222Apart from describing the hardware present, U-Boot also uses its 223control dtb for various configuration purposes. For example, the 224public key(s) used for Verified Boot are embedded in a specific format 225in a /signature node. 226 227As mentioned above, the U-Boot build system automatically includes a 228`*-u-boot.dtsi` file, if found, containing U-Boot specific 229quirks. However, some data, such as the mentioned public keys, are not 230appropriate for upstream U-Boot but are better kept and maintained 231outside the U-Boot repository. You can use `DEVICE_TREE_INCLUDES` Kconfig 232option to specify a list of .dtsi files that will also be included when 233building .dtb files. 234 235 236Devicetree bindings schema checks 237--------------------------------- 238 239With devicetee-rebasing Git subtree, the devicetree bindings are also regularly 240synced with Linux kernel as `dts/upstream/Bindings/` sub-directory. This 241allows U-Boot to run devicetree bindings schema checks which will bring 242compliance to U-Boot core/drivers regarding usage of devicetree. 243 244Dependencies 245~~~~~~~~~~~~ 246 247The DT schema project must be installed in order to validate the DT schema 248binding documents and validate DTS files using the DT schema. For installation 249instructions, refer to the `DT schema project page`_. 250 251Several executables (dt-doc-validate, dt-mk-schema, dt-validate) will be 252installed. Ensure they are in your PATH (~/.local/bin by default). 253 254You should also install yamllint (used by dtschema when present). On Debian/ 255Ubuntu systems:: 256 257 apt install yamllint 258 259Running checks 260~~~~~~~~~~~~~~ 261 262In order to perform validation of DTB files, use the ``dtbs_check`` target:: 263 264 make dtbs_check 265 266It is also possible to run checks with a subset of matching schema files by 267setting the ``DT_SCHEMA_FILES`` variable to 1 or more specific schema files or 268patterns (partial match of a fixed string). Each file or pattern should be 269separated by ':'. 270 271:: 272 273 make dtbs_check DT_SCHEMA_FILES=trivial-devices.yaml:rtc.yaml 274 make dtbs_check DT_SCHEMA_FILES=/gpio/ 275 make dtbs_check DT_SCHEMA_FILES=trivial-devices.yaml 276 277 278Relocation, SPL and TPL 279----------------------- 280 281U-Boot can be divided into three phases: TPL, SPL and U-Boot proper. 282 283The full devicetree is available to U-Boot proper, but normally only a subset 284(or none at all) is available to TPL and SPL. See 'Pre-Relocation Support' and 285'SPL Support' in doc/driver-model/design.rst for more details. 286 287 288Using several DTBs in the SPL (SPL_MULTI_DTB_FIT Kconfig option) 289---------------------------------------------------------------- 290In some rare cases it is desirable to let SPL be able to select one DTB among 291many. This usually not very useful as the DTB for the SPL is small and usually 292fits several platforms. However the DTB sometimes include information that do 293work on several platforms (like IO tuning parameters). 294In this case it is possible to use SPL_MULTI_DTB_FIT Kconfig option. This option 295appends to the SPL a FIT image containing several DTBs listed in SPL_OF_LIST. 296board_fit_config_name_match() is called to select the right DTB. 297 298If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM 299containing the board ID for example), it possible to start with a generic DTB 300and then switch over to the right DTB after the detection. For this purpose, 301the platform code must call fdtdec_resetup(). Based on the returned flag, the 302platform may have to re-initialise the DM subsystem using dm_uninit() and 303dm_init_and_scan(). 304 305 306Limitations 307----------- 308 309Devicetrees can help reduce the complexity of supporting variants of boards 310which use the same SOC / CPU. 311 312However U-Boot is designed to build for a single architecture type and CPU 313type. So for example it is not possible to build a single ARM binary 314which runs on your AT91 and OMAP boards, relying on an fdt to configure 315the various features. This is because you must select one of 316the CPU families within arch/arm/cpu/arm926ejs (omap or at91) at build 317time. Similarly U-Boot cannot be built for multiple cpu types or 318architectures. 319 320It is important to understand that the fdt only selects options 321available in the platform / drivers. It cannot add new drivers (yet). So 322you must still have the Kconfig option to enable the driver. For example, 323you need to enable SYS_NS16550 Kconfig option to bring in the NS16550 driver, 324but can use the fdt to specific the UART clock, peripheral address, etc. 325In very broad terms, the Kconfig options in general control *what* driver 326files are pulled in, and the fdt controls *how* those files work. 327 328History 329------- 330 331U-Boot configuration was previous done using CONFIG options in the board 332config file. This eventually got out of hand with nearly 10,000 options. 333 334U-Boot adopted devicetrees around the same time as Linux and early boards 335used it before Linux (e.g. snow). The two projects developed in parallel 336and there are still some differences in the bindings for certain boards. 337While there has been discussion of having a separate repository for devicetree 338files, in practice the Linux kernel Git repository has become the place where 339these are stored, with U-Boot taking copies via 340`devicetree-rebasing repository`_ and adding tweaks with u-boot.dtsi files. 341 342.. _the devicetree specification: https://www.devicetree.org/specifications/ 343.. _devicetree compiler mailing list: https://www.spinics.net/lists/devicetree-compiler/ 344.. _devicetree-rebasing repository: https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git 345.. _DT schema project page: https://github.com/devicetree-org/dt-schema/tree/main