
This is an attempt to answer the comments provided by Xavier [1].
[1] https://lore.kernel.org/all/Yulcol7HpTHtjXTX@begut/
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/Makefile | 1 + tools/binman/binman.rst | 166 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+)
diff --git a/doc/Makefile b/doc/Makefile index 050d9dd2391..6081858726e 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -56,6 +56,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) PYTHONDONTWRITEBYTECODE=1 \ BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \ $(SPHINXBUILD) \ + -j$(shell nproc) \ -b $2 \ -c $(abspath $(srctree)/$(src)) \ -d $(abspath $(BUILDDIR)/.doctrees/$3) \ diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 935839c433e..2e5d301174d 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -118,6 +118,10 @@ flash. For U-Boot, binman should not be used to create ad-hoc images in place of FIT.
+Note that binman can itself can create a FIT. This helps to move mkimage +invocations out of the Makefile and into binman image descriptions. It also +helps by removing the need for ad-hoc tools like `make_fit_atf.py`. +
Relationship to mkimage ----------------------- @@ -140,6 +144,9 @@ seems better to use the mkimage tool to generate binaries and avoid blurring the boundaries between building input files (mkimage) and packaging then into a final image (binman).
+Note that binman can itself invoke mkimage. This helps to move mkimage +invocations out of the Makefile and into binman image descriptions. +
Using binman ============ @@ -170,6 +177,164 @@ This simplifies the U-Boot Makefile somewhat, since various pieces of logic can be replaced by a call to binman.
+Invoking binman within U-Boot +----------------------------- + +Within U-Boot, binman is invoked by the build system, i,e. when you type 'make' +or use buildman to build U-Boot. There is no need to run binman independently +during development. Everything happens automatically and is set up for your +SoC or board so that binman produced the right things. + +The general policy is that the Makefile builds all the binaries in INPUTS-y +(the 'inputs' rule), then binman is run to produce the final images (the 'all' +rule). + +There should be only one invocation of binman in Makefile, the very last step +that pulls everything together. At present there are some arch-specific +invocations as well, but these should be dropped when those archs are converted +to use binman propertly. + +As above, the term 'binary' is used for something in INPUTS-y and 'image' is +used for the things that binman creates. So the binaries are inputs to the +image(s) and it is the image that is actually loaded on the board. + +Again, at present, there are a number of things created in Makefile which should +be done by binman (when we get around to it), like `u-boot-ivt.img`, +`lpc32xx-spl.img`, `u-boot-with-nand-spl.imx`, `u-boot-spl-padx4.sfp` and +`u-boot-mtk.bin`, just to pick on a few. When completed this will remove about +400 lines from `Makefile`. + +Since binman is invoked only once, it must of course create all the images that +are needed, in that one invocation. It does this by working through the image +descriptions one by one, collecting the input binaries, processing them as +needed and producing the final images. + +The same binaries may be used by multiple images. For example binman may be used +to produce an SD-card image and a SPI-flash image. In this case the binaries +going into the process are the same, but binman produces slifhtly different +images in each case. + +For some SoCs, U-Boot is not the only project that produces the necessary +binaries. For example, ARM Trusted Firmware (ATF) is a project that produces +binaries which must be incorporate, such as `bl31.elf` or `bl31.bin`. For this +to work you must have built ATF before you build U-Boot and you must tell U-Boot +where to find the bl31 image, using the BL31 environemnt variable. + +How do you know how to incorporate ATF? It is handled by the atf-bl31 entry type +(etype). An etype is an implementation of reading a binary into binman, in this +case the `bl31.bin` file. When you build U-Boot but do not set the BL31 +environment variable, binman provides a help message, which comes from +`missing-blob-help`:: + + See the documentation for your board. You may need to build ARM Trusted + Firmware and build with BL31=/path/to/bl31.bin + +The mechanism by which binman is advised of this is also in the Makefile. See +the `-a atf-bl31-path=${BL31}` piece in `cmd_binman`. This tells binman to +set the EntryArg `atf-bl31-path` to the value of the `BL31` environment +variable. Within binman, this EntryArg is picked up by the `Entry_atf_bl31` +etype. An EntryArg is simply an argument to the entry. The `atf-bl31-path` +name is documented in :ref:`etype_atf_bl31`. + + +Invoking binman outside U-Boot +------------------------------ + +While binman is invoked from within the U-Boot build system, it is also possible +to invoke it separately. This is typically used in a production build system, +where signing is completed (with real keys) and any missing binaries are +provided. + +For example, for build testing there is no need to provide a real signature, +nor is there any need to provide a real ATF BL31 binary (for example). These can +be added later by invoking binman again, providing all the required inputs +from the first time, plus any that were missing or placeholders. + +So in practice binman is often used twice: + +- once within the U-Boot build system, for development and testing +- again outside U-Boot to assembly and final production images + +While the same inputbinaries are used in each case, you will of course you will +need to create your own binman command line, similar to that in `cmd_binman` in +the Makefile. You may find the -I and --toolpath options useful. The +device tree file is provided to binman in binary form, so there is no need to +have access to the original `.dts` sources. + + +Assembling the image description +-------------------------------- + +Since binman uses device tree for its image description, you can use the same +files that describe your board's hardware to describe how the image is assembled. +Typically the images description is in a common file used by all boards with a +particular SoC (e.g. `imx8mp-u-boot.dtsi`). + +Where a particular boards needs to make changes, it can override properties in +the SoC file, just as it would for any other device tree property. It can also +add a image that is specific to the board. + +Another way to control the image description to make use of CONFIG options in +the description. For example, if the start offset of a particular entry varies +by board, you can add a Kconfig for that and reference it in the description:: + + u-boot-spl { + }; + + fit { + offset = <CONFIG_SPL_PAD_TO>; + ... + }; + +The SoC can provide a default value but boards can override that as needed and +binman will take care of it. + +It is even possible to control which entries appear in the image, by using the +C preprocessor:: + + #ifdef CONFIG_HAVE_MRC + intel-mrc { + offset = <CONFIG_X86_MRC_ADDR>; + }; + #endif + +Only boards which enable `HAVE_MRC` will include this entry. + +Obviously a similar approach can be used to control which images are produced, +with a Kconfig option to enable a SPI image, for example. However there is +generally no harm in producing an image that is not used. If a board uses MMC +but not SPI, but the SoC supports booting from both, then both images can be +produced, with only on or other being used by particular boards. This can help +reduce the need for having multiple defconfig targets for a board where the +only difference is the boot media, enabling / disabling secure boot, etc. + +Of course you can use the device tree itself to pass any board-specific +information that is needed by U-Boot at runtime (see binman_syms_ for how to +make binman insert these values directly into executables like SPL). + +There is one more way this can be done: with individual .dtsi files for each +image supported by the SoC. Then the board `.dts` file can include the ones it +wants. This is not recommended, since it is likely to be difficult to maintain +and harder to understand the relationship between the different boards. + + +Producing images for multiple boards +------------------------------------ + +When invoked within U-Boot, binman only builds a single set of images, for +the chosen board. This is set by the `CONFIG_DEFAULT_DEVICE_TREE` option. + +However, U-Boot generally builds all the device tree files associated with an +SoC. These are written to the (e.g. for ARM) `arch/arm/dts` directory. Each of +these contains the full binman description for that board. Often the best +approach is to build a single image that includes all these device tree binaries +and allow SPL to select the correct one on boot. + +However, it is also possible to build separate images for each board, sinply by +invoking binman multiple times, once for each device tree file, using a +different output directory. This will produce one set of images for each board. + + Example use of binman for x86 -----------------------------
@@ -254,6 +419,7 @@ file, typically <soc>-u-boot.dtsi, where <soc> is your CONFIG_SYS_SOC value. You can use other, more specific CONFIG options - see 'Automatic .dtsi inclusion' below.
+.. _binman_syms:
Access to binman entry offsets at run time (symbols) ----------------------------------------------------