Skip to content

Kernel#

The BSP offers three kernel options for production-grade software. All of them use the same config fragments, so a board's kernel configuration does not depend on which option is selected.

Option Recipe Layer Source Repo Branch Vendor patches
Staging Kernel linux-ktn meta-ked-kernel Kontron fork sw/misc/linux integration/v<series>-ktn (rebased) yes, carried in the fork
LTS Kernel linux-stable meta-linux-mainline Upstream Stable linux-<lts series>.y (linear) only backports from upstream, carried in the layer
Stable Kernel linux-stable meta-linux-mainline Upstream Stable linux-<newest series>.y (linear) only backports from upstream, carried in the layer

The vendor delta is meant to shrink towards zero as patches are upstreamed, so platforms move from the Staging to the upstream kernels over time.

Platform Support#

Platform Staging Kernel LTS/Stable Kernel Experimental Vendor Kernel
NXP i.MX6UL/ULL supported (default) supported not supported
NXP i.MX8MM supported (default) supported not supported
NXP i.MX8MP supported (default) supported not supported
NXP i.MX93 supported (default) supported not supported
ST STM32MP15 supported (default) not supported not supported
TI AM62L not supported not supported supported (default)

Where a kernel is not supported, none of the machine's device trees exists in it and the build stops with an error naming the machine.

Selecting the Kernel#

The Staging Kernel is the default and needs nothing to be selected. The two upstream kernels are selected by adding a kas fragment to the build:

Kernel kas configuration Version
Staging (default, nothing to add) the series the Kontron fork is on
LTS kas/inc/kernel-lts.yml the series upstream currently maintains as LTS
Stable kas/inc/kernel-stable.yml the newest stable series, never a release candidate

Append the fragment to the platform configuration:

kas build kas/ked-mx8mp.yml:kas/inc/kernel-lts.yml
kas build kas/ked-mx8mp.yml:kas/inc/kernel-stable.yml

The menu command offers the same choice under "Kernel", see Build.

Neither fragment pins a kernel version in the BSP: both follow meta-linux-mainline, which decides what "LTS" and "newest" currently are. The version therefore only moves when bsp:update-layers bumps the locked revision of that layer.

Device trees#

The machine configurations list the device trees of the Staging Kernel, which carries device trees that are not (yet) upstream. When an upstream kernel is selected, the ones it has no source for are dropped from KERNEL_DEVICETREE automatically, for both the kernel and the FIT image.

Which ones those are is stated per device tree in the machine configuration, as the first upstream release carrying it:

KERNEL_DEVICETREE_UPSTREAM[freescale/imx8mp-kontron-dl.dtbo] = "6.13"

Entries without such a line are Kontron-only and are never built against an upstream kernel. So when a device tree is upstreamed, add its line.

A device tree that a backport patch adds to an older kernel is available there too. Those releases are named one by one, because a backport reaches exactly the series whose recipe the patch is added to:

KERNEL_DEVICETREE_BACKPORT[freescale/imx8mp-kontron-dl.dtbo] = "6.12"

Both lines belong in the machine configuration.

The filtering lives in kernel-devicetree-upstream.bbclass in meta-ked-kernel. bitbake -e virtual/kernel | grep ^KERNEL_DEVICETREE= shows the resulting list, and the dropped ones are listed as a note during parsing. Should a line claim more than the kernel actually has, the build stops before compiling with a message naming the device trees without a source.

Backport patches#

The upstream kernels take patches from meta-ked-kernel, for changes that are in a later upstream release but not in the one being built. Because a patch only applies to the series it was made for, it is added in a bbappend for that series, linux-stable_6.12.bbappend next to the existing linux-stable_%.bbappend:

SRC_URI += "file://0001-arm64-dts-imx8mp-add-kontron-dl-overlay.patch"

When such a patch adds a device tree, add the matching KERNEL_DEVICETREE_BACKPORT line to the machine configuration, naming the series of the bbappend. Backporting every device tree of a machine is what it takes to support a platform on a kernel the table above lists as not supported.

Staging Kernel#

The vendor patches live on an integration branch integration/v<series>-ktn that is continuously rebased onto the current stable point release, with the vendor patches always on top. Merge requests add changes and fixups; the fixups are folded after merging so the vendor commits keep a clean, upstreamable shape.

Immutable references#

Because the integration branch is force-pushed, its tip is not a stable reference — every rewrite orphans previously pinned revisions. The BSP therefore never references the integration branch. Instead, CI pushes a protected, never-deleted tag v<series>-ktn-<n> for each revision the BSP references, and the recipe fetches the revision with nobranch=1.

