Am 13. Mai 2026 04:09:29 MESZ schrieb Daniel Golle <[email protected]>:
>Add documentation for CONFIG_FIT_VERITY which allows U-Boot to
>construct dm-mod.create= and dm-mod.waitfor= kernel command-line
>parameters from dm-verity metadata embedded in FIT filesystem
>sub-images.
>
>The new document covers the relationship between FIT loadable indices
>and the /dev/fitN block devices that the Linux uImage.FIT block driver
>creates, provides a complete .its example with a dm-verity-protected
>SquashFS root filesystem, describes all required and optional dm-verity
>subnode properties and explains how mkimage generates the verity
>metadata automatically.
>
>dm-verity is only supported for external-data FIT images (mkimage -E);
>mkimage aborts with an error if the flag is omitted.
>
>Signed-off-by: Daniel Golle <[email protected]>
>Reviewed-by: Simon Glass <[email protected]>
>---
>v4: no changes
>v3: clarify that hash-start-block only equals num-data-blocks when
>    data-block-size == hash-block-size; in the general case it is
>    data_size / hash-block-size
>v2: trim minimal .its example to user-provided properties only and
>    remove stale references to a verity superblock
>
> doc/usage/fit/dm-verity.rst | 284 ++++++++++++++++++++++++++++++++++++
> doc/usage/fit/index.rst     |   1 +
> 2 files changed, 285 insertions(+)
> create mode 100644 doc/usage/fit/dm-verity.rst
>
>diff --git a/doc/usage/fit/dm-verity.rst b/doc/usage/fit/dm-verity.rst
>new file mode 100644
>index 00000000000..eddce9e7cf7
>--- /dev/null
>+++ b/doc/usage/fit/dm-verity.rst
>@@ -0,0 +1,284 @@
>+.. SPDX-License-Identifier: GPL-2.0+
>+
>+FIT dm-verity Boot Parameters
>+=============================
>+
>+Introduction
>+------------
>+
>+Linux's dm-verity device-mapper target provides transparent integrity
>+checking of block devices using a Merkle tree. It is commonly used to
>+protect read-only root filesystems such as SquashFS images.
>+
>+When a FIT image packages the root filesystem as a loadable sub-image of
>+type ``filesystem`` (``IH_TYPE_FILESYSTEM``), the verity metadata can be
>+stored alongside the image data in a ``dm-verity`` subnode. U-Boot reads
>+this metadata at boot time and generates the kernel command-line parameters
>+that Linux needs to activate the verity target, eliminating the need for
>+an initramfs or userspace helper to set up dm-verity.
>+
>+This feature is enabled by ``CONFIG_FIT_VERITY`` (see ``boot/Kconfig``).
>+
>+Prerequisites
>+-------------
>+
>+* **Linux uImage.FIT block driver** – the kernel must include the FIT block
>+  driver that exposes loadable sub-images as ``/dev/fit0``, ``/dev/fit1``,


The dtb file format of FIT images only guarantees 4 byte alignment. Does that 
match with the requirement of file-system drivers including dma access if the 
FIT is for example on eMMC? Or do we need a mechanism to enforce higher 
alignment in FIT images?

Best regards

Heinrich


