binary-manager 0.0.7
Binman firmware-packaging tool
Requires Python: >=3.7

.. SPDX-License-Identifier: GPL-2.0+
.. Copyright (c) 2016 Google, Inc

Introduction
============

Firmware often consists of several components which must be packaged together.
For example, we may have SPL, U-Boot, a devicetree and an environment area
grouped together and placed in MMC flash. When the system starts, it must be
able to find these pieces.

Building firmware should be separate from packaging it. Many of the complexities
of modern firmware build systems come from trying to do both at once. With
binman, you build all the pieces that are needed, using whatever assortment of
projects and build systems are needed, then use binman to stitch everything
together.


What it does
------------

Binman reads your board's devicetree and finds a node which describes the
required image layout. It uses this to work out what to place where.

Binman provides a mechanism for building images, from simple SPL + U-Boot
combinations, to more complex arrangements with many parts. It also allows
users to inspect images, extract and replace binaries within them, repacking if
needed.


Features
--------

Apart from basic padding, alignment, and positioning features, Binman supports
hierarchical images, compression, hashing and dealing with the binary blobs,
which are a sad trend in open-source firmware at present.

Executable binaries can access the location of other binaries in an image by
using special linker symbols (zero-overhead but limited) or by reading
the devicetree description of the image.

Binman is designed primarily for use with U-Boot and associated binaries such
as ARM Trusted Firmware, but it is suitable for use with other projects, such
as Zephyr. Binman also provides facilities useful in Chromium OS, such as CBFS,
vblocks and the like.

Binman provides a way to process binaries before they are included, by adding a
Python plug-in.

Binman is intended for use with U-Boot but is designed to be general enough
to be useful in other image-packaging situations.


Motivation
----------

As mentioned above, packaging of firmware is quite a different task from
building the various parts. In many cases the various binaries which go into image
come from separate build systems. For example, ARM Trusted Firmware
is used on ARMv8 devices but is not built in the U-Boot tree. If a Linux kernel
is included in the firmware image, it is built elsewhere.

It is of course possible to add further build rules to the U-Boot
build system to cover these cases. It can shell out to other Makefiles and
build scripts. But it seems preferable to create a clear divide between building
software and packaging it.

At present this is handled by manual instructions, different for each board,
on how to create images that will boot. By turning these instructions into a
standard format, we can support making valid images for any board without
manual effort, lots of READMEs, etc.

Benefits:

  - Each binary can have its own build system and tool chain without creating
    any dependencies between them
  - Avoids the need for a single-shot build: individual parts can be updated
    and brought in as needed
  - Provides for a standard image description available in the build and at
    run-time
  - SoC-specific image-signing tools can be accommodated
  - Avoids cluttering the U-Boot build system with image-building code
  - The image description is automatically available at run-time in U-Boot,
    SPL. It can be made available to other software also
  - The image description is easily readable (a text file in devicetree
    format) and permits flexible packing of binaries


Terminology
-----------

Binman uses the following terms:

- image - an output file containing a firmware image
- binary - an input binary that goes into the image


Installation
------------

You can install binman using::

   pip install binary-manager

The name was chosen since binman conflicts with an existing package.

If you are using binman within the U-Boot tree, it may be easiest to add a
symlink from your local `~/.bin` directory to `/path/to/tools/binman/binman`.


Relationship to FIT
-------------------

FIT is U-Boot's official image format. It supports multiple binaries with
load / execution addresses, compression. It also supports verification
through hashing and RSA signatures.

FIT was originally designed to support booting a Linux kernel (with an
optional ramdisk) and devicetree chosen from assorted options in the FIT.
Now that U-Boot supports configuration via devicetree, it is possible to
load U-Boot from a FIT, with the devicetree chosen by SPL.

Binman considers FIT to be one of the binaries it can place in the image.

Where possible it is best to put as much as possible in the FIT, with binman
used to deal with cases not covered by FIT. Examples include initial
execution (since FIT itself does not have an executable header) and dealing
with device boundaries, such as the read-only/read-write separation in SPI
flash.

For U-Boot, binman should not be used to create ad-hoc images in place of
FIT.

Note that binman can itself 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
-----------------------

The mkimage tool provides a means to create a FIT. Traditionally it has
needed an image description file: a devicetree, like binman, but in a
different format. More recently it has started to support a '-f auto' mode
which can generate that automatically.

More relevant to binman, mkimage also permits creation of many SoC-specific
image types. These can be listed by running 'mkimage -T list'. Examples
include 'rksd', the Rockchip SD/MMC boot format. The mkimage tool is often
called from the U-Boot build system for this reason.

