Skip to content

scripts: add build-dtb-image.sh, self-contained FIT DTB image builder co-located with metadata#83

Open
bjordiscollaku wants to merge 2 commits intoqualcomm-linux:mainfrom
bjordiscollaku:feat/qclinux-fit-image-build-script
Open

scripts: add build-dtb-image.sh, self-contained FIT DTB image builder co-located with metadata#83
bjordiscollaku wants to merge 2 commits intoqualcomm-linux:mainfrom
bjordiscollaku:feat/qclinux-fit-image-build-script

Conversation

@bjordiscollaku
Copy link
Copy Markdown

@bjordiscollaku bjordiscollaku commented Apr 14, 2026

Summary

Introduce build-dtb-image.sh, a production-ready build tool for generating FAT-formatted FIT DTB images for Qualcomm ARM64 platforms. The script is co-located with the ITS and DTS metadata it consumes, making the repository fully self-contained: cloning qcom-dtb-metadata is sufficient to build a FIT image, no additional tooling repositories, no network access at build time, and no metadata path arguments.


Background

Previously, FIT DTB image generation required a separate build tool (build-dtb-image.sh in qcom-build-utils) that cloned qcom-dtb-metadata at runtime, reset to a pinned commit, and referenced the ITS and DTS files from the cloned copy.


Design

The script resolves its own location at runtime using BASH_SOURCE[0]:

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

All metadata files (qcom-metadata.dts, qcom-next-fitimage.its) are read directly from SCRIPT_DIR. The version of the metadata used is always exactly the version of the repository that was cloned, no pinning, no drift, no separate clone step.


Capabilities

DTB source modes (exactly one required):

Flag Description
--kernel-deb <path> Extract DTBs from a Debian kernel package (.deb)
--dtb-src <path> Read DTBs directly from a kernel build tree directory

--kernel-deb DTB discovery probes paths in order, most to least preferred:

1. usr/lib/linux-image-*/        ← Debian standard (direct, no symlink)
2. usr/lib/firmware/*/device-tree ← Ubuntu compat symlink (usrmerge layout)
3. lib/firmware/*/device-tree     ← Ubuntu compat symlink (legacy layout)

Probing the Debian standard path first ensures correct operation on both Debian and Ubuntu regardless of usrmerge layout, and is fully backward compatible with legacy packages.

--fit-image is accepted for backward compatibility with existing CI callers but is a no-op, FIT image mode is the default and only mode.


Build Pipeline

Step 1  Create a temporary staging tree:
          fit_image/
            arch/arm64/boot/dts/qcom/   ← all DTBs (flat, collected via find -L)
            qcom-metadata.dtb           ← compiled from SCRIPT_DIR/qcom-metadata.dts
            qcom-next-fitimage.its      ← copied from SCRIPT_DIR

Step 2  Compile qcom-metadata.dts → qcom-metadata.dtb  (dtc)

Step 3  Copy qcom-next-fitimage.its into the staging directory

Step 4  Invoke mkimage from the staging directory:
          mkimage -f qcom-next-fitimage.its out/qclinux_fit.img -E -B 8
        Output filename is hardcoded in UEFI firmware and must not change.

Step 5  Pack qclinux_fit.img into a FAT image using mtools (mformat + mcopy) —
        no loop device, no mount point, no root privileges required.
        (default output: dtb.bin, 4 MB)

Hardening

  • Upfront metadata validation: verifies qcom-metadata.dts and the ITS file exist in SCRIPT_DIR before any build work begins, fails fast with a clear diagnostic.
  • Recursive DTB collection: find -L replaces the previous flat *.dtb* glob, correctly collecting DTBs nested under vendor subdirectories (e.g. qcom/) and following symlinks transparently.
  • Staged DTB count check: fails with a clear error if no DTBs are found; prints a sorted listing of all staged DTBs for build log traceability.
  • Comprehensive cleanup trap: covers all temporary resources (.deb extraction directory, staging directory) on any exit path, including error exits.

Usage

# Clone once, the tool and its metadata are co-located
git clone https://github.com/qualcomm-linux/qcom-dtb-metadata.git
cd qcom-dtb-metadata

