Show a cover letter.

GET /api/covers/2196994/?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2196994,
    "url": "http://patchwork.ozlabs.org/api/covers/2196994/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/cover/cover.1771275704.git.daniel@makrotopia.org/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "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,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<cover.1771275704.git.daniel@makrotopia.org>",
    "list_archive_url": null,
    "date": "2026-02-16T21:21:14",
    "name": "[RFC,00/20] boot: add OpenWrt boot method and on-demand FIT loading",
    "submitter": {
        "id": 64091,
        "url": "http://patchwork.ozlabs.org/api/people/64091/?format=api",
        "name": "Daniel Golle",
        "email": "daniel@makrotopia.org"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/cover/cover.1771275704.git.daniel@makrotopia.org/mbox/",
    "series": [
        {
            "id": 492351,
            "url": "http://patchwork.ozlabs.org/api/series/492351/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=492351",
            "date": "2026-02-16T21:21:14",
            "name": "boot: add OpenWrt boot method and on-demand FIT loading",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492351/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/covers/2196994/comments/",
    "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 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fFG2y5r82z1xwD\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 17 Feb 2026 08:23:06 +1100 (AEDT)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id C476B83B8A;\n\tMon, 16 Feb 2026 22:22:56 +0100 (CET)",
            "by phobos.denx.de (Postfix, from userid 109)\n id B2A8D83C6C; Mon, 16 Feb 2026 22:21:54 +0100 (CET)",
            "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 E3CFB83AA9\n for <u-boot@lists.denx.de>; Mon, 16 Feb 2026 22:21:46 +0100 (CET)",
            "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 1vs61v-000000002bj-0ant; Mon, 16 Feb 2026 21:21:19 +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": "Mon, 16 Feb 2026 21:21:14 +0000",
        "From": "Daniel Golle <daniel@makrotopia.org>",
        "To": "Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,\n Quentin Schulz <quentin.schulz@cherry.de>,\n Daniel Golle <daniel@makrotopia.org>,\n Kory Maincent <kory.maincent@bootlin.com>,\n Mattijs Korpershoek <mkorpershoek@kernel.org>,\n Martin Schwan <m.schwan@phytec.de>, Anshul Dalal <anshuld@ti.com>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Sughosh Ganu <sughosh.ganu@arm.com>, Aristo Chen <jj251510319013@gmail.com>,\n\t=?utf-8?b?54mbIOW/l+Wujw==?= <Zone.Niuzh@hotmail.com>,\n Marek Vasut <marek.vasut+renesas@mailbox.org>,\n Heinrich Schuchardt <xypron.glpk@gmx.de>,\n Wolfgang Wallner <wolfgang.wallner@at.abb.com>,\n Frank Wunderlich <frank-w@public-files.de>,\n David Lechner <dlechner@baylibre.com>,\n Osama Abdelkader <osama.abdelkader@gmail.com>,\n Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>,\n Michael Trimarchi <michael@amarulasolutions.com>,\n Miquel Raynal <miquel.raynal@bootlin.com>,\n Andrew Goodbody <andrew.goodbody@linaro.org>,\n Yegor Yefremov <yegorslists@googlemail.com>,\n Mike Looijmans <mike.looijmans@topic.nl>,\n Weijie Gao <weijie.gao@mediatek.com>,\n Alexander Stein <alexander.stein@ew.tq-group.com>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Mayuresh Chitale <mchitale@ventanamicro.com>,\n Paul HENRYS <paul.henrys_ext@softathome.com>, u-boot@lists.denx.de",
        "Cc": "John Crispin <john@phrozen.org>, Paul Spooren <mail@aparcar.org>",
        "Subject": "[RFC PATCH 00/20] boot: add OpenWrt boot method and on-demand FIT\n loading",
        "Message-ID": "<cover.1771275704.git.daniel@makrotopia.org>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Disposition": "inline",
        "Content-Transfer-Encoding": "8bit",
        "X-Mailman-Approved-At": "Mon, 16 Feb 2026 22:22:55 +0100",
        "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": "Hi all,\n\nThis RFC series adds a new boot method for OpenWrt's \"uImage.FIT with\nembedded rootfs\" firmware model, along with the underlying infrastructure\nto load FIT images on-demand directly from storage devices without copying\nthem entirely to RAM first.\n\nI would like to discuss the design with U-Boot maintainers and fellow\nOpenWrt developers before submitting a formal patch series.\n\nBackground: Why OpenWrt needs its own boot method\n==================================================\n\nOpenWrt's modern embedded boot model uses a single uImage.FIT container\nthat includes the Linux kernel, device tree, and a read-only root\nfilesystem (squashfs or more recently erofs).\n\nAt boot, the kernel maps the embedded squashfs directly from flash as a\nblock device (/dev/fit0 via the fitblk driver[1]). No separate boot\npartition, boot filesystem, or initrd is required.\n\nThis creates a monolithic, deterministic, flash-native firmware image that\nis fundamentally different from what U-Boot's existing boot methods\n(distroboot, EFI, extlinux) are designed for. Those methods assume:\n\n  - A partition table with a boot filesystem (FAT ESP, ext4 /boot)\n  - Kernel and initrd as separate files on that filesystem\n  - Mutable boot state managed by filesystem metadata\n  - Multi-OS flexibility on replaceable storage\n\nOpenWrt's model assumes:\n\n  - A single-flash embedded appliance with no removable storage\n  - One immutable firmware blob per slot\n  - No boot filesystem at all\n  - Boot-medium agnostic deployment (the same .itb image works on eMMC,\n    SD, SPI-NOR, SPI-NAND/UBI, and raw NAND)\n\n[1]: https://github.com/openwrt/openwrt/blob/30ac12f4b4682207c5b0501b3ffc50d56f58b690/target/linux/generic/pending-6.12/510-block-add-uImage.FIT-subimage-block-driver.patch\n\nOne image for all use cases\n===========================\n\nThe same .itb image can be:\n\n  - Used as a sysupgrade image inside a running OpenWrt system\n  - Flashed from U-Boot via TFTP or HTTP\n  - Written to an eMMC or SD partition via dd\n  - Stored in a UBI volume (SPI-NAND, raw NAND)\n  - Stored in a raw MTD partition (SPI-NOR, parallel NOR)\n\nIt is entirely boot-medium agnostic. UEFI and distroboot by contrast\nassume a block-oriented storage device with a specific partition layout\nand boot filesystem, and cannot easily be used on raw flash devices or\nUBI.\n\nWhy boot filesystems are a problem for embedded\n===============================================\n\nBoot filesystems (FAT ESPs, ext4 /boot) introduce:\n\n  - Metadata corruption risks on power loss\n  - fsck requirements after unclean shutdown\n  - State drift across firmware upgrades\n  - A structural single point of failure\n\nThese are not theoretical concerns. OpenWrt is deployed in telecom\ninfrastructure, industrial control systems, and ISP CPE devices —\nenvironments where thousands (sometimes millions) of devices must boot\nand receive software updates reliably for years without physical\naccess. A corrupted FAT partition on a rooftop wireless backhaul\ndevice can mean a truck roll, in a private home often means scheduling\na costly visit by the ISPs service team.\n\nThe FIT-with-rootfs model eliminates this entire failure class:\n\n  - No filesystem metadata to corrupt\n  - No fsck needed after power loss\n  - No mutable boot artifacts\n  - Bit-identical system partitions across the entire fleet\n\nThis is critical for QA reproducibility, telecom deployments, and any\nfleet where deterministic firmware state is a hard requirement.\n\nReduced failure surface\n=======================\n\nA typical UEFI / distroboot path:\n\n  Bootloader -> Filesystem driver -> Directory traversal -> File read\n  -> Kernel -> Initrd -> Pivot to rootfs\n\nThe OpenWrt uImage.FIT path:\n\n  Bootloader -> Read FIT blob from partition -> Kernel\n  -> squashfs/erofs rootfs mapped from same blob\n\nFewer parsing stages mean fewer corruption vectors and lower boot-path\ncomplexity. The boot chain is shorter and each step is simpler.\n\nSecure boot friendly\n====================\n\nFIT natively supports cryptographic signatures and verified boot chains.\nBecause kernel, DTB, and rootfs are inside the same signed container,\nthey are verified together — no unsigned kernel swapping, no mismatched\nkernel/rootfs pairs. This is structurally cleaner than verifying\nseparate files scattered across a boot filesystem.\n\nReal-world adoption\n===================\n\nThis boot method is not a theoretical proposal — it is already the\nstandard production boot method for a large number of shipping devices.\n\nIn OpenWrt's MediaTek Filogic target alone, over 40 boards use\nfit_do_upgrade() for their primary firmware upgrade path. See\ntarget/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh in\nopenwrt.git for the full list.\n\nBeyond MediaTek, the SiFlower SF21-based BananaPi BPi-RV2 (NAND) also\nuses this exact method. Countless additional boards use minor variations,\nfor example, appending the squashfs blob after the uImage.FIT container\ninstead of using an IH_TYPE_FILESYSTEM uImage.FIT sub-image.\n\nProduction / recovery architecture\n===================================\n\nThe slot configuration in this series supports:\n\n  - A production FIT image\n  - A recovery FIT image\n  - Separate persistent data partition\n\nRecovery can reflash production remotely and preserve configuration.\nThis dual-slot model — which Android eventually adopted for similar\nembedded constraints — is a natural fit for the OpenWrt deployment\nmodel.\n\nWhy existing boot methods cannot be reused\n==========================================\n\n1. distroboot / extlinux: Require a boot filesystem containing\n   extlinux.conf. OpenWrt avoids using a boot filesystem.\n\n2. EFI: Requires an EFI System Partition with a PE binary. OpenWrt's\n   firmware is a flat FIT blob, not an EFI application. EFI also mandates\n   booting from a block-oriented storage device or PXE, while devices\n   supported by OpenWrt often come with SPI-NAND or SPI-NOR flash,\n   sometimes as little as 32 MiB in total.\n\n3. script-based sf_bootdev: Reads a boot script from a fixed offset in\n   SPI flash. It does not understand partitions, does not iterate MTD\n   or UBI devices, and does not support FIT image detection.\n\n4. On-demand loading: None of the existing methods support loading FIT\n   subimages directly from storage. OpenWrt's FIT images typically\n   contain a 5-20 MB squashfs that does NOT need to be copied to RAM —\n   the kernel maps it directly from flash. The bootloader only needs\n   to load the kernel and DTB (~5-10 MB), not the entire 20-50 MB\n   container. This requires a new loading abstraction.\n\nWhat this series adds\n=====================\n\nThe series is structured in two logical parts:\n\nPart 1: On-demand FIT loading infrastructure (patches 1-12)\n-----------------------------------------------------------\n\nA new image_loader abstraction that provides a read callback for loading\ndata from storage on demand, rather than requiring the entire image to\nreside in RAM. This is wired into fit_image_load() so that bootm can\nload individual FIT subimages directly from block devices, MTD\npartitions, or UBI volumes.\n\nThree storage backends:\n\n  - Block device (eMMC, SD, SATA, NVMe, USB mass storage, virtio)\n  - MTD (SPI-NOR, raw NOR, raw NAND with bad block skipping)\n  - UBI volume (SPI-NAND, raw NAND)\n\nThe \"bootm\" command is extended to accept a storage device specification\ninstead of a RAM address:\n\n  bootm mmc 0:4         # boot FIT from eMMC partition 4\n  bootm mtd recovery    # boot FIT from MTD partition \"recovery\"\n  bootm ubi recovery    # boot FIT from UBI volume \"recovery\"\n\nThis infrastructure is independently useful beyond the OpenWrt boot\nmethod. Any board that stores a FIT image directly in a partition\n(rather than as a file on a filesystem) can benefit from on-demand\nsubimage loading.\n\nPart 2: OpenWrt boot method and bootdevs (patches 13-20)\n---------------------------------------------------------\n\nA proper bootstd boot method (bootmeth_openwrt) that:\n\n  - Scans block device partitions, MTD partitions, and UBI volumes\n    for raw FIT images (detected by fdt_check_header on the first bytes)\n  - Boots via the image_loader / bootm storage path\n  - Supports configurable dual-slot boot (production + recovery) via\n    environment variables\n  - Provides a script hook (openwrt_boot_script) for boards that need\n    to probe hardware before selecting the FIT configuration\n\nTwo new boot devices are introduced:\n\n  - mtd_bootdev: Iterates MTD partitions. A hunt callback walks the\n    MTD subsystem device list to bind bootdevs for both UCLASS_MTD\n    (SPI-NAND) and UCLASS_SPI_FLASH (SPI-NOR) devices.\n\n  - ubi_bootdev: Auto-attaches UBI from DT (compatible = \"linux,ubi\")\n    and iterates UBI volumes.\n\nThe boot method integrates with bootstd's existing scan/priority\nframework. \"bootflow scan\" discovers OpenWrt firmware on all attached\nstorage, and \"bootflow boot\" boots the first valid one — exactly like\ndistroboot or EFI, but for raw FIT images.\n\nSlot configuration example:\n\n  openwrt_slot_production=firmware\n  openwrt_slot_recovery=recovery\n  openwrt_boot_order=production recovery\n\nThis enables production/recovery dual-boot, boot-loop detection (planned\nfor a future series via pstore), and boot menu integration.\n\nTesting\n=======\n\nThe BananaPi BPi-R3 (MT7986) is the ideal demonstration device for this\nseries because it is the only commonly available board that exposes all\nfour storage types — SPI-NOR, SPI-NAND, eMMC, and a microSD slot — and\ncan boot from any of them using the very same uImage.FIT image. This\nmakes it possible to test every image_loader backend and the full\ncross-media boot flow on a single board.\n\n  - sandbox: unit tests for image_loader\n  - BananaPi BPi-R3 (MT7986): real hardware testing with SPI-NOR,\n    SPI-NAND (UBI), eMMC, and SD card — including combinations of\n    present/absent flash devices and deliberate probe failures\n\nPatch overview\n==============\n\nOn-demand FIT loading (generic infrastructure):\n\n  01/20  boot: add image_loader on-demand loading abstraction\n  02/20  boot: image-loader: add block device backend\n  03/20  mtd: add mtd_read_skip_bad() helper\n  04/20  boot: image-loader: add MTD backend\n  05/20  cmd: ubi: export ubi_find_volume()\n  06/20  mtd: set flash_node on DT-created partitions\n  07/20  cmd: ubi: add ubi_part_from_mtd()\n  08/20  boot: image-loader: add UBI volume backend\n  09/20  boot: fit: support on-demand loading in fit_image_load()\n  10/20  cmd: bootm: accept storage device as image source\n  11/20  test: boot: add image_loader unit tests\n  12/20  doc: bootm: document direct storage boot\n\nOpenWrt boot method:\n\n  13/20  boot: bootmeth: add OpenWrt boot method skeleton\n  14/20  boot: bootmeth: openwrt: implement read_bootflow for block devices\n  15/20  boot: bootmeth: openwrt: implement boot via bootm storage path\n  16/20  boot: bootdev: add MTD boot device\n  17/20  boot: bootdev: add UBI boot device\n  18/20  boot: bootmeth: openwrt: support MTD and UBI bootdevs\n  19/20  boot: bootmeth: openwrt: add openwrt_boot_script hook for bootconf\n  20/20  boot: bootmeth: openwrt: add slot configuration from environment\n\nDiffstat summary:\n\n 29 files changed, 2666 insertions(+), 45 deletions(-)\n\nPlanned future work\n===================\n\n  - pstore-based boot state tracking for automatic fallback to recovery\n    after repeated boot failures and boot-loop avoidance\n  - Comprehensive documentation and board migration guide\n  - dm-verity integration for runtime integrity verification of the\n    rootfs image, complementing FIT signature verification at boot\n  - Board enablement patches for MediaTek (MT7986, MT7981, MT7988),\n    Qualcomm (IPQ807x, IPQ60xx), and other OpenWrt-supported SoCs\n\nComments, questions, and review very much appreciated.\n\nAI tool disclosure\n==================\n\nMajor parts of this series were developed with assistance from GitHub\nCopilot (Claude Opus 4.6, Anthropic). The AI was used as a coding\npartner for scaffolding boilerplate, drafting documentation and commit\nmessages, running checkpatch sweeps, and iterating on review feedback.\nAll architectural decisions, U-Boot subsystem integration, hardware\ntesting, and final review were done by the human author. Every line of\ncode was reviewed and tested on real hardware before inclusion.\n\n\nCheers\n\n\nDaniel\n\n\nDaniel Golle (20):\n  boot: add image_loader on-demand loading abstraction\n  boot: image-loader: add block device backend\n  mtd: add mtd_read_skip_bad() helper\n  boot: image-loader: add MTD backend\n  cmd: ubi: export ubi_find_volume()\n  mtd: set flash_node on DT-created partitions\n  cmd: ubi: add ubi_part_from_mtd()\n  boot: image-loader: add UBI volume backend\n  boot: fit: support on-demand loading in fit_image_load()\n  cmd: bootm: accept storage device as image source\n  test: boot: add image_loader unit tests\n  doc: bootm: document direct storage boot\n  boot: bootmeth: add OpenWrt boot method skeleton\n  boot: bootmeth: openwrt: implement read_bootflow for block devices\n  boot: bootmeth: openwrt: implement boot via bootm storage path\n  boot: bootdev: add MTD boot device\n  boot: bootdev: add UBI boot device\n  boot: bootmeth: openwrt: support MTD and UBI bootdevs\n  boot: bootmeth: openwrt: add openwrt_boot_script hook for bootconf\n  boot: bootmeth: openwrt: add slot configuration from environment\n\n boot/Kconfig                   |  88 +++++++\n boot/Makefile                  |   8 +\n boot/bootm.c                   |  62 ++++-\n boot/bootmeth_openwrt.c        | 248 +++++++++++++++++++\n boot/image-fit.c               |  96 ++++++++\n boot/image-loader-blk.c        | 133 ++++++++++\n boot/image-loader-mtd.c        | 103 ++++++++\n boot/image-loader-ubi.c        | 112 +++++++++\n boot/image-loader.c            | 163 +++++++++++++\n boot/mtd_bootdev.c             | 150 ++++++++++++\n boot/ubi_bootdev.c             | 180 ++++++++++++++\n cmd/bootm.c                    | 148 +++++++++++-\n cmd/mtd.c                      |  65 ++---\n cmd/ubi.c                      |  33 ++-\n doc/develop/bootm-storage.rst  | 210 ++++++++++++++++\n doc/develop/index.rst          |   1 +\n doc/usage/fit/index.rst        |   1 +\n doc/usage/fit/storage-boot.rst | 201 +++++++++++++++\n drivers/mtd/mtd-uclass.c       |  15 ++\n drivers/mtd/mtdcore.c          |  45 ++++\n drivers/mtd/mtdpart.c          |   2 +\n include/bootm.h                |   2 +\n include/image-loader.h         | 188 +++++++++++++++\n include/image.h                |   4 +\n include/linux/mtd/mtd.h        |  24 ++\n include/ubi_uboot.h            |   2 +\n test/boot/Makefile             |   2 +\n test/boot/image_loader.c       | 429 +++++++++++++++++++++++++++++++++\n test/cmd_ut.c                  |   2 +\n 29 files changed, 2673 insertions(+), 44 deletions(-)\n create mode 100644 boot/bootmeth_openwrt.c\n create mode 100644 boot/image-loader-blk.c\n create mode 100644 boot/image-loader-mtd.c\n create mode 100644 boot/image-loader-ubi.c\n create mode 100644 boot/image-loader.c\n create mode 100644 boot/mtd_bootdev.c\n create mode 100644 boot/ubi_bootdev.c\n create mode 100644 doc/develop/bootm-storage.rst\n create mode 100644 doc/usage/fit/storage-boot.rst\n create mode 100644 include/image-loader.h\n create mode 100644 test/boot/image_loader.c"
}