Changing the kernel#

Kernel changes are reviewed as real kernel diffs in sw/misc/linux — the BSP only ever sees the revision bump:

Kernel development workflow

  1. Branch off the integration branch:
git fetch origin integration/v6.12-ktn
git checkout -b feature/my-fix origin/integration/v6.12-ktn
  1. Make your changes. One logical change = one commit, with a proper commit message and an Upstream-Status: trailer (Pending, Submitted [lore link], Backport, Inappropriate [reason]).

To fix an existing patch, do not add a free-standing commit — mark it as a fixup so it can be folded into the right commit:

# fix the code, keep the original message:
git commit --fixup=<sha-of-the-patch-commit>
# fix the code and replace the commit message (opens an editor
# pre-filled with the current message; edit everything below the
# "amend! ..." marker line):
git commit --fixup=amend:<sha-of-the-patch-commit>
# only replace the commit message, no code change:
git commit --allow-empty --fixup=reword:<sha-of-the-patch-commit>

Prefer amend:/reword: over --squash for message changes: they replace the message, whereas --squash appends the new text to the old message.

A reword: changes no file, so it is not listed in the BSP changelog as a change; a step that consists of nothing else is reported as "Commit messages only, no code change." It still gets its own v*-ktn-<n> tag — the messages are where a vendor patch documents itself, Upstream-Status: included, and the revision the BSP pins should carry that.

A MR may consist of nothing but fixups. Leave them unfolded — the reviewer then sees exactly the fix instead of a rewritten patch, and CI folds them after the merge.

  1. Open a MR in sw/misc/linux targeting the integration branch. Review it, then merge fast-forward.

validate-patch-series checks the series as it will look after the merge: it folds the fixups in its own checkout and rejects the MR if one names no commit of the series, if folding conflicts, if a resulting vendor commit has no Upstream-Status: trailer, or if the MR carries a merge commit.

  1. On merge, fold-and-tag-integration-tip folds the fixups into the vendor commits they target and force-pushes the integration branch.

  2. The same job pushes the immutable tag v<series>-ktn-<n> for the folded tip and trigger-bsp-bump starts the BSP's kernel:bump job, which opens a MR that updates SRCTAG/SRCREV/KERNEL_PATCHLEVEL in the recipe.

  3. Review and merge the BSP MR. Open kernel feature branches have to be rebased onto the new integration branch tip afterwards.

Point release rebases#

New stable point releases are mirrored into the fork by mirror-tags:<series>, and rebase:<series>-ktn then rebases the integration branch onto the newest one. A mirrored tag on its own triggers nothing — this job is what turns it into an update. If the series applies cleanly, the branch is force-pushed, and that push starts the same chain as any merge: fold, tag, BSP MR with the new KERNEL_PATCHLEVEL.

Vendor patches that have been upstreamed meanwhile are contained in the new point release and are dropped by the rebase.

If the rebase conflicts, the job fails and the branch stays where it is. Resolve it in sw/misc/linux and force-push the result; that push tags it and bumps the BSP as usual. The BSP only ever sees the resulting revision bump.

CI jobs#

Job Trigger Purpose
kernel:bump Triggered from sw/misc/linux after a merge into the integration branch; also Run pipeline with KERNEL_TAG/KERNEL_SHA set Rewrite SRCTAG/SRCREV/KERNEL_PATCHLEVEL in linux-ktn_6.12.bb and open a MR
validate-patch-series (in sw/misc/linux-ci) MR targeting integration/* Validate the folded series: no merge commits, every fixup foldable, Upstream-Status: on every vendor commit
fold-and-tag-integration-tip (in sw/misc/linux-ci) Push to integration/v*-ktn Fold the fixups, force-push the branch and the new v<series>-ktn-<n> tag atomically
mirror-tags:<series> (in sw/misc/linux-ci) Schedule, or Run pipeline with SYNC_TAGS=true Mirror the upstream stable tags of the series into the fork
rebase:<series>-ktn (in sw/misc/linux-ci) Same run as mirror-tags; skip it with REBASE_INTEGRATION=false Rebase the integration branch onto the newest mirrored point release
bsp:update-layers Schedule, or Run pipeline with UPDATE_LAYERS=true Bump the locked layer revisions, which moves the LTS and Stable Kernel to a new point release
bsp:build:kernel Changes to the kernel layer, the machine configurations or kas/inc/kernel-*.yml; every scheduled pipeline; a button otherwise Build the kernel and the FIT image for every platform against the LTS and the Stable Kernel