>+  etc.  The driver assigns device numbers in the order loadables appear in
>+  the FIT configuration.
>+
>+* **dm-verity support in the kernel** – ``CONFIG_DM_VERITY`` must be
>+  enabled so the kernel can process the ``dm-mod.create=`` parameter.
>+
>+* **CONFIG_FIT_VERITY** enabled in U-Boot.
>+
>+How it works
>+------------
>+
>+The implementation is split into a **build** phase and an **apply** phase,
>+both of which run automatically within the ``bootm`` state machine. No boot
>+method needs to call verity functions explicitly.
>+
>+**Build phase** (``BOOTM_STATE_FINDOTHER`` → ``boot_get_loadable()``)
>+
>+1. After all loadable sub-images have been loaded,
>+   ``fit_verity_build_cmdline()`` iterates the configuration's
>+   ``loadables`` list.
>+
>+2. For each loadable that is an ``IH_TYPE_FILESYSTEM`` image **and**
>+   contains a ``dm-verity`` child node, a dm-verity target specification is
>+   built by the helper ``fit_verity_build_target()``.
>+
>+3. The dm-verity target references ``/dev/fitN``, where *N* is the
>+   zero-based index of the loadable in the configuration.  This matches the
>+   numbering used by the Linux FIT block driver.
>+
>+4. The resulting fragments are stored in ``struct bootm_headers``:
>+
>+   ``images->dm_mod_create``
>+     The full dm-verity target table. Multiple targets are separated by ``;``.
>+
>+   ``images->dm_mod_waitfor``
>+     Comma-separated list of ``/dev/fitN`` devices so the kernel waits for
>+     the underlying FIT block devices to appear before activating
>+     device-mapper.
>+
>+**Apply phase** (``BOOTM_STATE_OS_PREP``)
>+
>+5. Just before ``bootm_process_cmdline_env()`` processes the ``bootargs``
>+   environment variable, ``fit_verity_apply_bootargs()`` appends the
>+   ``dm-mod.create=`` and ``dm-mod.waitfor=`` parameters.
>+
>+**Bootmeth integration**
>+
>+  Because the fragments are stored in ``struct bootm_headers``, a boot
>+  method can check ``fit_verity_active(images)`` between bootm state
>+  invocations. A typical pattern splits ``bootm_run_states()`` into two
>+  calls -- one for ``START|FINDOS|FINDOTHER|LOADOS`` and one for
>+  ``OS_PREP|OS_GO`` -- and inspects ``fit_verity_active()`` in
>+  between to decide whether to add a ``root=`` parameter pointing at the
>+  dm-verity device.
>+
>+FIT image source (.its) example
>+-------------------------------
>+
>+Below is a minimal ``.its`` file showing a kernel and a dm-verity-protected
>+root filesystem packaged as a FIT. Only the three user-provided properties
>+(``algo``, ``data-block-size``, ``hash-block-size``) are included; ``mkimage``
>+computes and fills in ``digest``, ``salt``, ``num-data-blocks``, and
>+``hash-start-block`` automatically (see `Generating verity metadata`_ below)::
>+
>+    /dts-v1/;
>+
>+    / {
>+        description = "Kernel + dm-verity rootfs";
>+        #address-cells = <1>;
>+
>+        images {
>+            kernel {
>+                description = "Linux kernel";
>+                data = /incbin/("./Image.gz");
>+                type = "kernel";
>+                arch = "arm64";
>+                os = "linux";
>+                compression = "gzip";
>+                load = <0x44000000>;
>+                entry = <0x44000000>;
>+                hash-1 {
>+                    algo = "sha256";
>+                };
>+            };
>+
>+            fdt {
>+                description = "Device tree blob";
>+                data = /incbin/("./board.dtb");
>+                type = "flat_dt";
>+                arch = "arm64";
>+                compression = "none";
>+                hash-1 {
>+                    algo = "sha256";
>+                };
>+            };
>+
>+            rootfs {
>+                description = "SquashFS root filesystem";
>+                data = /incbin/("./rootfs.squashfs");
>+                type = "filesystem";
>+                arch = "arm64";
>+                compression = "none";
>+                hash-1 {
>+                    algo = "sha256";
>+                };
>+
>+                dm-verity {
>+                    algo = "sha256";
>+                    data-block-size = <4096>;
>+                    hash-block-size = <4096>;
>+                };
>+            };
>+        };
>+
>+        configurations {
>+            default = "config-1";
>+            config-1 {
>+                description = "Boot with dm-verity rootfs";
>+                kernel = "kernel";
>+                fdt = "fdt";
>+                loadables = "rootfs";
>+            };
>+        };
>+    };
>+
>+With this configuration U-Boot produces a kernel command line similar to::
>+
>+    dm-mod.create="rootfs,,, ro,0 <data_sectors> verity 1 \
>+        /dev/fit0 /dev/fit0 4096 4096 3762 3762 sha256 \
>+        8e6791637f93cbb81fc45299e203cbe85ca2e47a38f5051bddeece92d7b1c9f9 \
>+        aa7b11f8db8fe2e5bfd4eca1d18a22b5de7ea39d2e1b93bb7272ce0c6ca3cc8e" \
>+    dm-mod.waitfor=/dev/fit0
>+
>+dm-verity subnode properties
>+----------------------------
>+
>+User-provided properties (required in the ``.its``):
>+
>+.. list-table::
>+   :header-rows: 1
>+   :widths: 20 15 65
>+
>+   * - Property
>+     - Type
>+     - Description
>+   * - ``algo``
>+     - string
>+     - Hash algorithm name, e.g. ``"sha256"``.
>+   * - ``data-block-size``
>+     - u32
>+     - Data block size in bytes (>= 512, typically 4096).
>+   * - ``hash-block-size``
>+     - u32
>+     - Hash block size in bytes (>= 512, typically 4096).
>+
>+Computed properties (filled in by ``mkimage``):
>+
>+.. list-table::
>+   :header-rows: 1
>+   :widths: 20 15 65
>+
>+   * - Property
>+     - Type
>+     - Description
>+   * - ``num-data-blocks``
>+     - u32
>+     - Number of data blocks in the filesystem image (computed from the
>+       image size and ``data-block-size``).
>+   * - ``hash-start-block``
>+     - u32
>+     - Offset in ``hash-block-size``-sized blocks from the start of the
>+       sub-image to the root block of the hash tree.
>+   * - ``digest``
>+     - byte array
>+     - Root hash of the Merkle tree, stored as raw bytes. Length must match
>+       the output size of ``algo``.
>+   * - ``salt``
>+     - byte array
>+     - Salt used when computing the Merkle tree, stored as raw bytes.
>+
>+These values are the same ones produced by ``veritysetup format`` and can
>+typically be obtained from its output.
>+The ``digest`` and ``salt`` byte arrays correspond to the hex-encoded
>+``Root hash`` and ``Salt`` printed by ``veritysetup format``.
>+
>+Optional boolean properties (when present, they are collected and appended
>+as dm-verity optional parameters with hyphens converted to underscores):
>+
>+.. list-table::
>+   :header-rows: 1
>+   :widths: 30 70
>+
>+   * - Property
>+     - Description
>+   * - ``restart-on-corruption``
>+     - Restart the system on data corruption.
>+   * - ``panic-on-corruption``
>+     - Panic the system on data corruption.
>+   * - ``restart-on-error``
>+     - Restart the system on I/O error.
>+   * - ``panic-on-error``
>+     - Panic the system on I/O error.
>+   * - ``check-at-most-once``
>+     - Verify data blocks only on first read.
>+
>+
>+Generating verity metadata
>+--------------------------
>+
>+``mkimage`` automates the entire process. When it encounters a
>+``dm-verity`` subnode, it:
>+
>+1. Writes the embedded image data to a temporary file.
>+2. Runs ``veritysetup format`` with the user-supplied algorithm and
>+   block sizes.
>+3. Parses ``Root hash`` and ``Salt`` from ``veritysetup`` stdout.
>+4. Reads back the expanded file (original data + Merkle hash tree) and
>+   replaces the image's ``data`` property.
>+5. Writes the computed ``digest``, ``salt``, ``num-data-blocks``, and
>+   ``hash-start-block`` properties into the ``dm-verity`` subnode.
>+
>+Images with ``dm-verity`` subnodes **must** use external data layout
>+(``mkimage -E``). ``mkimage`` will abort with an error if ``-E`` is
>+not specified.
>+
>+Usage::
>+
>+    # Create the filesystem image
>+    mksquashfs rootfs/ rootfs.squashfs -comp xz
>+
>+    # Build the FIT (dm-verity is computed automatically)
>+    mkimage -E -f image.its image.itb
>+
>+``veritysetup`` (from the cryptsetup_ package) must be installed on
>+the build host.
>+
>+.. _cryptsetup: https://gitlab.com/cryptsetup/cryptsetup
>+
>+.. note::
>+
>+   ``veritysetup format`` is invoked with ``--no-superblock``, so no
>+   on-disk superblock is written between the data and hash regions.
>+   The Merkle hash tree is appended directly to the image data within
>+   the FIT external data section.  ``hash-start-block`` is therefore
>+   computed as ``data_size / hash-block-size`` (the offset of the hash
>+   region in units of ``hash-block-size``).  When ``data-block-size``
>+   equals ``hash-block-size`` this happens to equal ``num-data-blocks``.
>+
>+Kconfig
>+-------
>+
>+``CONFIG_FIT_VERITY``
>+  Depends on ``CONFIG_FIT`` and ``CONFIG_OF_LIBFDT``.
>+  When enabled, ``fit_verity_build_cmdline()`` and
>+  ``fit_verity_apply_bootargs()`` are compiled into the boot path.
>+  When disabled, the functions are static inlines returning 0, so there
>+  is no code-size impact.  Works with both the ``bootm`` command and
>+  BOOTSTD boot methods.
>diff --git a/doc/usage/fit/index.rst b/doc/usage/fit/index.rst
>index 6c78d8584ed..d17582b1d64 100644
>--- a/doc/usage/fit/index.rst
>+++ b/doc/usage/fit/index.rst
>@@ -11,6 +11,7 @@ images that it reads and boots. Documentation about FIT is 
>available in
>     :maxdepth: 1
> 
>     beaglebone_vboot
>+    dm-verity
>     howto
>     kernel_fdt
>     kernel_fdts_compressed

Reply via email to