Skip to content

Commit 4487169

Browse files
klutchellalexgg
authored andcommitted
meta-kernel-block: add layer
Signed-off-by: Alex Gonzalez <alexg@balena.io>
1 parent 77b7f2c commit 4487169

9 files changed

Lines changed: 303 additions & 8 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# kernel-extension.bbclass
2+
#
3+
# Builds a kernel extension block containing a self-consistent kernel image
4+
# PLUS its matching modules.
5+
#
6+
# Unlike kernel-modules-extension.bbclass, this class makes NO ABI-compat
7+
# guarantees against the base OS kernel. The extension is meant to be kexec'd
8+
# into from balena-bootloader, so the running kernel is the one shipped here.
9+
#
10+
# Strategy:
11+
# 1. After do_kernel_resin_injectconfig runs (balena defconfig + BALENA_CONFIGS
12+
# are already merged into .config), discover every *.cfg fragment reachable
13+
# via FILESEXTRAPATHS and merge them all via scripts/kconfig/merge_config.sh
14+
# in sorted order.
15+
# 2. Run olddefconfig once to resolve dependencies.
16+
# 3. Let the normal do_compile / do_install flow proceed.
17+
#
18+
# Usage:
19+
# inherit kernel-extension
20+
# # Place one or more *.cfg fragments in a FILESEXTRAPATHS-reachable dir.
21+
22+
python do_kernel_extend_config() {
23+
import glob
24+
import os
25+
import subprocess
26+
27+
S = d.getVar("S")
28+
B = d.getVar("B")
29+
base_config = os.path.join(B, ".config")
30+
31+
make_cmd = d.getVar("KERNEL_MAKE_CMD") or "make"
32+
make_opts = d.getVar("EXTRA_OEMAKE") or ""
33+
arch = d.getVar("ARCH")
34+
if not arch:
35+
bb.fatal("kernel-extension: ARCH variable not set")
36+
37+
# 1. Discover every *.cfg fragment reachable via FILESEXTRAPATHS, in
38+
# sorted order. Deduplicate paths reachable via multiple entries.
39+
fragments = []
40+
seen = set()
41+
filesextrapaths = d.getVar("FILESEXTRAPATHS") or ""
42+
for path in filesextrapaths.split(":"):
43+
if not path:
44+
continue
45+
for cfg in sorted(glob.glob(os.path.join(path, "*.cfg"))):
46+
if cfg not in seen:
47+
seen.add(cfg)
48+
fragments.append(cfg)
49+
50+
if not fragments:
51+
bb.fatal(
52+
"kernel-extension: no *.cfg fragments found via FILESEXTRAPATHS.\n"
53+
"Place at least one fragment in a FILESEXTRAPATHS-reachable dir.\n"
54+
f"Searched paths: {filesextrapaths}"
55+
)
56+
57+
bb.note(f"Merging {len(fragments)} kernel extension fragment(s):")
58+
for f in fragments:
59+
bb.note(f" {f}")
60+
61+
# 2. Merge every fragment in a single merge_config.sh invocation.
62+
# merge_config.sh accepts multiple input fragments; later inputs
63+
# override earlier ones for conflicting symbols and warn on stderr.
64+
merge_script = os.path.join(S, "scripts", "kconfig", "merge_config.sh")
65+
cmd = " ".join([merge_script, "-m", "-O", B, base_config, *fragments])
66+
ret = subprocess.run(cmd, shell=True, capture_output=True, text=True)
67+
if ret.returncode != 0:
68+
bb.fatal(f"merge_config.sh failed:\n{ret.stderr}")
69+
if ret.stderr:
70+
bb.note(ret.stderr)
71+
72+
# 3. Resolve dependencies.
73+
cmd = f'{make_cmd} {make_opts} -C {S} O={B} ARCH={arch} olddefconfig'
74+
bb.note("Running olddefconfig")
75+
ret = subprocess.run(cmd, shell=True, capture_output=True, text=True)
76+
if ret.returncode != 0:
77+
bb.fatal(f"olddefconfig failed:\n{ret.stderr}")
78+
}
79+
80+
addtask kernel_extend_config after do_kernel_resin_injectconfig before do_compile
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BBPATH .= ":${LAYERDIR}"
2+
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"
3+
BBFILE_COLLECTIONS += "meta-kernel-block"
4+
BBFILE_PATTERN_meta-kernel-block = "^${LAYERDIR}/"
5+
LAYERSERIES_COMPAT_meta-kernel-block = "kirkstone scarthgap"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
2+
# changes incompatibly
3+
POKY_BBLAYERS_CONF_VERSION = "2"
4+
5+
BBPATH = "${TOPDIR}"
6+
BBFILES ?= ""
7+
8+
BBLAYERS ?= " \
9+
${TOPDIR}/../layers/meta-balena/meta-balena-rust \
10+
${TOPDIR}/../layers/meta-balena/meta-balena-common \
11+
${TOPDIR}/../layers/meta-balena/meta-balena-kirkstone \
12+
${TOPDIR}/../layers/meta-balena-raspberrypi \
13+
${TOPDIR}/../layers/poky/meta \
14+
${TOPDIR}/../layers/poky/meta-poky \
15+
${TOPDIR}/../layers/meta-openembedded/meta-oe \
16+
${TOPDIR}/../layers/meta-openembedded/meta-filesystems \
17+
${TOPDIR}/../layers/meta-openembedded/meta-networking \
18+
${TOPDIR}/../layers/meta-openembedded/meta-python \
19+
${TOPDIR}/../layers/meta-openembedded/meta-perl \
20+
${TOPDIR}/../layers/meta-raspberrypi \
21+
${TOPDIR}/../layers/meta-cyclonedx \
22+
${TOPDIR}/../layers/meta-kernel-block \
23+
"
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Supported machines
2+
#MACHINE ?= "raspberrypi"
3+
#MACHINE ?= "raspberrypi2"
4+
#MACHINE ?= "raspberrypi3"
5+
#MACHINE ?= "raspberrypi3-64"
6+
#MACHINE ?= "revpi-connect"
7+
#MACHINE ?= "revpi-connect-s"
8+
#MACHINE ?= "revpi-connect-4"
9+
#MACHINE ?= "revpi-core-3"
10+
#MACHINE ?= "raspberrypi4-64"
11+
#MACHINE ?= "raspberrypi400-64"
12+
#MACHINE ?= "raspberrypicm4-ioboard"
13+
#MACHINE ?= "npe-x500-m3"
14+
#MACHINE ?= "rt-rpi-300"
15+
#MACHINE ?= "raspberrypi3-unipi-neuron"
16+
#MACHINE ?= "raspberrypi4-superhub"
17+
#MACHINE ?= "raspberrypi4-unipi-neuron"
18+
#MACHINE ?= "raspberrypi5"
19+
20+
# More info meta-resin/README.md
21+
#TARGET_REPOSITORY ?= ""
22+
#TARGET_TAG ?= ""
23+
24+
# RaspberryPi specific variables
25+
GPU_MEM = "16"
26+
27+
# for the moment, we disable vc4 graphics for all but the 64 bits machines
28+
DISABLE_VC4GRAPHICS = "1"
29+
DISABLE_VC4GRAPHICS:remove:raspberrypi3-64 = "1"
30+
DISABLE_VC4GRAPHICS:remove:raspberrypi4-64 = "1"
31+
DISABLE_VC4GRAPHICS:remove:raspberrypi5 = "1"
32+
DISABLE_VC4GRAPHICS:remove:raspberrypi0-2w-64 = "1"
33+
DISABLE_VC4GRAPHICS:remove:revpi-connect-s = "1"
34+
35+
# RPI BSP uses uncompressed kernel images by default
36+
KERNEL_IMAGETYPE="zImage"
37+
KERNEL_BOOTCMD="bootz"
38+
39+
# When u-boot is enabled we need to use the "Image" format and the "booti"
40+
# command to load the kernel for 64 bits machines
41+
KERNEL_IMAGETYPE:raspberrypi3-64="Image.gz"
42+
KERNEL_BOOTCMD:raspberrypi3-64 = "booti"
43+
KERNEL_IMAGETYPE:raspberrypi4-64="Image.gz"
44+
KERNEL_BOOTCMD:raspberrypi4-64 = "booti"
45+
KERNEL_IMAGETYPE:raspberrypi5="Image.gz"
46+
KERNEL_BOOTCMD:raspberrypi5 = "booti"
47+
KERNEL_IMAGETYPE:raspberrypi0-2w-64 = "Image.gz"
48+
KERNEL_BOOTCMD:raspberrypi0-2w-64 = "booti"
49+
50+
# RPI Use u-boot. This needs to be 1 as we use u-boot
51+
RPI_USE_U_BOOT = "1"
52+
53+
# Set this to 1 to disable quiet boot and allow bootloader shell access
54+
#OS_DEVELOPMENT = "1"
55+
56+
# Set this to make build system generate resinhup bundles
57+
#RESINHUP ?= "yes"
58+
59+
# Set this to change the supervisor tag used
60+
#SUPERVISOR_TAG ?= "master"
61+
62+
# Compress final raw image
63+
#BALENA_RAW_IMG_COMPRESSION ?= "xz"
64+
65+
# Parallelism Options
66+
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
67+
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
68+
69+
# Resin specific distros
70+
DISTRO ?= "resin-systemd"
71+
72+
# Custom downloads directory
73+
#DL_DIR ?= "${TOPDIR}/downloads"
74+
75+
# Custom sstate directory
76+
#SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
77+
78+
# Inheriting this class has shown to speed up builds due to significantly lower
79+
# amounts of data stored in the data cache as well as on disk.
80+
# http://www.yoctoproject.org/docs/latest/mega-manual/mega-manual.html#ref-classes-rm-work
81+
#INHERIT += "rm_work"
82+
83+
# Remove the old image before the new one is generated to save disk space when RM_OLD_IMAGE is set to 1, this is an easy way to keep the DEPLOY_DIR_IMAGE clean.
84+
RM_OLD_IMAGE = "1"
85+
86+
# Additional image features
87+
USER_CLASSES ?= "buildstats"
88+
89+
# By default disable interactive patch resolution (tasks will just fail instead):
90+
PATCHRESOLVE = "noop"
91+
92+
# Disk Space Monitoring during the build
93+
BB_DISKMON_DIRS = "\
94+
STOPTASKS,${TMPDIR},1G,100K \
95+
STOPTASKS,${DL_DIR},1G,100K \
96+
STOPTASKS,${SSTATE_DIR},1G,100K \
97+
HALT,${TMPDIR},100M,1K \
98+
HALT,${DL_DIR},100M,1K \
99+
HALT,${SSTATE_DIR},100M,1K"
100+
101+
CONF_VERSION = "2"
102+
103+
HOSTTOOLS += "docker iptables"
104+
105+
LICENSE_FLAGS_ACCEPTED = "synaptics-killswitch"
106+
107+
# CycloneDX SBOM and VEX generation
108+
INHERIT += "cyclonedx-export"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
DESCRIPTION = "Kernel block image containing a full kernel + matching modules"
2+
LICENSE = "MIT"
3+
4+
inherit balena-hostapp-extension
5+
6+
IMAGE_INSTALL = "kernel-extension-modules kernel-extension-image-initramfs kernel-extension-devicetree bpftool libbpf"
7+
8+
IMAGE_LINGUAS = ""
9+
VIRTUAL-RUNTIME_init_manager = ""
10+
INITRAMFS_IMAGE = ""
11+
IMAGE_FSTYPES = "tar.gz"
12+
13+
remove_unnecessary_files() {
14+
rm -f ${IMAGE_ROOTFS}/bin ${IMAGE_ROOTFS}/sbin
15+
rm -rf ${IMAGE_ROOTFS}/etc
16+
rm -rf ${IMAGE_ROOTFS}/run
17+
rm -rf ${IMAGE_ROOTFS}/var
18+
}
19+
IMAGE_PREPROCESS_COMMAND += "remove_unnecessary_files;"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require recipes-kernel/linux/kernel-image-initramfs.bb
2+
3+
KERNEL_INITRAMFS_PROVIDER = "virtual/kernel-extension"
4+
KERNEL_INITRAMFS_DEPLOY_DIR = "${DEPLOY_DIR_IMAGE}/kernel-extension"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require recipes-kernel/linux/linux-raspberrypi_6.12.inc
2+
3+
# Bump the extension kernel ahead of the base kernel for HUP testing.
4+
LINUX_VERSION = "6.12.62"
5+
SRCREV_machine = "f8e11438119efd4bd88de4ff394acd5a596ce0a2"
6+
SRCREV_meta = "0bc72383691f29eb7fc4661afa9d67e106635929"
7+
8+
KMETA = "kernel-meta"
9+
10+
SRC_URI = " \
11+
git://github.com/raspberrypi/linux.git;name=machine;nobranch=1;protocol=https \
12+
git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=${LINUX_RPI_KMETA_BRANCH};destsuffix=${KMETA} \
13+
file://powersave.cfg \
14+
file://android-drivers.cfg \
15+
"
16+
17+
require recipes-kernel/linux/linux-raspberrypi.inc
18+
19+
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
20+
FILESEXTRAPATHS:prepend := "${COREBASE}/../meta-balena-raspberrypi/recipes-kernel/linux/files:"
21+
FILESEXTRAPATHS:prepend := "${COREBASE}/../meta-balena-raspberrypi/recipes-kernel/linux/linux-raspberrypi:"
22+
FILESEXTRAPATHS:prepend := "${COREBASE}/../meta-raspberrypi/recipes-kernel/linux/files:"
23+
24+
KERNEL_DTC_FLAGS += "-@ -H epapr"
25+
26+
# Brand this kernel as the extension provider.
27+
KERNEL_PACKAGE_NAME = "kernel-extension"
28+
PROVIDES = "virtual/kernel-extension"
29+
30+
inherit kernel-balena kernel-extension
31+
32+
# Track fragments in the task hash and merge it via the existing
33+
# kernel-extension class.
34+
python () {
35+
import glob
36+
import os
37+
thisdir = d.getVar("THISDIR")
38+
fragments = sorted(glob.glob(os.path.join(thisdir, "files", "*.cfg")))
39+
d.appendVarFlag(
40+
"do_kernel_extend_config", "file-checksums",
41+
" " + " ".join(f"{p}:True" for p in fragments),
42+
)
43+
}

raspberrypi4-64.hostapp.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json
22
version: '2.4'
33
services:
4-
5-
hostapp:
4+
kernel-modules:
65
image: __BUILD_OUTPUT__
7-
x-build: {}
8-
labels:
9-
io.balena.image.store: 'root'
10-
io.balena.image.class: 'hostapp'
11-
io.balena.update.requires-reboot: '1'
12-
io.balena.private.hostapp.board-rev: '${DEVICE_REPO_REV}'
6+
x-build:
7+
recipe: balena-kernel-block
8+
build_args:
9+
- "-t"
10+
- "layers/meta-kernel-block/conf/samples"
11+
profiles:
12+
- kernel-modules

raspberrypi5.hostapp.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json
2+
version: '2.4'
3+
services:
4+
5+
kernel-modules:
6+
image: __BUILD_OUTPUT__
7+
x-build:
8+
recipe: balena-kernel-block
9+
build_args:
10+
- "-t"
11+
- "layers/meta-kernel-block/conf/samples"
12+
profiles:
13+
- kernel-modules

0 commit comments

Comments
 (0)