Integrate out-of-tree DKMS modules into the kernel at build time - #54
Integrate out-of-tree DKMS modules into the kernel at build time#54Bjordis Collaku (bjordiscollaku) wants to merge 13 commits into
Conversation
kgsl-dkms provides the KGSL GPU driver source and DKMS configuration. Listing it as a Build-Depends makes dpkg-buildpackage install it into the build environment before any debian/rules target runs, giving the DKMS build step in override_dh_auto_install access to the source tree at /usr/src/kgsl-<version>/. dkms is the build-time tool that compiles the module. Neither package appears in the binary package Depends/Recommends/Suggests — they are consumed during the build and never reach the target device. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
…nux-image Build the module from its installed -dkms source with `dkms build`, against the kernel headers staged earlier in the same dpkg-buildpackage run, and install the resulting .ko into linux-image under /lib/modules/<KVER>/extra/. Use a private --dkmstree (mktemp) with a hand-created source symlink so the build runs rootless under fakeroot without writing to the root-owned /var/lib/dkms, and pass an absolute --kernelsourcedir via $(CURDIR) because dkms invokes make from inside the module source directory. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Add debian/dkms-modules, a plain-text list of modules to build and bundle, and read it in debian/rules so the build loops over every listed module instead of a single hardcoded block. Adding a module is then a one-line manifest entry plus its Build-Depends, with no debian/rules change. Comments (# to end of line), blank lines, and CR line endings are stripped when the manifest is read, so an annotated or CRLF-edited manifest cannot leak stray tokens into the module list. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
dkms build can complete without producing a module, for example when a BUILD_EXCLUSIVE_* directive in the module's dkms.conf does not match the target kernel, and the bundling loop would previously just bundle nothing. A manifest entry is a presence contract: capture the built .ko list and hard-fail when it is empty, instead of silently shipping linux-image without a declared module. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
dkms --arch and dkms.conf BUILD_EXCLUSIVE_ARCH speak uname -m vocabulary (aarch64), while the build passed a hardcoded kbuild-style token (arm64). The mismatch is latent today only because kgsl declares no BUILD_EXCLUSIVE_ARCH gate; a module that does would be wrongly gated off by the arm64 token. Introduce DKMS_ARCH (aarch64) alongside the kbuild ARCH variable and pass that instead. Only the architecture label inside the private dkms tree changes; the built .ko is found recursively under the kernel directory, so the produced packages are identical. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The DKMS-built .ko was installed into linux-image with `install -m 644` and never stripped. dh_strip skips /lib/modules, and the module never flows through `make modules_install`, which strips in-tree modules via INSTALL_MOD_STRIP=1. So an unstripped ~2.8 MB module shipped on every device, with its debug symbols baked in rather than separated out. Give each bundled .ko the same two-stage treatment in-tree modules get: capture its debug into the -dbg package's parallel debug tree with objcopy --only-keep-debug (matching the in-tree modules.order loop), then strip the shipped copy in place with strip --strip-debug. That is the exact tool and flag modules_install INSTALL_MOD_STRIP=1 uses on in-tree modules (the kernel's STRIP --strip-debug, plain strip on native arm64). --strip-debug is required for kernel modules (a full strip drops the symtab and relocations needed to load), and the strip must follow the debug capture. Loadability is unaffected (depmod/modinfo data preserved). Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Replace the dpkg-query version parse (cut -d- mishandles epochs and hyphenated upstream versions) with resolution through the package manager: dpkg -L <name>-dkms names the one /usr/src/<dir>/dkms.conf the package ships (dh_dkms layout), so the source tree is found without guessing and a look-alike directory from another package, for example a future kgsl-extras-dkms next to kgsl-dkms, can never be picked up. The dkms name/version tokens are then read from dkms.conf (PACKAGE_NAME/PACKAGE_VERSION), which is what dkms itself keys its tree layout and build on, so the manifest entry only needs to match the package name, not the module's internal naming. Guards fail the build when the package is missing, ships zero or several dkms.conf files, lacks the name/version fields, or when two manifest entries resolve to the same dkms module. No change to the produced packages: for kgsl the resolved source dir, tokens, and build call are identical. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
A missing module can be a failed build or a skipped one, and dkms
exit-code conventions are not a reliable discriminator (a
BUILD_EXCLUSIVE skip can exit 0, and conventions vary across dkms
versions). Worse, on a real compile failure dkms points at its
make.log inside the private dkms tree, which lives in an ephemeral
build environment: the actual compile error never reached the CI log.
Capture the dkms exit code and judge the outcome by artifacts:
- a .ko under <tree>/<name>/<ver>/<kernel>/ means success;
- otherwise, make.log present means a build was attempted and
failed: print its tail inline (the only surviving record in CI),
together with the exit code;
- no make.log means dkms attempted no build: print the
BUILD_EXCLUSIVE gates declared in the module's dkms.conf, evaluate
each BUILD_EXCLUSIVE_CONFIG against the staged kernel config, and
print the kernel release and dkms arch being built, so the
unsatisfied gate is visible without reproducing the build;
- call out compressed module output explicitly if that is what the
build produced, since only plain .ko is bundled.
The build still hard-fails in every no-module case (a manifest entry
is a presence contract). The private dkms tree is now removed via an
EXIT trap, so failure paths no longer leak it.
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
Two manifest entries emitting a .ko with the same basename would silently overwrite each other in extra/, and a bundled module sharing its name with an in-tree module would ship two copies of the same module name in one package, leaving precedence on the target to depmod search order. Fail the build loudly in both cases; neither is a configuration this package should ship. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
…les.sh
Move the entire out-of-tree DKMS module integration block out of
override_dh_auto_install in debian/rules and into a dedicated, standalone
tool: debian/scripts/bundle-dkms-modules.sh.
Motivation
----------
The DKMS block in debian/rules had grown to ~120 lines of dense shell
embedded in Make recipe syntax. Keeping it there made debian/rules harder
to read, and any future DKMS-related change (new module type, signing,
compression support) required editing the build rules file directly.
Extracting the logic into a named tool with a documented CLI achieves three
goals simultaneously:
1. Cleanliness — debian/rules is reduced to a single 7-line invocation
with explicit, named parameters; the build rules file describes *what*
happens, not *how* DKMS modules are built.
2. Modularity — all DKMS logic lives in one place. Future changes
(additional guards, new dkms.conf fields, signing hooks) touch only
bundle-dkms-modules.sh, never debian/rules.
3. Developer ergonomics — the script is independently invocable. A
developer who has already staged the kernel trees can re-run just the
DKMS bundling step without re-executing the full dpkg-buildpackage,
passing the required paths explicitly via a documented CLI.
What the script does (unchanged from the original rules block)
--------------------------------------------------------------
For each module listed in debian/dkms-modules:
- Resolves the installed -dkms package via 'dpkg -L' (authoritative;
no /usr/src/ globbing; a look-alike from another package cannot be
picked up).
- Reads PACKAGE_NAME / PACKAGE_VERSION from the package's dkms.conf
(the authority on the tokens that drive the dkms tree layout).
- Builds with 'dkms build' against the staged kernel headers, using a
private --dkmstree (mktemp -d) to avoid writing to the root-owned
/var/lib/dkms/ under fakeroot.
- Judges the outcome by .ko artifact presence, not dkms exit code
(conventions vary across dkms versions; a BUILD_EXCLUSIVE skip can
exit 0). On failure: prints make.log tail (compile error) or
BUILD_EXCLUSIVE gate analysis with per-CONFIG_* kernel config
evaluation (skip), then hard-fails — a manifest entry is a presence
contract.
- For each produced .ko: collision-checks against already-bundled
modules (duplicate basename) and in-tree modules (depmod precedence
ambiguity); installs to lib/modules/<kver>/extra/; extracts debug
symbols via 'objcopy --only-keep-debug' into the -dbg staging tree;
strips the shipped copy with 'strip --strip-debug' (not full strip:
kernel modules require their symtab and relocations to be loadable
by the module loader).
One intentional improvement over the original rules block: the .ko
install loop is rewritten from 'printf | while' (pipe subshell) to
'while < <(process substitution)', so 'exit 1' inside the collision
guards terminates the script directly rather than only the subshell.
Under 'set -e -o pipefail' both forms propagate failure, but the process
substitution form is unambiguous and does not rely on pipefail semantics.
CLI design
----------
Required parameters (must be passed explicitly; no defaults derivable
without Make context):
--kver KVER Kernel release string (uname -r)
--headers-dir DIR Absolute path to staged kernel headers root
(MUST be absolute: dkms cd's into the module
source dir before invoking make)
--image-pkg-dir DIR linux-image staging tree root
--dbg-pkg-dir DIR linux-image-dbg staging tree root
Optional parameters (have safe defaults matching the rules context):
--modules-manifest FILE Default: debian/dkms-modules (relative to
the script's own location)
--arch ARCH Default: aarch64 (uname -m vocabulary for
dkms --arch and BUILD_EXCLUSIVE_ARCH gates)
--objcopy PATH Default: aarch64-linux-gnu-objcopy -> objcopy
-h, --help Full usage with prerequisites and examples
debian/rules changes
--------------------
- Add DKMS_ARCH ?= aarch64 Make variable (passed to script via --arch;
kept in rules so it remains overridable at dpkg-buildpackage time via
the standard Make variable override mechanism).
- Replace the ~120-line DKMS shell block with a 7-line script
invocation. All paths are passed as absolute via $(CURDIR) to satisfy
the --headers-dir absoluteness requirement and to make the invocation
self-documenting.
- Remove the DKMS_MODULES Make variable (manifest is now read at
runtime by the script; no Make-time evaluation needed).
New files
---------
debian/scripts/bundle-dkms-modules.sh standalone DKMS bundling tool
debian/dkms-modules module manifest (kgsl)
Modified files
--------------
debian/rules DKMS_ARCH var + single script invocation
debian/control.in kgsl-dkms (>= 1.0.2), dkms in Build-Depends
README.md repo structure, file table, new DKMS bundling section
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The DKMS extraction (14a1f96) left a stray "; \" line between the vmlinux block's closing "fi; \" and the bundle-dkms-modules.sh invocation. Under .ONESHELL (SHELL=/bin/bash, .SHELLFLAGS=-e -o pipefail -c) the whole recipe is one spliced `bash -c`, so the backslash-continuations collapse the region to "...fi; ; <script>", an empty command between two ";" separators. bash rejects it with "syntax error near unexpected token ';'", and the recipe aborts at parse time before the DKMS script (or anything after the vmlinux block) ever runs. This is an unconditional build break: CI run 28134406848 failed at "debian/rules:211: override_dh_auto_install" with exactly this error after a full 12-minute kernel compile, and the .deb was never built. Remove the stray separator; the preceding "fi; \" already terminates the if-statement. Verified with a make .ONESHELL reproduction (errors before, parses and reaches the script after) and bash -n on the recipe. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
The manifest is a presence contract, but a missing or misdirected --modules-manifest produced an empty module list, which the script treated as "no modules" and exited 0 — silently shipping a kernel without its declared out-of-tree modules. That is exactly the failure the contract exists to prevent. Check the manifest exists before parsing and hard-fail if it does not; only an existing-but-empty (or comment-only) manifest is a legitimate skip. This also removes the now-dead post-parse existence check and drops the cd error-suppression in the path-to-absolute resolution (the file is confirmed present first, so the cd cannot fail and a mangled path can no longer slip through). Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
…uirement
For the standalone developer path the CLI was too permissive:
- An unknown/misspelled option fell into usage(), which exits 0, so a
typo'd flag looked like success. Report it on stderr and exit 1.
- A value-taking flag given as the last argument tripped `set -u` with
a raw "$2: unbound variable". Guard each with require_val so it fails
with a clear "<flag> requires a value" message.
Also document two prerequisites that were implicit: module resolution
needs a Debian-family host with a dpkg database, and the script does not
cross-compile (dkms uses the host toolchain), so it must run on a native
arm64 host for the produced .ko to match the target kernel. --arch only
sets the dkms BUILD_EXCLUSIVE_ARCH label, not the compiler.
Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
1d842df to
916da65
Compare
The Debian Debusine build path now needs kgsl-dkms as a build dependency (via PR #54 against qcom/debian/latest). The package is published in the qli Debusine workspace, so the build step must expose qli as an extra build-dependency source when invoking debusine-action/lib/build. Set EXTRA_BUILD_DEP_WORKSPACES=qli in Build in Debusine and pass DEBUSINE_USER, which lib/build currently requires to apply its extra_repositories compatibility workaround.
The Debian Debusine build path now needs kgsl-dkms as a build dependency (via PR #54 against qcom/debian/latest). The package is published in the qli Debusine workspace, so the build step must expose qli as an extra build-dependency source when invoking debusine-action/lib/build. Set EXTRA_BUILD_DEP_WORKSPACES=qli in Build in Debusine and pass DEBUSINE_USER, which lib/build currently requires to apply its extra_repositories compatibility workaround. Signed-off-by: Bjordis Collaku <bcollaku@qti.qualcomm.com>
9917688 to
916da65
Compare
|
Bjordis Collaku (@bjordiscollaku) what is the status of this PR? would be great to get it in :-) |
Hi Christopher Obbard (@obbardc), technically, status is READY :) It's been ready for a while from my end, it's gonne through iteration of improvements, and also been validated as part of pkg-linux-qcom build with pkg-kgsl enabled (please check PR description on validation), both for ubuntu resolute and debian trixie. One note, as specified at the end of PR " hardware validation, owned by the device team." --> so in this case we would want gfx team to confirm this on target device. Since this is a big chunk of change though, it'd be good to get the mechanism in, and if any incremental changes/improvements arise, we can take care in subsequent PRs. Why it's not merged yet? We switched primary focus to #62 AND #63. I'd say we get #62 and #63 in (they've been validated in I'd appreciate your review on all 3 if/when you get a chance! Thanks in advance, and happy to work together! |
Christopher Obbard (obbardc)
left a comment
There was a problem hiding this comment.
Starting to look great, but some minor thoughts attached. I think you can squash a few commits, I'd like this to build camx-dkms and iris-vpu-dkms to prove the logic, but we can look at that separately if you wish.
| bc, bison, flex, libssl-dev, libelf-dev, dwarves, | ||
| python3, kmod, cpio, rsync, pkg-config, gcc, make | ||
| python3, kmod, cpio, rsync, pkg-config, gcc, make, | ||
| kgsl-dkms (>= 1.0.2), dkms |
There was a problem hiding this comment.
I'd rather this was split into two independent commits:
- one adding
dkms / gccand other deps - one adding
kgsl-dkms
Also, we now have kgsl 1.0.4 in qli (1.0.10 in qli-staging), can we remove the pinned version for kgsl-dkms?
There was a problem hiding this comment.
Good call, I'll split it into deps vs the kgsl-dkms build-dep. And yeah, (>= 1.0.2) was just a floor, with 1.0.4/1.0.10 out now I'll drop the pin.
| fi | ||
| fi; \ | ||
| \ | ||
| # ── DKMS module integration ────────────────────────────────────────────────── |
There was a problem hiding this comment.
can we make this generic for any DKMS build ?
There was a problem hiding this comment.
Yeah this is the first inline cut. 1a833dd pulls it all out into bundle-dkms-modules.sh, which is fully generic (no module names in it), driven by the manifest + Build-Depends. Agreed the intermediate commits are noisy to read though, I'll squash them into the extraction so it reads as the generic tool directly.
| else \ | ||
| echo "Warning: vmlinux not found at $$VMLINUX_PATH — debug package will not contain vmlinux"; \ | ||
| fi | ||
| fi; \ |
There was a problem hiding this comment.
also need to build camx-dkms and iris-vpu-dkms, would be good to do that at the same time...
There was a problem hiding this comment.
With the generic tool it's a two-line change per module (manifest + Build-Depends). I'd keep this PR to the mechanism + kgsl since that's the one validated on resolute and trixie, then turn camx and iris-vpu on in follow-ups so any per-module issues don't hold up the mechanism.
| --dkmstree "$$DKMS_TREE" \ | ||
| -k "$$BASE" \ | ||
| --arch arm64; \ | ||
| find "$$DKMS_TREE/kgsl/$$KGSL_VER/$$BASE" -name '*.ko' | \ |
There was a problem hiding this comment.
wonder if there are other dkms files we should install ? e.g. anything from camx-dkms and iris-vpu-dkms
There was a problem hiding this comment.
The tool bundles the built module into the kernel package, with its debug symbols going to -dbg. On-target validation is still pending with the gfx team, so if anything else turns out to be needed for the module to load we'd want to catch that. Shall we keep it to a separate discussion rather than expanding this PR?
| "debian/linux-image-$$BASE-qcom/lib/modules/$$BASE/extra/$$(basename $$ko)"; \ | ||
| done; \ | ||
| rm -rf "$$DKMS_TREE"; \ | ||
| echo "Bundled msm_kgsl.ko into debian/linux-image-$$BASE-qcom" |
There was a problem hiding this comment.
this is not generic :-)
There was a problem hiding this comment.
ah; you fix that in a later commit. Maybe you can squash them?
There was a problem hiding this comment.
Yep, exactly that. I'll squash the intermediate rules commits into the extraction so the series lands the generic tool directly instead of the inline-then-extracted history.
| # | ||
| # To disable a module temporarily: comment out the line with #. | ||
| # debian/rules is untouched in either case. | ||
| kgsl No newline at end of file |
There was a problem hiding this comment.
surely we don't have to repeat ourselves? can we maybe just look at src directories installed? from memory they just go into /usr/src, so maybe we can't differentiate :/
There was a problem hiding this comment.
I went with an explicit allowlist on purpose. Scanning /usr/src picks up every dkms source that happens to be installed with no way to tell which ones we actually want to bundle, and the explicit list means the build fails loudly if a declared module goes missing rather than quietly shipping without it. The overlap with Build-Depends is one line each, which felt like a fair trade, but if you see a neater way I'm happy to take it.
| @@ -0,0 +1,12 @@ | |||
| # DKMS modules to build and bundle into linux-image-<KVER>-qcom. | |||
There was a problem hiding this comment.
this may be better in a README file on how to add additional dkms modules?
There was a problem hiding this comment.
The how-to is in the manifest header and the PR description at the moment. I like having it next to the thing you actually edit, but happy to move it to a README if you prefer.
| ln -sf "/usr/src/$${name}-$$VER" "$$DKMS_TREE/$${name}/$$VER/source"; \ | ||
| echo "Building DKMS module $${name}/$$VER for $$BASE"; \ | ||
| # Resolve the module from the package manager rather than by globbing | ||
| # /usr/src: <name>-dkms ships exactly one /usr/src/<dir>/dkms.conf |
There was a problem hiding this comment.
also, do we need to ship the dkms source in a package somehow? I think this is a wider question for a follow-up issue as it doesn't look like your pkg-linux-qcom generator ships source code in a separate package (see e.g. https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/templates/sourcebin.control.in?ref_type=heads)
There was a problem hiding this comment.
Agreed, out of scope here, and thanks for filing #66. The tool consumes the -dkms source at build time so it doesn't need to re-ship it, we can settle the separate source package question over there.
| #!/bin/bash | ||
| # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | ||
| # SPDX-License-Identifier: BSD-3-Clause | ||
| set -euo pipefail |
There was a problem hiding this comment.
It'd be good to squash everything build-related into this commit.
There was a problem hiding this comment.
Will do, I'll fold the intermediate rules commits and the fixups into this one so the bundling lands as a single change.
| @@ -380,7 +380,6 @@ override_dh_auto_install: | |||
| else \ | |||
| echo "Warning: vmlinux not found at $$VMLINUX_PATH — debug package will not contain vmlinux"; \ | |||
| fi; \ | |||
There was a problem hiding this comment.
squash this commit :-)
There was a problem hiding this comment.
Same here, this one gets folded into the extraction commit too.
|
Thanks a lot for going through this commit by commit Christopher Obbard (@obbardc), really appreciate the detailed review. Replies inline. Short version: I'll squash the noisy intermediate commits into the extraction, split the deps commit, and drop the version pin. Will ping you once it's pushed. |
Summary
This adds a build-time mechanism that compiles out-of-tree kernel modules from
their DKMS source packages and bundles them into the kernel package, in the same
run that builds the kernel. The device receives one self-contained kernel
package: the module is present and pinned to the exact kernel it was built
against, with no DKMS, compiler, or headers required on the target.
The mechanism is module-agnostic. It is implemented as a standalone, documented
tool (
debian/scripts/bundle-dkms-modules.sh) thatdebian/rulesinvokes duringthe build, and it is driven by a manifest, so onboarding any out-of-tree module
is a two-line change with no change to the build logic.
Design history and rationale: #44.
How it works, in order
flowchart TD P["module DKMS source package<br/>(from the distro apt source)"] K["1. Build kernel + headers<br/>in one packaging run"] H["2. Stage headers in the build tree"] R["3. debian/rules calls<br/>bundle-dkms-modules.sh"] RES["4. Resolve source + tokens<br/>via dpkg -L and dkms.conf"] D["5. dkms build against the<br/>staged headers (private tree)"] J{"6. Built a .ko?"} X["Fail the build<br/>with precise diagnostics"] S["7. Extract debug to -dbg,<br/>strip the shipped copy"] B["8. Bundle into the kernel image<br/>under lib/modules/KVER/extra"] O["9. On device: depmod indexes it,<br/>modprobe + autoload work"] P -. "Build-Depends" .-> RES K --> H --> R --> RES --> D --> J J -- "no" --> X J -- "yes" --> S --> B --> O*-dkmspackage is installed viaBuild-Depends(build-timeonly; it never enters any binary package's runtime dependencies).
debian/rules(override_dh_auto_install) invokes the bundling tool once thetrees are staged.
name/version tokens from
dpkg -Land the shippeddkms.conf.dkms buildagainst the staged headers in a private DKMS tree, so themodule matches the exact kernel and the build stays rootless under
fakeroot.build with precise diagnostics if a listed module produces nothing.
-dbgpackage and strips the shippedcopy, the same two-stage handling an in-tree module gets.
lib/modules/<KVER>/extra/,guarding against duplicate and in-tree name collisions.
depmodindexesextra/, somodprobeand autoload resolve the module.
The tool:
debian/scripts/bundle-dkms-modules.shThe bundling logic is a single standalone tool with a documented CLI, so
debian/rulesstays a thin call, future changes (a new guard, signing,compression) touch one file, and a developer can re-run just the bundling step
against already-staged trees.
The tool resolves each module authoritatively (no path globbing), judges
outcomes by artifacts, hard-fails when a declared module produces nothing, prints actionable diagnostics on failure
(the
make.logtail for a build failure, or thedkms.confgates evaluatedagainst the kernel config for a skip), and guards against name collisions.
CI path:
debian/rulescalls the tooloverride_dh_auto_installinvokes the tool with explicit, absolute paths afterthe kernel, headers, and debug trees are staged:
$(CURDIR)/debian/scripts/bundle-dkms-modules.sh \ --kver "$$BASE" \ --headers-dir "$(CURDIR)/debian/linux-headers-$$BASE-qcom/usr/src/linux-headers-$$BASE" \ --image-pkg-dir "$(CURDIR)/$$PKG" \ --dbg-pkg-dir "$(CURDIR)/$$DBG_PKG" \ --arch "$(DKMS_ARCH)" \ --objcopy "$(OBJCOPY)" \ --modules-manifest "$(CURDIR)/debian/dkms-modules"dh_installmodules(called inoverride_dh_installdeb) wires the postinstdepmodthat indexesextra/on the device.Developer path: run the tool standalone
A developer who has already staged the kernel trees can re-run just the bundling
step, without re-running the whole
dpkg-buildpackage:--helpdocuments the full CLI, prerequisites, and a host-arch note (the toolbuilds with the host toolchain and is intended to run on a native arm64 host).
The manifest:
debian/dkms-modulesA plain-text list of module names, one per line. Comments, blank lines, and CRLF
endings are tolerated. This is the single place that decides which modules are
built and bundled; the tool and
debian/rulesare untouched when it changes.Adding a module is two lines:
debian/dkms-modules.dkmsand<name>-dkms (>= x.y.z)toBuild-Dependsindebian/control.in.Module load policy
Blacklisting and load policy are orthogonal to this change. The bundled module is
installed under
/lib/modules/<KVER>/extra/and indexed by the standarddepmod,so to the loader it is an ordinary module: the usual controls apply by module name,
unchanged (a
blacklistorinstallline inmodprobe.d, ormodprobe.blacklist=or
module_blacklist=on the kernel command line). The kernel package intentionallyships no load policy of its own, because a blacklist is board and policy specific
while this package is shared across boards; that decision stays external to this
mechanism, at the image build stage.
Validation
CI (Ubuntu, resolute). Run
28193902324
(resolute, kernel
7.1.0-rc7-qcom-next-20260618). TheBuild kernel packagestep builds and bundles the module from its
*-dkmspackage:The packaged contents confirm the two-stage handling landed in both packages:
All four packages (image, headers, dbg, dbgsym) built, and the
Upload .deb packages to S3step now passes, so every step in the run isgreen and the artifacts are published to
s3://.../pkg/temp/pkg-linux-qcom/28193902324-1/.CI (Debian, trixie). Run
29125019996
(trixie, via Debusine). With
kgsl-dkmsnow published to the Debusine workspace,the Debian path satisfies the
Build-Depends, the build runs to completion, andmsm_kgsl.kois bundled into the linux-image exactly as on the Ubuntu path. AllDebusine build steps pass and the
.debs publish to S3. Both distro families nowbuild and bundle the module end to end: Ubuntu (resolute, docker) and Debian
(trixie, Debusine).
Local (standalone tool, 18 of 18). The tool was exercised through its CLI
against shimmed leaf tools, so its real control flow, resolution, outcome
judgment, collision guards, and path layout all run:
extra/, debug written to the-dbgtree, strip ran on the shipped copydkms.conf, missingPACKAGE_NAMEmake.logtail; gated skip with config set, with config unset, and with no gates declared; compressed output reportedRequirements (R1 to R7)
Build-Dependson the DKMS source packages. DKMS is a build-time tool, not a runtime mechanism.Depends,Recommends, orSuggestsof any binary package.*-dkmspackage. The kernel CI only consumes it.-dbgpackage.Design decisions
debian/rulesis a thin call, future changes touch one place, and the step is independently re-runnable.make.logand thedkms.confgates.dpkg -Lnames the onedkms.confthe package ships; itsPACKAGE_NAME/PACKAGE_VERSIONare the tokens dkms keys on. No path globbing.fakeroot, away from the root-owned/var/lib/dkms.-dbgpackage viaobjcopy --only-keep-debug, then strip the shipped copy viastrip --strip-debug.Commits (13)
Not in this PR
module loads and functions (
modprobe, autoload). Hardware validation, owned bythe device team.
Notes
qcom/debian/latest.