Binman considers the output files created by mkimage to be binary blobs
which it can place in an image. Binman does not replace the mkimage tool or
this purpose. It would be possible in some situations to create a new entry
type for the images in mkimage, but this would not add functionality. It
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
============

Example use of binman in U-Boot
-------------------------------

Binman aims to replace some of the ad-hoc image creation in the U-Boot
build system.

Consider sunxi. It has the following steps:

  #. It uses a custom mksunxiboot tool to build an SPL image called
     sunxi-spl.bin. This should better go into mkimage.

  #. It uses mkimage to package U-Boot into a legacy image file (so that it can
     hold the load and execution address) called u-boot.img.

  #. It builds a final output image called u-boot-sunxi-with-spl.bin which
     consists of sunxi-spl.bin, some padding and u-boot.img.

Binman is intended to replace the last step. The U-Boot build system builds
u-boot.bin and sunxi-spl.bin. Binman can then take over creation of
sunxi-spl.bin by calling mksunxiboot or mkimage. In any case, it would then
create the image from the component parts.

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 architectures are
converted to use binman properly.

As above, the term 'binary' is used for something in INPUTS-y and 'image' is
used for the things that binman creates. Hence, 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 few 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 for 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 slightly 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 incorporated, 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 environment 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 .

Taking this a little further, when binman is used to create a FIT, it supports
using an ELF file, e.g. `bl31.elf` and splitting it into separate pieces (with
`fit,operation = "split-elf"`), each with its own load address.


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.

Then, 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 input binaries are used in each case, you will of course you will
need to create your own binman command line, like that in `cmd_binman` in
the Makefile. You may find the -I and --toolpath options useful. The
devicetree 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 the devicetree 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 board needs to make changes, it can override properties in
the SoC file, just as it would for any other devicetree property. It can also
add an 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 = <CFG_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
no general 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 one or other being used by a particular board. This can help
reduce the need for having multiple defconfig targets, for boards where the
only difference is the boot media, enabling / disabling secure boot, etc.

Of course, you can use the devicetree 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 builds all the devicetree files associated with an
SoC. These are written in 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 devicetree binaries
and allow SPL to select the correct one on boot.

However, it is also possible to build separate images for each board, simply by
invoking binman multiple times, once for each devicetree file, using a
different output directory. This will produce one set of images for each board.


Example use of binman for x86
-----------------------------

In most cases x86 images have a lot of binary blobs, 'black-box' code
provided by Intel which must be run for the platform to work. Typically
these blobs are not relocatable and must be placed at fixed areas in the
firmware image.

Currently this is handled by ifdtool, which places microcode, FSP, MRC, VGA
BIOS, reference code and Intel ME binaries into a u-boot.rom file.

Binman is intended to replace all of this, with ifdtool left to handle only
the configuration of the Intel-format descriptor.


Installing binman
-----------------

First install prerequisites, e.g:

.. code-block:: bash

    sudo apt-get install python-pyelftools python3-pyelftools lzma-alone \
        liblz4-tool

You can run binman directly if you put it on your PATH. But if you want to
install into your `~/.local` Python directory, use:

.. code-block:: bash

    pip install tools/patman tools/dtoc tools/binman

Note that binman makes use of libraries from patman and dtoc, which is why these
need to be installed. Also you need `libfdt` and `pylibfdt` which can be
installed like this:

.. code-block:: bash

   git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
   cd dtc
   pip install .
   make NO_PYTHON=1 install

This installs the `libfdt.so` library into `~/lib` so you can use
`LD_LIBRARY_PATH=~/lib` when running binman. If you want to install it in the
system-library directory, replace the last line with:

.. code-block:: bash

   make NO_PYTHON=1 PREFIX=/ install

Running binman
--------------

Type:

.. code-block:: bash

   make NO_PYTHON=1 PREFIX=/ install
    binman build -b <board_name>

to build an image for a board. The board name is the same name used when
configuring U-Boot (e.g. for sandbox_defconfig the board name is 'sandbox').
Binman assumes that the input files for the build are in ../b/<board_name>.

Or you can specify this explicitly:

.. code-block:: bash

   make NO_PYTHON=1 PREFIX=/ install
    binman build -I <build_path>

where <build_path> is the build directory containing the output of the U-Boot
build.

(Future work will make this more configurable)

In either case, binman picks up the devicetree file (u-boot.dtb) and looks
for its instructions in the 'binman' node.