# Build from a Debian kernel package (recommended)
./build-dtb-image.sh \
    --kernel-deb linux-image-7.0.0-rc5-qcom_1-1_arm64.deb \
    --out dtb.bin

# Build from a kernel build tree
./build-dtb-image.sh \
    --dtb-src /path/to/kernel/arch/arm64/boot/dts \
    --out dtb.bin

Files Changed

  • build-dtb-image.sh (new): self-contained FIT DTB image builder

Introduce build-dtb-image.sh, a production-ready tool for generating
FAT-formatted FIT DTB images for Qualcomm ARM64 platforms.

The script is co-located with the metadata it consumes (qcom-metadata.dts,
qcom-next-fitimage.its), eliminating the need to clone this repository
at build time.  The metadata directory is resolved at runtime via
BASH_SOURCE[0], so the script works correctly regardless of the caller's
working directory or CI environment.

FIT image mode is the default and only operating mode.  The --fit-image
flag is accepted for backward compatibility with existing callers but is
a no-op.

Two DTB source sub-modes are supported:

  --kernel-deb  Extract DTBs from a Debian kernel package (.deb).
                Probes paths in order:
                  1. usr/lib/linux-image-*/        (Debian standard)
                  2. usr/lib/firmware/*/device-tree (Ubuntu, usrmerge)
                  3. lib/firmware/*/device-tree     (Ubuntu, legacy)
                This probe order ensures correct operation on both Debian
                and Ubuntu regardless of usrmerge layout, and is fully
                backward compatible with legacy build-kernel-deb.sh packages.

  --dtb-src     Read DTBs directly from a kernel build tree directory.

Build pipeline (5 steps):
  1. Assemble a temporary staging tree with ITS, compiled metadata DTB,
     and all per-platform DTBs laid out as the ITS /incbin/ paths expect.
  2. Compile qcom-metadata.dts → qcom-metadata.dtb via dtc.
  3. Copy qcom-next-fitimage.its into the staging directory.
  4. Invoke mkimage from the staging directory to produce qclinux_fit.img
     (-E -B 8).  The output filename is hardcoded in UEFI firmware and
     must not be changed.
  5. Pack qclinux_fit.img into a FAT image (default: dtb.bin, 4 MB).

Hardening:
  - Upfront validation that qcom-metadata.dts and the ITS file exist
    before any build work begins.
  - find -L replaces flat *.dtb* glob, correctly collecting DTBs nested
    under vendor subdirectories (e.g. qcom/).
  - Staged DTB count check with sorted listing for early diagnosis of
    empty or misconfigured DTB sources.
  - Cleanup trap covers all temporary resources (loop device, mount
    point, .deb extraction dir, staging dir) on any exit path.
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
@lumag
Copy link
Copy Markdown

lumag commented Apr 15, 2026

Please drop sudo usage from your examples. There should be no need for elevating properties to build the FIT image file.

@bjordiscollaku bjordiscollaku force-pushed the feat/qclinux-fit-image-build-script branch from ad297fb to 34e80dc Compare April 15, 2026 16:55
@bjordiscollaku
Copy link
Copy Markdown
Author

bjordiscollaku commented Apr 15, 2026

Please drop sudo usage from your examples. There should be no need for elevating properties to build the FIT image file.

Done, addressed by 64f8ef7.

Replace losetup/mkfs.vfat/mount with mtools (mformat + mcopy) for FAT
image creation.  mtools operates directly on image files without needing
a loop device or mount point, eliminating the only step that required
root privileges.  The script now runs entirely as a normal user.

4 KiB sector size is preserved via mformat -S 5 (2^(5+7) = 4096 bytes),
matching the previous mkfs.vfat -S 4096.  FAT type auto-detection is
preserved by omitting -F, so mformat selects the same FAT variant as
mkfs.vfat for a given image size.

Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
@bjordiscollaku bjordiscollaku force-pushed the feat/qclinux-fit-image-build-script branch from 69b61c3 to 64f8ef7 Compare April 15, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants