Adding a patch
boot2deb applies an ordered patch series to each source tree (kernel, ffmpeg,
userspace, u-boot) before it compiles. The series is declared by a
patch series that
lives in the separate patches repo. Adding a patch means getting it into that series
and then into a build. This page walks the loop end to end.
This page is about getting a new patch into a series. Carrying an existing series across a kernel version — measuring what breaks, and encoding the boundary in the series — is Moving a board to a newer kernel.
It applies to a kernel that names a series. A kernel with patch_series = "none"
applies no series and never reads the patches repo; giving such a board a patch means
first authoring a series for its kernel.
The loop
patch import -> commit in ../patches -> boot2deb update -> boot2deb build
(verify-patches at any point along the way)
The linchpin is the middle two steps: update re-pins the patches repo’s current
commit into the lock, and build reads the series at exactly that pinned commit. So a
patch sitting on disk does nothing until it is committed in the patches repo and the
lock is re-pinned to include that commit. patch import prints these follow-ups for
you; the rest of this page is the same steps, with their failure modes.
The running example imports a kernel patch into the rk3588-accel series and builds the
turing-rk1/forky recipe.
1. Import the patch
patch import fetches a patch (a patchwork/mbox URL, a local file, or - for stdin),
normalizes it to canonical git am-ready mbox, writes it into the series’ tree, and
slots it into the series manifest at the right position:
boot2deb patch import \
https://patchwork.kernel.org/project/linux-rockchip/patch/NNNN/mbox/ \
--series rk3588-accel --scope kernel
--scopeselects which tree’s series to insert into:kernel,ffmpeg,userspace, oruboot.- The filename prefix is chosen to sort the patch at its list position; pass
--positionto insert at a specific index (default: append). If the neighbours leave no numeric gap (e.g.070/071), the import falls back to a lettered sub-prefix (070a) automatically. - Add
--verify-tree <kernel-checkout>to dry-rungit amthe resulting series during the import (it rolls back the write on failure). Without it, the patch is written unverified — see verify.
On success it prints exactly what to do next:
patch import: wrote media-accel/kernel/045-fix-foo.patch (3812 bytes)
!! patch written but NOT verified — it has not been dry-run against a kernel tree.
verify it now: boot2deb verify-patches turing-rk1/forky
(auto-fetches the locked kernel at its pin — no checkout needed)
next time: add --verify-tree <kernel-checkout> to verify during import.
patch import: rk3588-accel/kernel now lists the patch at position 5 of 11
next steps — no build reads the patch until the series is committed and re-pinned:
1. commit it: git -C /home/you/dev/patches add -A && git -C /home/you/dev/patches commit
2. re-pin locks: boot2deb update turing-rk1/forky
The re-pin line names each recipe that applies the series you imported into, on either
axis — a device’s default_uboot_series counts the same as a kernel’s patch_series,
so importing into a u-boot series names the recipes that carry it. The checkout path it
prints is the one it wrote to: --patches-path when you passed one, else the config
root’s sibling ../patches — anchored to --root, not to the directory you ran from.
2. Commit in the patches repo
The new patch file and the series edit both live in the patches repo. Commit them
there:
git -C ../patches add -A
git -C ../patches commit -m "kernel: fix foo"
This matters because update pins the patches repo’s HEAD commit. An uncommitted
patch is invisible to that pin — which is exactly why update refuses to run against a
dirty patches checkout (see failure modes).
3. Verify
Confirm the series still applies cleanly to the pinned tree:
boot2deb verify-patches turing-rk1/forky
With no --kernel-path, verify-patches auto-fetches the locked kernel at its pin —
no hand-cloned tree needed. The first run on a cold cache clones linux-stable (large); if
you already have a checkout, point --kernel-src at it to skip the clone:
boot2deb verify-patches turing-rk1/forky --kernel-src ../linux
A --scope uboot import verifies the same way, against the recipe that carries the
u-boot series — the locked u-boot is auto-fetched at its pin, and the run reports the
uboot series at the u-boot tag rather than a kernel one:
boot2deb verify-patches rk3576-generic/loader
You can verify before or after committing — the series on disk is what is checked.
(Passing --verify-tree to patch import runs the same check inline.) See
Verification for verify-config and the full flag
set.
4. Re-pin the lock, then build
update re-pins the patches commit (and re-resolves the other refs) into the lock:
boot2deb update turing-rk1/forky
You do not need --kernel-ref for a patch-only re-pin: with a lock already present,
update inherits the previous kernel ref and re-pins only what changed. Commit the
updated recipes/<device>/<leaf>.lock, then build:
boot2deb build turing-rk1/forky
The build reads the series at the pinned commit and applies it with git am --3way.
Failure modes
Dirty patches checkout. update refuses a patches repo with uncommitted changes
(PatchesDirty): a dirty pin would be wrong in every case, so commit first. This guard
turns “I imported but forgot to commit” into an instant, offline error instead of a
confusing build-time one.
Stale / mismatched pin. If the checkout build reads is at a different commit than
the lock pins, you get PatchesPinMismatch. Its remedy text distinguishes the cases: if
your local HEAD is ahead of the pin (you committed but did not re-pin), run update;
if the checkout is behind the pin (stale), git checkout the pinned commit. Re-pinning
after a commit is the usual fix.
Auto-fetch can’t find the commit. A zero-clone build (no local ../patches) fetches
the series at the pinned commit from the series’ patches_url. That only works if the
commit has been pushed — an unpushed local commit resolves fine against a local
checkout but not on another machine. Push the patches repo before relying on the
auto-fetch.
Co-developing the series
While iterating on a patch you may not want to commit-and-re-pin on every change. Point
build (and verify-patches) at your working checkout instead:
boot2deb build turing-rk1/forky --patches-path ../patches
An explicit --patches-path downgrades a pin mismatch from an error to a loud
warning, so you can build from an uncommitted, un-re-pinned series. The trade-off is
reproducibility: that build is no longer pinned by the lock, so it is a development
convenience, not a committed result. When the patch is settled, commit it, update, and
drop the flag.