Binman has a few other options which you can see by running 'binman -h'.


Enabling binman for a board
---------------------------

At present binman is invoked from a rule in the main Makefile. You should be
able to enable CONFIG_BINMAN to enable this rule.

The output file is typically named image.bin and is in the output
directory. If input files are needed to you add these to INPUTS-y either in the
main Makefile or in a config.mk file in your arch subdirectory.

Once binman is executed it will pick up its instructions from a devicetree
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)
----------------------------------------------------

Binman assembles images and determines where each entry is placed in the image.
This information may be useful to U-Boot at run time. For example, in SPL it
is useful to be able to find the location of U-Boot so that it can be executed
when SPL is finished.

Binman allows you to declare symbols in the SPL image which are filled in
with their correct values during the build. For example:

.. code-block:: c

    binman_sym_declare(ulong, u_boot_any, image_pos);

declares a ulong value which will be assigned to the image-pos of any U-Boot
image (u-boot.bin, u-boot.img, u-boot-nodtb.bin) that is present in the image.
You can access this value with something like:

.. code-block:: c

    ulong u_boot_offset = binman_sym(ulong, u_boot_any, image_pos);

Thus u_boot_offset will be set to the image-pos of U-Boot in memory, assuming
that the whole image has been loaded or is available in flash. You can then
jump to that address to start U-Boot.

At present this feature is only supported in SPL and TPL. In principle it is
possible to fill in such symbols in U-Boot proper, as well, but a future C
library is planned for this instead, to read from the devicetree.

As well as image-pos, it is possible to read the size of an entry and its
offset (which is the start position of the entry within its parent).

A small technical note: Binman automatically adds the base address of the image
(i.e. __image_copy_start) to the value of the image-pos symbol, so that when the
image is loaded to its linked address; the value will be correct and actually
point into the image.

For example, say SPL is at the start of the image and linked to start at address
80108000. If U-Boot's image-pos is 0x8000 then binman will write an image-pos
for U-Boot of 80110000 into the SPL binary, since it assumes the image is loaded
to 80108000, with SPL at 80108000 and U-Boot at 80110000. In other words, the
positions are calculated relative to the start address of the image to which
they are being written.

For x86 devices (with the end-at-4gb property) this base address is not added
since it is assumed that images are XIP and the offsets already include the
address.

For non-x86 cases where the symbol is used as a flash offset, the symbols-base
property can be set to that offset (e.g. 0), so that the unadjusted image-pos
is written into the image.

While U-Boot's symbol updating is handled automatically by the u-boot-spl
entry type (and others), it is possible to use this feature with any blob. To
do this, add a `write-symbols` (boolean) property to the node, set the ELF
filename using `elf-filename` and set 'elf-base-sym' to the base symbol for the
start of the binary image (this defaults to `__image_copy_start` which is what
U-Boot uses). See `testBlobSymbol()` for an example.

.. _binman_fdt:

Access to binman entry offsets at run time (fdt)
------------------------------------------------

Binman can update the U-Boot FDT to include the final position and size of
each entry in the images it processes. The option to enable this is -u and it
causes binman to make sure that the 'offset', 'image-pos' and 'size' properties
are set correctly for every entry. Since it is not necessary to specify these in
the image definition, binman calculates the final values and writes these to
the devicetree. These can be used by U-Boot at run-time to find the location
of each entry.

Alternatively, an FDT map entry can be used to add a special FDT containing
just the information about the image. This is preceded by a magic string so can
be located anywhere in the image. An image header (typically at the start or end
of the image) can be used to point to the FDT map. See fdtmap and image-header
entries for more information.

Map files
---------

The -m option causes binman to output a .map file for each image that it
generates. This shows the offset and size of each entry. For example::

      Offset      Size  Name
    00000000  00000028  main-section
     00000000  00000010  section@0
      00000000  00000004  u-boot
     00000010  00000010  section@1
      00000000  00000004  u-boot

This shows a hierarchical image with two sections, each with a single entry. The
offsets of the sections are absolute hex byte offsets within the image. The
offsets of the entries are relative to their respective sections. The size of
each entry is also shown, in bytes (hex). The indentation shows the entries
nested inside their sections.


Passing command-line arguments to entries
-----------------------------------------

Sometimes it is useful to pass binman the value of an entry property from the
command line. For example, some entries need access to files, and it is not
always convenient to put these filenames in the image definition (devicetree).

The -a option supports this::

    -a <prop>=<value>

where::

    <prop> is the property to set
    <value> is the value to set it to

Not all properties can be provided this way. Only some entries support it,
typically for filenames.


Image description format
========================

The binman node is called 'binman'. An example image description is shown
below::

    binman {
        filename = "u-boot-sunxi-with-spl.bin";
        pad-byte = <0xff>;
        blob {
            filename = "spl/sunxi-spl.bin";
        };
        u-boot {
            offset = <CONFIG_SPL_PAD_TO>;
        };
    };


This requests binman to create an image file called u-boot-sunxi-with-spl.bin
consisting of a specially formatted SPL (spl/sunxi-spl.bin, built by the
normal U-Boot Makefile), some 0xff padding, and a U-Boot legacy image. The
padding comes from the fact that the second binary is placed at
CONFIG_SPL_PAD_TO. If that line were omitted, then the U-Boot binary would
immediately follow the SPL binary.

The binman node describes an image. The sub-nodes describe entries in the
image. Each entry represents a region within the overall image. The name of
the entry (blob, u-boot) tells binman what to put there. For 'blob' we must
provide a filename. For 'u-boot', binman knows that this means 'u-boot.bin'.

Entries are normally placed into the image sequentially, one after the other.
The image size is the total size of all entries. As you can see, you can
specify the start offset of an entry using the 'offset' property.

Note that due to a devicetree requirement, all entries must have a unique
name. If you want to put the same binary in the image multiple times, you can
use any unique name, with the 'type' property providing the type.

The attributes supported for entries are described below.

offset:
    This sets the offset of an entry within the image or section containing
    it. The first byte of the image is normally at offset 0. If 'offset' is
    not provided, binman sets it to the end of the previous region, or the
    start of the image's entry area (normally 0) if there is no previous
    region.

align:
    This sets the alignment of the entry. The entry offset is adjusted
    so that the entry starts on an aligned boundary within the containing
    section or image. For example, 'align = <16>' means that the entry will
    start on a 16-byte boundary. This may mean that padding is added before
    the entry. The padding is part of the containing section but is not
    included in the entry, meaning that an empty space may be created before
    the entry starts. Alignment should be a power of 2. If 'align' is not
    provided, no alignment is performed.

size:
    This sets the size of the entry. The contents will be padded out to
    this size. If this is not provided, it will be set to the size of the
    contents.

min-size:
    Sets the minimum size of the entry. This size includes explicit padding
    ('pad-before' and 'pad-after'), but not padding added to meet alignment
    requirements. While this does not affect the contents of the entry within
    binman itself (the padding is performed only when its parent section is
    assembled), the result will be that the entry ends with the padding
    bytes, so may grow. Defaults to 0.

pad-before:
    Padding before the contents of the entry. Normally this is 0, meaning
    that the contents start at the beginning of the entry. This can be used
    to offset the entry contents a little. While this does not affect the
    contents of the entry within binman itself (the padding is performed
    only when its parent section is assembled), the result will be that
    the entry starts with the padding bytes, so it may grow. Defaults to 0.

pad-after:
    Padding after the contents of the entry. Normally this is 0, meaning
    that the entry ends at the last byte of content (unless adjusted by
    other properties). This allows room to be created in the image for
    this entry to expand later. While this does not affect the contents of
    the entry within binman itself (the padding is performed only when its
    parent section is assembled), the result will be that the entry ends
    with the padding bytes, so may grow. Defaults to 0.

align-size:
    This sets the alignment of the entry size. For example, to ensure
    that the size of an entry is a multiple of 64 bytes, set this to 64.
    While this does not affect the contents of the entry within binman
    itself (the padding is performed only when its parent section is
    assembled), the result is that the entry ends with the padding
    bytes, so may grow. If 'align-size' is not provided, no alignment is
    performed.

align-end:
    This sets the alignment of the end of an entry with respect to the
    containing section. Some entries require that they end on an alignment
    boundary, regardless of where they start. This does not move the start
    of the entry, so the contents of the entry will still start at the
    beginning. But there may be padding at the end. While this does not
    affect the contents of the entry within binman itself (the padding is
    performed only when its parent section is assembled), the result
    is that the entry ends with the padding bytes, so may grow.
    If 'align-end' is not provided, no alignment is performed.

filename:
    For 'blob' types this provides the filename containing the binary to
    put into the entry. If binman knows about the entry type (like
    u-boot-bin), then there is no need to specify this.

type:
    Sets the type of an entry. This defaults to the entry name, but it is
    possible to use any name, and then add (for example) 'type = "u-boot"'
    to specify the type.

offset-unset:
    Indicates that the offset of this entry should not be set by placing
    it immediately after the entry before. Instead, is set by another
    entry which knows where this entry should go. When this boolean
    property is present, binman will give an error if another entry does
    not set the offset (with the GetOffsets() method).

image-pos:
    This cannot be set on entry (or at least it is ignored if it is), but
    with the -u option, binman will set it to the absolute image position
    for each entry. This makes it easy to find out exactly where the entry
    ended up in the image, regardless of parent sections, etc.

extend-size:
    Extend the size of this entry to fit available space. This space is only
    limited by the size of the image/section and the position of the next
    entry.

compress:
    Sets the compression algorithm to use (for blobs only). See the entry
    documentation for details.

missing-msg:
    Sets the tag of the message to show if this entry is missing. This is
    used for external blobs. When they are missing it is helpful to show
    information about what needs to be fixed. See missing-blob-help for the
    message for each tag.

assume-size:
    Sets the assumed size of a blob entry if it is missing. This allows for a
    check that the rest of the image fits into the available space, even when
    the contents are not available. If the entry is missing, Binman will use
    this assumed size for the entry size, including creating a fake file of that
    size if requested.

no-expanded:
    By default, binman substitutes entries with expanded versions if available,
    so that a `u-boot` entry type turns into `u-boot-expanded`, for example. The
    `--no-expanded` command-line option disables this globally. The
    `no-expanded` property disables this just for a single entry. Put the
    `no-expanded` boolean property in the node to select this behavior.

optional:
    External blobs are normally required to be present for the image to be
    built (but see `External blobs`_). This properly allows an entry to be
    optional, so that when it cannot be found, this problem is ignored and
    an empty file is used for this blob. This should be used only when the blob
    is entirely optional and is not needed for correct operation of the image.
    Note that missing, optional blobs do not produce a non-zero exit code from
    binman, although it does show a warning about the missing external blob.

insert-template:
    This is not an entry property, since it is processed early
    in Binman before the entries are read. It is a list of phandles of nodes to
    include in the current (target) node. For each node, its subnodes and their
    properties are brought into the target node. See Templates_ below for
    more information.

symbols-base:
    When writing symbols into a binary, the value of that symbol is assumed to
    be relative to the base address of the binary. This allow the binary to be
    loaded in memory at its base address, so that symbols point into the binary
    correctly. In some cases, the binary is in fact not yet in memory, but must
    be read from storage. In this case there is no base address for the symbols.
    This property can be set to 0 to indicate this. Other values for
    symbols-base are allowed, but care must be taken that the code which uses
    the symbol is aware of the base being used. If omitted, the binary's base
    address is used.

The attributes supported for images and sections are described below. Several
of them are like the attributes for entries.

size:
    Sets the image size in bytes, for example 'size = <0x100000>' for a
    1MB image.

offset:
    This is like 'offset' in entries, setting the offset of a section
    within the image or section containing it. The first byte of the section
    is normally at offset 0. If 'offset' is not provided, binman sets it to
    the end of the previous region, or the start of the image's entry area
    (normally 0) if there is no previous region.

align-size:
    This sets the alignment of the image size. For example, to ensure
    that the image ends on a 512-byte boundary, use 'align-size = <512>'.
    If 'align-size' is not provided, no alignment is performed.

pad-before:
    This sets the padding before the image entries. The first entry will
    be positioned after the padding. This defaults to 0.

pad-after:
    This sets the padding after the image entries. The padding will be
    placed after the last entry. This defaults to 0.

pad-byte:
    This specifies the pad byte to use when padding in the image. It
    defaults to 0. To use 0xff, you would add 'pad-byte = <0xff>'.

filename:
    This specifies the image filename. It defaults to 'image.bin'.

sort-by-offset:
    This causes binman to reorder the entries as needed to make sure they
    are in increasing positional order. This can be used when your entry
    order may not match the positional order. A common situation is where
    the 'offset' properties are set by CONFIG options, so their ordering is
    not known a priori.

    This is a boolean property, so it needs no value. To enable it, add a
    line 'sort-by-offset;' to your description.

multiple-images:
    Normally only a single image is generated. To create more than one
    image, put this property in the binman node. For example, this will
    create image1.bin containing u-boot.bin, and image2.bin containing
    both spl/u-boot-spl.bin and u-boot.bin::

        binman {
            multiple-images;
            image1 {
                u-boot {
                };
            };

            image2 {
                spl {
                };
                u-boot {
                };
            };
        };

