{"id":2218921,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2218921/?format=json","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/1.0/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<d9c5939cd5b644daf950ee6e792b13484fada321.1775099118.git.daniel@makrotopia.org>","date":"2026-04-02T03:09:12","name":"[4/4] doc: fit: add dm-verity boot parameter documentation","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"81dc8d50434625ab7a62ce479c301210a52a9cdc","submitter":{"id":64091,"url":"http://patchwork.ozlabs.org/api/1.0/people/64091/?format=json","name":"Daniel Golle","email":"daniel@makrotopia.org"},"delegate":{"id":3651,"url":"http://patchwork.ozlabs.org/api/1.0/users/3651/?format=json","username":"trini","first_name":"Tom","last_name":"Rini","email":"trini@ti.com"},"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/d9c5939cd5b644daf950ee6e792b13484fada321.1775099118.git.daniel@makrotopia.org/mbox/","series":[{"id":498423,"url":"http://patchwork.ozlabs.org/api/1.0/series/498423/?format=json","date":"2026-04-02T03:08:27","name":"fit: dm-verity support","version":1,"mbox":"http://patchwork.ozlabs.org/series/498423/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2218921/checks/","tags":{},"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=makrotopia.org","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=makrotopia.org","phobos.denx.de;\n spf=pass smtp.mailfrom=daniel@makrotopia.org"],"Received":["from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fmRfk1Tqnz1yFv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 14:09:50 +1100 (AEDT)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id A017C84101;\n\tThu,  2 Apr 2026 05:09:40 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id D9EEB840CB; Thu,  2 Apr 2026 05:09:32 +0200 (CEST)","from pidgin.makrotopia.org (pidgin.makrotopia.org\n [IPv6:2a07:2ec0:3002::65])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 11D23840B0\n for <u-boot@lists.denx.de>; Thu,  2 Apr 2026 05:09:29 +0200 (CEST)","from local\n by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)\n (Exim 4.99) (envelope-from <daniel@makrotopia.org>)\n id 1w88Ql-000000007hy-3ski; Thu, 02 Apr 2026 03:09:16 +0000"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-1.9 required=5.0 tests=BAYES_00,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2","Date":"Thu, 2 Apr 2026 04:09:12 +0100","From":"Daniel Golle <daniel@makrotopia.org>","To":"Tom Rini <trini@konsulko.com>, Quentin Schulz <quentin.schulz@cherry.de>,\n Kory Maincent <kory.maincent@bootlin.com>, Simon Glass <sjg@chromium.org>,\n Mattijs Korpershoek <mkorpershoek@kernel.org>, Peng Fan <peng.fan@nxp.com>,\n Marek Vasut <marek.vasut+renesas@mailbox.org>,\n Daniel Golle <daniel@makrotopia.org>, Martin Schwan <m.schwan@phytec.de>,\n Anshul Dalal <anshuld@ti.com>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Sughosh Ganu <sughosh.ganu@arm.com>,\n =?utf-8?b?54mbIOW/l+Wujw==?= <Zone.Niuzh@hotmail.com>,\n Benjamin ROBIN <dev@benjarobin.fr>, Aristo Chen <jj251510319013@gmail.com>,\n James Hilliard <james.hilliard1@gmail.com>,\n Frank Wunderlich <frank-w@public-files.de>,\n Mayuresh Chitale <mchitale@ventanamicro.com>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Wolfgang Wallner <wolfgang.wallner@at.abb.com>,\n Rasmus Villemoes <ravi@prevas.dk>, Francois Berder <fberder@outlook.fr>,\n Shiji Yang <yangshiji66@outlook.com>, u-boot@lists.denx.de","Subject":"[PATCH 4/4] doc: fit: add dm-verity boot parameter documentation","Message-ID":"\n <d9c5939cd5b644daf950ee6e792b13484fada321.1775099118.git.daniel@makrotopia.org>","References":"<cover.1775099118.git.daniel@makrotopia.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<cover.1775099118.git.daniel@makrotopia.org>","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"Add documentation for CONFIG_FIT_VERITY which allows U-Boot to\nconstruct dm-mod.create= and dm-mod.waitfor= kernel command-line\nparameters from dm-verity metadata embedded in FIT filesystem\nsub-images.\n\nThe new document covers the relationship between FIT loadable indices\nand the /dev/fitN block devices that the Linux uImage.FIT block driver\ncreates, provides a complete .its example with a dm-verity-protected\nSquashFS root filesystem, describes all required and optional dm-verity\nsubnode properties and explains how mkimage generates the verity\nmetadata automatically.\n\ndm-verity is only supported for external-data FIT images (mkimage -E);\nmkimage aborts with an error if the flag is omitted.\n\nSigned-off-by: Daniel Golle <daniel@makrotopia.org>\n---\n doc/usage/fit/dm-verity.rst | 279 ++++++++++++++++++++++++++++++++++++\n doc/usage/fit/index.rst     |   1 +\n 2 files changed, 280 insertions(+)\n create mode 100644 doc/usage/fit/dm-verity.rst","diff":"diff --git a/doc/usage/fit/dm-verity.rst b/doc/usage/fit/dm-verity.rst\nnew file mode 100644\nindex 00000000000..99f9ea66286\n--- /dev/null\n+++ b/doc/usage/fit/dm-verity.rst\n@@ -0,0 +1,279 @@\n+.. SPDX-License-Identifier: GPL-2.0+\n+\n+FIT dm-verity Boot Parameters\n+=============================\n+\n+Introduction\n+------------\n+\n+Linux's dm-verity device-mapper target provides transparent integrity\n+checking of block devices using a Merkle tree.  It is commonly used to\n+protect read-only root filesystems such as SquashFS images.\n+\n+When a FIT image packages the root filesystem as a loadable sub-image of\n+type ``filesystem`` (``IH_TYPE_FILESYSTEM``), the verity metadata can be\n+stored alongside the image data in a ``dm-verity`` subnode.  U-Boot reads\n+this metadata at boot time and generates the kernel command-line parameters\n+that Linux needs to activate the verity target, eliminating the need for\n+an initramfs or userspace helper to set up dm-verity.\n+\n+This feature is enabled by ``CONFIG_FIT_VERITY`` (see ``boot/Kconfig``).\n+\n+Prerequisites\n+-------------\n+\n+* **Linux uImage.FIT block driver** – the kernel must include the FIT block\n+  driver that exposes loadable sub-images as ``/dev/fit0``, ``/dev/fit1``,\n+  etc.  The driver assigns device numbers in the order loadables appear in\n+  the FIT configuration.\n+\n+* **dm-verity support in the kernel** – ``CONFIG_DM_VERITY`` must be\n+  enabled so the kernel can process the ``dm-mod.create=`` parameter.\n+\n+* **CONFIG_FIT_VERITY** enabled in U-Boot.\n+\n+How it works\n+------------\n+\n+The implementation is split into a **build** phase and an **apply** phase,\n+both of which run automatically within the ``bootm`` state machine.  No\n+boot method needs to call verity functions explicitly.\n+\n+**Build phase** (``BOOTM_STATE_FINDOTHER`` → ``boot_get_loadable()``)\n+\n+1. After all loadable sub-images have been loaded,\n+   ``fit_verity_build_cmdline()`` iterates the configuration's\n+   ``loadables`` list.\n+\n+2. For each loadable that is an ``IH_TYPE_FILESYSTEM`` image **and**\n+   contains a ``dm-verity`` child node, a dm-verity target specification is\n+   built by the helper ``fit_verity_build_target()``.\n+\n+3. The dm-verity target references ``/dev/fitN``, where *N* is the\n+   zero-based index of the loadable in the configuration.  This matches the\n+   numbering used by the Linux FIT block driver.\n+\n+4. The resulting fragments are stored in ``struct bootm_headers``:\n+\n+   ``images->dm_mod_create``\n+     The full dm-verity target table.  Multiple targets are separated by\n+     ``;``.\n+\n+   ``images->dm_mod_waitfor``\n+     Comma-separated list of ``/dev/fitN`` devices so the kernel waits for\n+     the underlying FIT block devices to appear before activating\n+     device-mapper.\n+\n+**Apply phase** (``BOOTM_STATE_OS_PREP``)\n+\n+5. Just before ``bootm_process_cmdline_env()`` processes the ``bootargs``\n+   environment variable, ``fit_verity_apply_bootargs()`` appends the\n+   ``dm-mod.create=`` and ``dm-mod.waitfor=`` parameters.\n+\n+**Bootmeth integration**\n+\n+  Because the fragments are stored in ``struct bootm_headers``, a boot\n+  method can check ``fit_verity_active(images)`` between bootm state\n+  invocations.  A typical pattern splits ``bootm_run_states()`` into two\n+  calls -- one for ``START|FINDOS|FINDOTHER|LOADOS`` and one for\n+  ``OS_PREP|OS_GO`` -- and inspects ``fit_verity_active()`` in\n+  between to decide whether to add a ``root=`` parameter pointing at the\n+  dm-verity device.\n+\n+FIT image source (.its) example\n+-------------------------------\n+\n+Below is a minimal ``.its`` file showing a kernel and a dm-verity-protected\n+root filesystem packaged as a FIT. Only the three user-provided properties\n+(``algo``, ``data-block-size``, ``hash-block-size``) are included; ``mkimage``\n+computes and fills in ``digest``, ``salt``, ``num-data-blocks``, and\n+``hash-start-block`` automatically (see `Generating verity metadata`_ below)::\n+\n+    /dts-v1/;\n+\n+    / {\n+        description = \"Kernel + dm-verity rootfs\";\n+        #address-cells = <1>;\n+\n+        images {\n+            kernel {\n+                description = \"Linux kernel\";\n+                data = /incbin/(\"./Image.gz\");\n+                type = \"kernel\";\n+                arch = \"arm64\";\n+                os = \"linux\";\n+                compression = \"gzip\";\n+                load = <0x44000000>;\n+                entry = <0x44000000>;\n+            };\n+\n+            fdt {\n+                description = \"Device tree blob\";\n+                data = /incbin/(\"./board.dtb\");\n+                type = \"flat_dt\";\n+                arch = \"arm64\";\n+                compression = \"none\";\n+            };\n+\n+            rootfs {\n+                description = \"SquashFS root filesystem\";\n+                data = /incbin/(\"./rootfs.squashfs\");\n+                type = \"filesystem\";\n+                arch = \"arm64\";\n+                compression = \"none\";\n+\n+                dm-verity {\n+                    data-block-size = <4096>;\n+                    hash-block-size = <4096>;\n+                    num-data-blocks = <3762>;\n+                    hash-start-block = <3762>;\n+                    algo = \"sha256\";\n+                    digest = [8e 67 91 63 7f 93 cb b8 1f c4 52 99 e2 03 cb e8\n+                              5c a2 e4 7a 38 f5 05 1b dd ee ce 92 d7 b1 c9 f9];\n+                    salt = [aa 7b 11 f8 db 8f e2 e5 bf d4 ec a1 d1 8a 22 b5\n+                            de 7e a3 9d 2e 1b 93 bb 72 72 ce 0c 6c a3 cc 8e];\n+                };\n+            };\n+        };\n+\n+        configurations {\n+            default = \"config-1\";\n+            config-1 {\n+                description = \"Boot with dm-verity rootfs\";\n+                kernel = \"kernel\";\n+                fdt = \"fdt\";\n+                loadables = \"rootfs\";\n+            };\n+        };\n+    };\n+\n+With this configuration U-Boot produces a kernel command line similar to::\n+\n+    dm-mod.create=\"rootfs,,, ro,0 <data_sectors> verity 1 \\\n+        /dev/fit0 /dev/fit0 4096 4096 3762 3762 sha256 \\\n+        8e6791637f93cbb81fc45299e203cbe85ca2e47a38f5051bddeece92d7b1c9f9 \\\n+        aa7b11f8db8fe2e5bfd4eca1d18a22b5de7ea39d2e1b93bb7272ce0c6ca3cc8e\" \\\n+    dm-mod.waitfor=/dev/fit0\n+\n+dm-verity subnode properties\n+----------------------------\n+\n+User-provided properties (required in the ``.its``):\n+\n+.. list-table::\n+   :header-rows: 1\n+   :widths: 20 15 65\n+\n+   * - Property\n+     - Type\n+     - Description\n+   * - ``algo``\n+     - string\n+     - Hash algorithm name, e.g. ``\"sha256\"``.\n+   * - ``data-block-size``\n+     - u32\n+     - Data block size in bytes (>= 512, typically 4096).\n+   * - ``hash-block-size``\n+     - u32\n+     - Hash block size in bytes (>= 512, typically 4096).\n+\n+Computed properties (filled in by ``mkimage``):\n+\n+.. list-table::\n+   :header-rows: 1\n+   :widths: 20 15 65\n+\n+   * - Property\n+     - Type\n+     - Description\n+   * - ``num-data-blocks``\n+     - u32\n+     - Number of data blocks in the filesystem image (computed from the\n+       image size and ``data-block-size``).\n+   * - ``hash-start-block``\n+     - u32\n+     - Offset in ``hash-block-size``-sized blocks from the start of the\n+       sub-image to the root block of the hash tree.\n+   * - ``digest``\n+     - byte array\n+     - Root hash of the Merkle tree, stored as raw bytes. Length must match\n+       the output size of ``algo``.\n+   * - ``salt``\n+     - byte array\n+     - Salt used when computing the Merkle tree, stored as raw bytes.\n+\n+Optional boolean properties (when present, they are collected and appended\n+as dm-verity optional parameters with hyphens converted to underscores):\n+\n+.. list-table::\n+   :header-rows: 1\n+   :widths: 30 70\n+\n+   * - Property\n+     - Description\n+   * - ``restart-on-corruption``\n+     - Restart the system on data corruption.\n+   * - ``panic-on-corruption``\n+     - Panic the system on data corruption.\n+   * - ``restart-on-error``\n+     - Restart the system on I/O error.\n+   * - ``panic-on-error``\n+     - Panic the system on I/O error.\n+   * - ``check-at-most-once``\n+     - Verify data blocks only on first read.\n+\n+These values are the same ones produced by ``veritysetup format`` and can\n+typically be obtained from its output or from the verity superblock.\n+The ``digest`` and ``salt`` byte arrays correspond to the hex-encoded\n+``Root hash`` and ``Salt`` printed by ``veritysetup format``.\n+\n+Generating verity metadata\n+--------------------------\n+\n+``mkimage`` automates the entire process.  When it encounters a\n+``dm-verity`` subnode, it:\n+\n+1. Writes the embedded image data to a temporary file.\n+2. Runs ``veritysetup format`` with the user-supplied algorithm and\n+   block sizes.\n+3. Parses ``Root hash`` and ``Salt`` from ``veritysetup`` stdout.\n+4. Reads back the expanded file (original data + verity superblock +\n+   Merkle hash tree) and replaces the image's ``data`` property.\n+5. Writes the computed ``digest``, ``salt``, ``num-data-blocks``, and\n+   ``hash-start-block`` properties into the ``dm-verity`` subnode.\n+\n+Images with ``dm-verity`` subnodes **must** use external data layout\n+(``mkimage -E``).  ``mkimage`` will abort with an error if ``-E`` is\n+not specified.\n+\n+Usage::\n+\n+    # Create the filesystem image\n+    mksquashfs rootfs/ rootfs.squashfs -comp xz\n+\n+    # Build the FIT (dm-verity is computed automatically)\n+    mkimage -E -f image.its image.itb\n+\n+``veritysetup`` (from the cryptsetup_ package) must be installed on\n+the build host.\n+\n+.. _cryptsetup: https://gitlab.com/cryptsetup/cryptsetup\n+\n+.. note::\n+\n+   ``veritysetup format`` is invoked with ``--no-superblock``, so no\n+   on-disk superblock is written between the data and hash regions.\n+   The Merkle hash tree is appended directly to the image data within\n+   the FIT external data section.  Consequently ``hash-start-block``\n+   equals ``num-data-blocks``.\n+\n+Kconfig\n+-------\n+\n+``CONFIG_FIT_VERITY``\n+  Depends on ``CONFIG_FIT`` and ``CONFIG_OF_LIBFDT``.\n+  When enabled, ``fit_verity_build_cmdline()`` and\n+  ``fit_verity_apply_bootargs()`` are compiled into the boot path.\n+  When disabled, the functions are static inlines returning 0, so there\n+  is no code-size impact.  Works with both the ``bootm`` command and\n+  BOOTSTD boot methods.\ndiff --git a/doc/usage/fit/index.rst b/doc/usage/fit/index.rst\nindex 6c78d8584ed..d17582b1d64 100644\n--- a/doc/usage/fit/index.rst\n+++ b/doc/usage/fit/index.rst\n@@ -11,6 +11,7 @@ images that it reads and boots. Documentation about FIT is available in\n     :maxdepth: 1\n \n     beaglebone_vboot\n+    dm-verity\n     howto\n     kernel_fdt\n     kernel_fdts_compressed\n","prefixes":["4/4"]}