align-default:
    Specifies the default alignment for entries in this section if they do
    not specify an alignment. Note that this only applies to top-level entries
    in the section (direct subentries), not any subentries of those entries.
    This means that each section must specify its own default alignment, if
    required.

symlink:
    Adds a symlink to the image with string given in the symlink property.

overlap:
    Indicates that this entry overlaps with others in the same section. These
    entries should appear at the end of the section. Overlapping entries are not
    packed with other entries, but their contents are written over other entries
    in the section. Overlapping entries must have an explicit offset and size.

write-symbols:
    Indicates that the blob should be updated with symbol values calculated by
    binman. This is automatic for certain entry types, e.g. `u-boot-spl`. See
    binman_syms_ for more information.

no-write-symbols:
    Disables symbol writing for this entry. This can be used in entry types
    where symbol writing is automatic. For example, if `u-boot-spl` refers to
    the `u_boot_any_image_pos` symbol but U-Boot is not available in the image
    containing SPL, this can be used to disable the writing. Quite likely this
    indicates a bug in your setup.

elf-filename:
    Sets the file name of a blob's associated ELF file. For example, if the
    blob is `zephyr.bin` then the ELF file may be `zephyr.elf`. This allows
    binman to locate symbols and understand the structure of the blob. See
    binman_syms_ for more information.

elf-base-sym:
    Sets the name of the ELF symbol that points to the start of a blob. For
    U-Boot this is `__image_copy_start` and that is the default used by binman
    if this property is missing. For other projects, a difference symbol may be
    needed. Add this symbol to the properties for the blob so that symbols can
    be read correctly. See binman_syms_ for more information.

offset-from-elf:
    Sets the offset of an entry based on a symbol value in another entry.
    The format is <&phandle>, "sym_name", <offset> where phandle is the entry
    containing the blob (with associated ELF file providing symbols), <sym_name>
    is the symbol to lookup (relative to elf-base-sym) and <offset> is an offset
    to add to that value.

preserve:
    Indicates that this entry should be preserved by any firmware updates. This
    flag should be checked by the updater when it is deciding which entries to
    update. This flag is normally attached to sections but can be attached to
    a single entry in a section if the updater supports it. Not that binman
    itself has no control over the updater's behavior, so this is just a
    signal. It is not enforced by binman.

Examples of the above options can be found in the tests. See the
tools/binman/test directory.

It is possible to have the same binary appear multiple times in the image,
either by using a unit number suffix (u-boot@0, u-boot@1) or by using a
different name for each and specifying the type with the 'type' attribute.


Sections and hierarchical images
--------------------------------

Sometimes it is convenient to split an image into several pieces, each of which
contains its own set of binaries. An example is a flash device where part of
the image is read-only, and part is read-write. We can set up sections for each
of these, and place binaries in them independently. The image is still produced
as a single output file.

This feature provides a way of creating hierarchical images. For example, here
is an example image with two copies of U-Boot. One is read-only (ro), intended
to be written only in the factory. Another is read-write (rw), so that it can be
upgraded in the field. The sizes are fixed so that the ro/rw boundary is known
and can be programmed::

    binman {
        section@0 {
            read-only;
            name-prefix = "ro-";
            size = <0x100000>;
            u-boot {
            };
        };
        section@1 {
            name-prefix = "rw-";
            size = <0x100000>;
            u-boot {
            };
        };
    };

This image could be placed into a SPI flash chip, with the protection boundary
set at 1MB.

A few special properties are provided for sections:

read-only:
    Indicates that this section is read-only. This has no impact on binman's
    operation, but his property can be read at run time.

name-prefix:
    This string is prepended to all the names of the binaries in the
    section. In the example above, the 'u-boot' binaries will be
    renamed to 'ro-u-boot' and 'rw-u-boot'. This can be useful to
    distinguish binaries with otherwise identical names.

filename:
    This allows the contents of the section to be written to a file in the
    output directory. This can sometimes be useful to use the data in one
    section in different image, since there is currently no way to share data
    between images other than through files.

end-at-4gb:
    For x86 machines the ROM offsets start just before 4GB and extend
    up so that the image finished at the 4GB boundary. This boolean
    option can be enabled to support this. The image size must be
    provided so that binman knows when the image should start. For an
    8MB ROM, the offset of the first entry would be 0xfff80000 with
    this option, instead of 0 without this option.

skip-at-start:
    This property specifies the entry offset of the first entry in the section.