public inbox for openembedded-core@lists.openembedded.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images
@ 2026-03-18 23:30 Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 1/4] bootconfig: add recipe Francesco Valla
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Francesco Valla @ 2026-03-18 23:30 UTC (permalink / raw)
  To: openembedded-core
  Cc: Adrian Freihofer, Francesco Castagnotto, Francesco Valla

Hello,

this patchset introduces support for attaching a bootconfig block both
to plain initramfs images and inside FIT images. The bootconfig source
can be configured globally or per-image.

== Introduction to bootconfig ==

A bootconfig is a small footer that can be added to an initramfs image
and is read by the kernel at startup if the CONFIG_BOOT_CONFIG option is
set. Its content can be used to expand the kernel command line even
beyond its canonical size limit.

An interesting point about the bootconfig mechanism is that the
initramfs image does *not* need to be there for the bootconfig to be
read, as its presence is always checked starting from the bottom of the
declared initramfs area.

More details on the bootconfig concept can be found at [0]. 

== Patchset walkthrough == 

Patch 1 adds a new recipe to compile the tool used for bootconfig
management; being this part of the Linux kernel source code, it is
compiled from the kernel shared workdir.

Patch 2 adds a new image conversion type to add the bootconfig to an
image. While today only a cpio (plain or compressed) or an ext2 image
would make sense here as a base for such operation, this is not strictly
enforced as new usecases may arise in the future. A new bbclass
containing the relevant configuration variables for this operation is
also introduced in this patch.

Patche 3 adds a test recipe containing a bootconfig that can be used for
tests; this recipe will then be used by patch 4.

Patch 4 adds support for adding a bootconfig inside a FIT image. Since
the bootconfig is always read from the end of an initramfs memory area
(even if the initramfs isn´t really there!), two forms of support are
added here, both enabled by the FIT_INCLUDE_BOOTCONFIG variable:

 - if INITRAMFS_IMAGE is set, the .bootconfig image is searched to be
   included as ramdisk section;
 - if INITRAMFS_IMAGE is not set, a dummy/empty initramfs artifact is
   created and the bootconfig block is added there; the resulting binary
   is then added as ramdisk section.

It should be noted that if INITRAMFS_IMAGE_BUNDLE the bootconfig will
NOT be included inside the FIT image and a warning will be displayed.

== Usecases ==

The main usecases I can think of are:

 - (the one driving the work) initramfs-less dm-verity setup starting
   from a bootconfig included inside the FIT image and verified as part
   of the FIT verification; I have a working PoC for this based on a
   modified version of image_types_verity from meta-openembedded;
 - complex tracing setups where the classic kernel command line is not
   sufficient (bootconfig is e.g. indicated as boot-time tracing
   mechanism [1]);
 - debug flexibility: no need to modify the kernel nor the bootloader
   setup to pass debug arguments to the kernel.

Bonus track: the first usecase was featured in Francesco Castagnotto's
podcast "I use Yocto btw", with me explaining it (in italian) [2].

== Open points == 

Following points are still open, with probable room for improvements:

 - the BOOTCONFIG_TASK mechanism feels legacy, but I couldn't think of
   a better one;
 - I'm not sure if and how the INITRAMFS_IMAGE_BUNDLE case should be
   managed (maybe bundling also the bootconfig itself?);
 - should an example bootconfig recipe be added?

Thank you in advance for any feedback on this!

Best regards,
Francesco

[0] https://docs.kernel.org/admin-guide/bootconfig.html
[1] https://docs.kernel.org/trace/boottime-trace.html
[2] https://open.spotify.com/episode/0qR6lzm0nz4uylt0lCBfYQ

Signed-off-by: Francesco Valla <francesco@valla.it>
---
Francesco Valla (4):
      bootconfig: add recipe
      image_types: add bootconfig conversion type
      recipes-test: add bootconfig-test recipe
      kernel-fit-image: add bootconfig support

 .../recipes-test/bootconfig/bootconfig-test.bb     | 20 +++++++
 .../bootconfig/bootconfig-test/bootconfig-test.txt |  6 +++
 meta/classes-recipe/bootconfig-config.bbclass      | 12 +++++
 meta/classes-recipe/image_types.bbclass            | 15 +++++-
 meta/classes-recipe/kernel-fit-image.bbclass       | 44 +++++++++++++--
 meta/conf/image-fitimage.conf                      |  3 ++
 meta/lib/oeqa/selftest/cases/fitimage.py           | 63 +++++++++++++++++++---
 meta/recipes-kernel/bootconfig/bootconfig.bb       | 44 +++++++++++++++
 8 files changed, 193 insertions(+), 14 deletions(-)
---
base-commit: 531f87111d83430615f2e20dd41a3dd5fc25c7ab
change-id: 20260318-bootconfig-47ebc0231153

Best regards,
-- 
Francesco Valla <francesco@valla.it>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH RFC 1/4] bootconfig: add recipe
  2026-03-18 23:30 [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images Francesco Valla
@ 2026-03-18 23:30 ` Francesco Valla
  2026-03-19  8:54   ` Freihofer, Adrian
  2026-03-18 23:30 ` [PATCH RFC 2/4] image_types: add bootconfig conversion type Francesco Valla
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Francesco Valla @ 2026-03-18 23:30 UTC (permalink / raw)
  To: openembedded-core
  Cc: Adrian Freihofer, Francesco Castagnotto, Francesco Valla

Add a new recipe for the bootconfig tool, with source coming directly
from the kernel shared workdir.

Signed-off-by: Francesco Valla <francesco@valla.it>
---
 meta/recipes-kernel/bootconfig/bootconfig.bb | 44 ++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/meta/recipes-kernel/bootconfig/bootconfig.bb b/meta/recipes-kernel/bootconfig/bootconfig.bb
new file mode 100644
index 0000000000000000000000000000000000000000..77ee70dd1839ef90a292cf829f4f3a4353f85c28
--- /dev/null
+++ b/meta/recipes-kernel/bootconfig/bootconfig.bb
@@ -0,0 +1,44 @@
+SUMMARY = "Apply, delete or show boot config"
+DESCRIPTION = "bootconfig is a tool that can be used to add a boot config block \
+at the end of a kernel initramfs, as well as remove it or show its content."
+LICENSE = "GPL-2.0-only"
+
+inherit kernelsrc kernel-arch
+
+do_populate_lic[depends] += "virtual/kernel:do_shared_workdir"
+do_configure[depends] += "virtual/kernel:do_shared_workdir"
+
+EXTRA_OEMAKE = "\
+    -C ${S}/tools/bootconfig \
+    O=${B} \
+    CROSS=${TARGET_PREFIX} \
+    CC="${CC} ${DEBUG_PREFIX_MAP} -ffile-prefix-map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH} ${CFLAGS}" \
+    HOSTCC="${BUILD_CC} ${BUILD_CFLAGS}" \
+    LD="${LD}" \
+    AR=${AR} \
+    ARCH=${ARCH} \
+    V=1 \
+    'DESTDIR=${D}' \
+    'prefix=${prefix}' \
+    'bindir=${bindir}' \
+"
+
+do_compile() {
+	oe_runmake ${B}/bootconfig
+}
+
+do_install() {
+	install -d ${D}${bindir}
+	oe_runmake install
+}
+
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+python do_package:prepend() {
+    d.setVar('PKGV', d.getVar("KERNEL_VERSION").split("-")[0])
+}
+
+B = "${WORKDIR}/${BPN}-${PV}"
+
+BBCLASSEXTEND = "native nativesdk"

-- 
2.53.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC 2/4] image_types: add bootconfig conversion type
  2026-03-18 23:30 [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 1/4] bootconfig: add recipe Francesco Valla
@ 2026-03-18 23:30 ` Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 3/4] recipes-test: add bootconfig-test recipe Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 4/4] kernel-fit-image: add bootconfig support Francesco Valla
  3 siblings, 0 replies; 7+ messages in thread
From: Francesco Valla @ 2026-03-18 23:30 UTC (permalink / raw)
  To: openembedded-core
  Cc: Adrian Freihofer, Francesco Castagnotto, Francesco Valla

Add the addition of a bootconfig block at the end of an image as a
conversion type; while a bootconfig is mostly used in conjuntion with an
initramfs (i.e.: a cpio image or one of its compressed forms), having it
as a generic conversion type simplifies the implemntation and is ready
for future modifications at kernel side.

The following configurations variables are introduced (in a separate
bbclass, for further usage by other components):

  - BOOTCONFIG_SRC: source file to be used as bootconfig, to be found
    inside DEPLOY_DIR_IMAGE;
  - BOOTCONFIG_TASK: task deploying the bootconfig source file specified
    in BOOTCONFIG_SRC to DEPLOY_DIR_IMAGE; an image using the bootconfig
    modifier will depend on it.

Signed-off-by: Francesco Valla <francesco@valla.it>
---
 meta/classes-recipe/bootconfig-config.bbclass | 12 ++++++++++++
 meta/classes-recipe/image_types.bbclass       | 15 +++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/meta/classes-recipe/bootconfig-config.bbclass b/meta/classes-recipe/bootconfig-config.bbclass
new file mode 100644
index 0000000000000000000000000000000000000000..3d34fc47a3a684aef1ecdbd5ed52c904611bf95d
--- /dev/null
+++ b/meta/classes-recipe/bootconfig-config.bbclass
@@ -0,0 +1,12 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+# Name of the file to be used as bootconfig source, to be found inside DEPLOY_DIR_IMAGE
+BOOTCONFIG_SRC ?= ""
+
+# Task deploying the bootconfig source to DEPLOY_DIR_IMAGE
+#  e.g.: BOOTCONFIG_TASK = "bootconfig-debug:do_deploy"
+BOOTCONFIG_TASK ?= ""
diff --git a/meta/classes-recipe/image_types.bbclass b/meta/classes-recipe/image_types.bbclass
index e6ef0ce11e40c0f8388fb5547ab03943004bde2f..98c6d9e836f5c80f78e6f6f32aa923de66feb836 100644
--- a/meta/classes-recipe/image_types.bbclass
+++ b/meta/classes-recipe/image_types.bbclass
@@ -264,9 +264,18 @@ IMAGE_CMD:f2fs () {
 	sload.f2fs -f ${IMAGE_ROOTFS} ${IMGDEPLOYDIR}/${IMAGE_NAME}.f2fs
 }
 
+oe_bootconfig() {
+	local src_image=$1
+	if [ -z "${BOOTCONFIG_SRC}" ]; then
+		bbfatal "bootconfig image type requested but BOOTCONFIG_SRC is not set"
+	fi
+	cp ${src_image} ${src_image}.bootconfig
+	bootconfig -a ${DEPLOY_DIR_IMAGE}/${BOOTCONFIG_SRC} ${src_image}.bootconfig
+}
+
 EXTRA_IMAGECMD = ""
 
-inherit siteinfo kernel-arch image-artifact-names
+inherit siteinfo kernel-arch image-artifact-names bootconfig-config
 
 JFFS2_ENDIANNESS ?= "${@oe.utils.conditional('SITEINFO_ENDIANNESS', 'le', '-l', '-b', d)}"
 JFFS2_ERASEBLOCK ?= "0x40000"
@@ -333,7 +342,7 @@ IMAGE_TYPES:append:x86-64 = " hddimg iso"
 # CONVERSION_CMD/DEPENDS.
 COMPRESSIONTYPES ?= ""
 
-CONVERSIONTYPES = "gz bz2 lzma xz lz4 lzo zip 7zip zst sum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum bmap u-boot vmdk vhd vhdx vdi qcow2 base64 gzsync zsync ${COMPRESSIONTYPES}"
+CONVERSIONTYPES = "gz bz2 lzma xz lz4 lzo zip 7zip zst sum md5sum sha1sum sha224sum sha256sum sha384sum sha512sum bmap u-boot vmdk vhd vhdx vdi qcow2 base64 gzsync zsync bootconfig ${COMPRESSIONTYPES}"
 CONVERSION_CMD:lzma = "lzma -k -f -7 ${IMAGE_NAME}.${type}"
 CONVERSION_CMD:gz = "gzip -f -9 -n -c --rsyncable ${IMAGE_NAME}.${type} > ${IMAGE_NAME}.${type}.gz"
 CONVERSION_CMD:bz2 = "pbzip2 -f -k ${IMAGE_NAME}.${type}"
@@ -360,6 +369,7 @@ CONVERSION_CMD:qcow2 = "qemu-img convert -O qcow2 ${IMAGE_NAME}.${type} ${IMAGE_
 CONVERSION_CMD:base64 = "base64 ${IMAGE_NAME}.${type} > ${IMAGE_NAME}.${type}.base64"
 CONVERSION_CMD:zsync = "zsyncmake_curl ${IMAGE_NAME}.${type}"
 CONVERSION_CMD:gzsync = "zsyncmake_curl -z ${IMAGE_NAME}.${type}"
+CONVERSION_CMD:bootconfig = "oe_bootconfig ${IMAGE_NAME}.${type}"
 CONVERSION_DEPENDS_lzma = "xz-native"
 CONVERSION_DEPENDS_gz = "pigz-native"
 CONVERSION_DEPENDS_bz2 = "pbzip2-native"
@@ -380,6 +390,7 @@ CONVERSION_DEPENDS_vhdx = "qemu-system-native"
 CONVERSION_DEPENDS_vhd = "qemu-system-native"
 CONVERSION_DEPENDS_zsync = "zsync-curl-native"
 CONVERSION_DEPENDS_gzsync = "zsync-curl-native"
+CONVERSION_DEPENDS_bootconfig = "bootconfig-native ${BOOTCONFIG_TASK}"
 
 RUNNABLE_IMAGE_TYPES ?= "ext2 ext3 ext4"
 RUNNABLE_MACHINE_PATTERNS ?= "qemu"

-- 
2.53.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC 3/4] recipes-test: add bootconfig-test recipe
  2026-03-18 23:30 [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 1/4] bootconfig: add recipe Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 2/4] image_types: add bootconfig conversion type Francesco Valla
@ 2026-03-18 23:30 ` Francesco Valla
  2026-03-18 23:30 ` [PATCH RFC 4/4] kernel-fit-image: add bootconfig support Francesco Valla
  3 siblings, 0 replies; 7+ messages in thread
From: Francesco Valla @ 2026-03-18 23:30 UTC (permalink / raw)
  To: openembedded-core
  Cc: Adrian Freihofer, Francesco Castagnotto, Francesco Valla

Add a test recipe deploying a fixed bootconfig source file to
DEPLOY_DIR_IMAGE, to be used in tests that expect a bootconfig to be
available.

Signed-off-by: Francesco Valla <francesco@valla.it>
---
 .../recipes-test/bootconfig/bootconfig-test.bb       | 20 ++++++++++++++++++++
 .../bootconfig/bootconfig-test/bootconfig-test.txt   |  6 ++++++
 2 files changed, 26 insertions(+)

diff --git a/meta-selftest/recipes-test/bootconfig/bootconfig-test.bb b/meta-selftest/recipes-test/bootconfig/bootconfig-test.bb
new file mode 100644
index 0000000000000000000000000000000000000000..0cf74fa93652009466220f21001923a81d628a2e
--- /dev/null
+++ b/meta-selftest/recipes-test/bootconfig/bootconfig-test.bb
@@ -0,0 +1,20 @@
+SUMMARY = "Test bootconfig"
+DESCRIPTION = "This generates a dummy bootconfig to be used to for testing."
+LICENSE = "MIT"
+
+SRC_URI = "file://bootconfig-test.txt"
+
+EXCLUDE_FROM_WORLD = "1"
+ 
+inherit deploy nopackages
+
+do_configure[noexec] = "1"
+do_compile[noexec] = "1"
+deltask do_stash_locale
+deltask do_install
+deltask do_populate_sysroot
+
+do_deploy() {
+    install -m0664 ${UNPACKDIR}/bootconfig-test.txt ${DEPLOYDIR}/bootconfig-test.txt
+}
+addtask deploy after do_unpack before do_build
diff --git a/meta-selftest/recipes-test/bootconfig/bootconfig-test/bootconfig-test.txt b/meta-selftest/recipes-test/bootconfig/bootconfig-test/bootconfig-test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c194018b0bd0e225aaf01a49dff78fcaebe8a7d4
--- /dev/null
+++ b/meta-selftest/recipes-test/bootconfig/bootconfig-test/bootconfig-test.txt
@@ -0,0 +1,6 @@
+kernel {
+  root = 01234567-89ab-cdef-0123-456789abcd
+}
+init {
+  splash
+}

-- 
2.53.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC 4/4] kernel-fit-image: add bootconfig support
  2026-03-18 23:30 [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images Francesco Valla
                   ` (2 preceding siblings ...)
  2026-03-18 23:30 ` [PATCH RFC 3/4] recipes-test: add bootconfig-test recipe Francesco Valla
@ 2026-03-18 23:30 ` Francesco Valla
  3 siblings, 0 replies; 7+ messages in thread
From: Francesco Valla @ 2026-03-18 23:30 UTC (permalink / raw)
  To: openembedded-core
  Cc: Adrian Freihofer, Francesco Castagnotto, Francesco Valla

Support for bootconfig is added to generated FITs in two forms, both
depending on the FIT_INCLUDE_BOOTCONFIG being set to 1 to be enabled:

  - if INITRAMFS_IMAGE is set, a .bootconfig image will be searched
    instead of the plain or compressed cpio archives;
  - if INITRAMFS_IMAGE is not set, a dummy initramfs will be generated
    and the bootconfig specified in BOOTCONFIG_SRC will be attached to
    it.

The case where both FIT_INCLUDE_BOOTCONFIG and INITRAMFS_IMAGE_BUNDLE
are set to '1' is not supported, as it wouldn't work as expected on the
target device.

Signed-off-by: Francesco Valla <francesco@valla.it>
---
 meta/classes-recipe/kernel-fit-image.bbclass | 44 +++++++++++++++++--
 meta/conf/image-fitimage.conf                |  3 ++
 meta/lib/oeqa/selftest/cases/fitimage.py     | 63 ++++++++++++++++++++++++----
 3 files changed, 98 insertions(+), 12 deletions(-)

diff --git a/meta/classes-recipe/kernel-fit-image.bbclass b/meta/classes-recipe/kernel-fit-image.bbclass
index 367bc9bcfd3a4cd237e466269fa143941a02031a..9188723252912f2db6c9952798f66798cfe32b78 100644
--- a/meta/classes-recipe/kernel-fit-image.bbclass
+++ b/meta/classes-recipe/kernel-fit-image.bbclass
@@ -1,5 +1,5 @@
 
-inherit kernel-arch kernel-artifact-names uboot-config deploy
+inherit kernel-arch kernel-artifact-names uboot-config bootconfig-config deploy
 require conf/image-fitimage.conf
 
 S = "${UNPACKDIR}"
@@ -12,6 +12,7 @@ EXCLUDE_FROM_WORLD = "1"
 DEPENDS += "\
     u-boot-tools-native dtc-native \
     ${@'kernel-signing-keys-native' if d.getVar('FIT_GENERATE_KEYS') == '1' else ''} \
+    ${@'bootconfig-native' if (d.getVar('FIT_INCLUDE_BOOTCONFIG') == '1' and not d.getVar("INITRAMFS_IMAGE")) else ''} \
 "
 
 python () {
@@ -23,6 +24,9 @@ python () {
         else:
             d.appendVarFlag('do_compile', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
 
+    if not image and d.getVar('BOOTCONFIG_TASK') and d.getVar('FIT_INCLUDE_BOOTCONFIG') == '1':
+        d.appendVarFlag('do_compile', 'depends', ' ${BOOTCONFIG_TASK}')
+
     #check if there are any dtb providers
     providerdtb = d.getVar("PREFERRED_PROVIDER_virtual/dtb")
     if providerdtb:
@@ -54,8 +58,24 @@ FIT_KERNEL_SIGN_ENABLE ?= "${UBOOT_SIGN_ENABLE}"
 FIT_KERNEL_SIGN_KEYNAME ?= "${UBOOT_SIGN_KEYNAME}"
 FIT_KERNEL_SIGN_KEYDIR ?= "${UBOOT_SIGN_KEYDIR}"
 
+create_bootconfig_bin() {
+    if [ ! -e ${DEPLOY_DIR_IMAGE}/${BOOTCONFIG_SRC} ]; then
+        bbfatal "Did not find bootconfig source file: ${DEPLOY_DIR_IMAGE}/${BOOTCONFIG_SRC}"
+    fi
+
+    # Create empty file
+    dd if=/dev/zero of=bootconfig.bin count=0
+
+    # Add bootconfig to file
+    bootconfig -a ${DEPLOY_DIR_IMAGE}/${BOOTCONFIG_SRC} bootconfig.bin
+
+    # Re-read bootconfig
+    bootconfig -l bootconfig.bin
+}
+
 python do_compile() {
     import shutil
+    import subprocess
     import oe.fitimage
 
     itsfile = "fit-image.its"
@@ -135,10 +155,18 @@ python do_compile() {
 
     # Prepare a ramdisk section.
     initramfs_image = d.getVar('INITRAMFS_IMAGE')
-    if initramfs_image and d.getVar("INITRAMFS_IMAGE_BUNDLE") != '1':
+    if initramfs_image and d.getVar("INITRAMFS_IMAGE_BUNDLE") == '1':
+        bb.note("Initramfs is bundled with kernel image, not including it as ramdisk")
+        if d.getVar("FIT_INCLUDE_BOOTCONFIG") == '1':
+            bb.warn("FIT_INCLUDE_BOOTCONFIG not supported if INITRAMFS_IMAGE_BUNDLE is set. Bootconfig won't be included in the FIT image.")
+    elif initramfs_image:
         # Find and use the first initramfs image archive type we find
+        fstypes = d.getVar("FIT_SUPPORTED_INITRAMFS_FSTYPES").split()
+        if d.getVar("FIT_INCLUDE_BOOTCONFIG") == '1':
+            bb.note("Including initramfs with bootconfig")
+            fstypes = [ "%s.bootconfig" % f for f in fstypes ]
         found = False
-        for img in d.getVar("FIT_SUPPORTED_INITRAMFS_FSTYPES").split():
+        for img in fstypes:
             initramfs_path = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), "%s.%s" % (d.getVar('INITRAMFS_IMAGE_NAME'), img))
             if os.path.exists(initramfs_path):
                 bb.note("Found initramfs image: " + initramfs_path)
@@ -152,7 +180,15 @@ python do_compile() {
                 bb.note("Did not find initramfs image: " + initramfs_path)
 
         if not found:
-            bb.fatal("Could not find a valid initramfs type for %s, the supported types are: %s" % (d.getVar('INITRAMFS_IMAGE_NAME'), d.getVar('FIT_SUPPORTED_INITRAMFS_FSTYPES')))
+            bb.fatal("Could not find a valid initramfs type for %s, the supported types are: %s" % (d.getVar('INITRAMFS_IMAGE_NAME'), " ".join(fstypes)))
+    elif d.getVar("FIT_INCLUDE_BOOTCONFIG") == '1':
+        # Include bootconfig also without an initramfs, emitting a dedicated ramdisk section
+        bb.build.exec_func('create_bootconfig_bin', d)
+
+        root_node.fitimage_emit_section_ramdisk("ramdisk-1", "bootconfig.bin",
+            "bootconfig",
+            d.getVar("UBOOT_RD_LOADADDRESS"),
+            d.getVar("UBOOT_RD_ENTRYPOINT"))
 
     #
     # Prepare loadables sections
diff --git a/meta/conf/image-fitimage.conf b/meta/conf/image-fitimage.conf
index 2fdb816d556c786dcc2c14cb149446eaddc2ff4b..b2178853f388e320710b3c0117799145795bf8f4 100644
--- a/meta/conf/image-fitimage.conf
+++ b/meta/conf/image-fitimage.conf
@@ -37,6 +37,9 @@ FIT_CONF_PREFIX[doc] = "Prefix to use for FIT configuration node name"
 
 FIT_SUPPORTED_INITRAMFS_FSTYPES ?= "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio"
 
+# Include bootconfig (either with or without initramfs)
+FIT_INCLUDE_BOOTCONFIG ?= "0"
+
 # Allow user to support special use cases where the kernel binary is
 # not included in the FIT image itself.
 # This is particularly useful for UKI-based setups, where the kernel
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 3541c07520a8ee3f212471430792c31334d54278..3d3f7cc036253c6ecffa86d844a7113504447912 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -419,12 +419,15 @@ class KernelFitImageBase(FitImageTestCase):
         Call the get_bb_vars function once and get all variables needed by the test case.
         """
         internal_used = {
+            'BOOTCONFIG_SRC',
+            'BOOTCONFIG_TASK',
             'DEPLOY_DIR_IMAGE',
             'FIT_CONF_DEFAULT_DTB',
             'FIT_CONF_MAPPINGS',
             'FIT_CONF_PREFIX',
             'FIT_DESC',
             'FIT_HASH_ALG',
+            'FIT_INCLUDE_BOOTCONFIG',
             'FIT_KERNEL_COMP_ALG',
             'FIT_LOADABLES',
             'FIT_LOADABLE_ENTRYPOINT',
@@ -528,6 +531,7 @@ class KernelFitImageBase(FitImageTestCase):
             ]
         """
         dtb_files, dtb_symlinks = FitImageTestCase._get_dtb_files(bb_vars)
+        fit_include_bootconfig = bb_vars['FIT_INCLUDE_BOOTCONFIG']
         fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL']
         fit_uboot_env = bb_vars['FIT_UBOOT_ENV']
         initramfs_image = bb_vars['INITRAMFS_IMAGE']
@@ -552,7 +556,8 @@ class KernelFitImageBase(FitImageTestCase):
         else:
             not_images.append('setup-1')
 
-        if initramfs_image and initramfs_image_bundle != "1":
+        if (initramfs_image and initramfs_image_bundle != "1") or \
+           (fit_include_bootconfig == "1" and not initramfs_image):
             images.append('ramdisk-1')
         else:
             not_images.append('ramdisk-1')
@@ -627,6 +632,7 @@ class KernelFitImageBase(FitImageTestCase):
         return (req_its_paths, not_req_its_paths)
 
     def _get_req_its_fields(self, bb_vars):
+        fit_include_bootconfig = bb_vars['FIT_INCLUDE_BOOTCONFIG']
         initramfs_image = bb_vars['INITRAMFS_IMAGE']
         initramfs_image_bundle = bb_vars['INITRAMFS_IMAGE_BUNDLE']
         uboot_rd_loadaddress = bb_vars.get('UBOOT_RD_LOADADDRESS')
@@ -643,7 +649,8 @@ class KernelFitImageBase(FitImageTestCase):
             'load = <' + str(bb_vars['UBOOT_LOADADDRESS']) + '>;',
             'entry = <' + str(bb_vars['UBOOT_ENTRYPOINT']) + '>;',
         ]
-        if initramfs_image and initramfs_image_bundle != "1":
+        if (initramfs_image and initramfs_image_bundle != "1") or \
+           (fit_include_bootconfig == "1" and not initramfs_image):
             its_field_check.append('type = "ramdisk";')
             if uboot_rd_loadaddress:
                 its_field_check.append("load = <%s>;" % uboot_rd_loadaddress)
@@ -666,11 +673,13 @@ class KernelFitImageBase(FitImageTestCase):
                 # Works only for tests were the symlink is with -alias suffix
                 its_field_check.append('fdt = "fdt-%s";' % dtb.replace('-alias', ''))
 
-            if initramfs_image and initramfs_image_bundle != "1":
+            if (initramfs_image and initramfs_image_bundle != "1") or \
+               (fit_include_bootconfig == "1" and not initramfs_image):
                 its_field_check.append('ramdisk = "ramdisk-1";')
         else:
             its_field_check.append('kernel = "kernel-1";')
-            if initramfs_image and initramfs_image_bundle != "1":
+            if (initramfs_image and initramfs_image_bundle != "1") or \
+               (fit_include_bootconfig == "1" and not initramfs_image):
                 its_field_check.append('ramdisk = "ramdisk-1";')
 
         return its_field_check
@@ -680,7 +689,8 @@ class KernelFitImageBase(FitImageTestCase):
         if bb_vars.get('UBOOT_SIGN_ENABLE') != "1":
             return {}
         sign_images = '"kernel", "fdt"'
-        if bb_vars['INITRAMFS_IMAGE'] and bb_vars['INITRAMFS_IMAGE_BUNDLE'] != "1":
+        if (bb_vars['INITRAMFS_IMAGE'] and bb_vars['INITRAMFS_IMAGE_BUNDLE'] != "1") or \
+           (bb_vars['FIT_INCLUDE_BOOTCONFIG'] == "1" and not bb_vars['INITRAMFS_IMAGE']):
             sign_images += ', "ramdisk"'
         if bb_vars['FIT_UBOOT_ENV']:
             sign_images += ', "bootscr"'
@@ -705,6 +715,7 @@ class KernelFitImageBase(FitImageTestCase):
         """Generate a dictionary of expected sections in the output of dumpimage"""
         dtb_files, dtb_symlinks = FitImageTestCase._get_dtb_files(bb_vars)
         fit_hash_alg = bb_vars['FIT_HASH_ALG']
+        fit_include_bootconfig = bb_vars['FIT_INCLUDE_BOOTCONFIG']
         fit_sign_alg = bb_vars['FIT_SIGN_ALG']
         fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL']
         fit_uboot_env = bb_vars['FIT_UBOOT_ENV']
@@ -732,7 +743,8 @@ class KernelFitImageBase(FitImageTestCase):
         if fit_uboot_env:
             req_sections['bootscr-' + fit_uboot_env] = { "Type": "Script" }
         # Add the initramfs
-        if initramfs_image and initramfs_image_bundle != "1":
+        if (initramfs_image and initramfs_image_bundle != "1") or \
+           (fit_include_bootconfig == "1" and not initramfs_image):
             req_sections['ramdisk-1'] = {
                 "Type": "RAMDisk Image",
                 "Load Address": bb_vars['UBOOT_RD_LOADADDRESS'],
@@ -762,7 +774,8 @@ class KernelFitImageBase(FitImageTestCase):
                         "Kernel": "kernel-1",
                         "FDT": 'fdt-' + real_dtb,
                     }
-                if initramfs_image and initramfs_image_bundle != "1":
+                if (initramfs_image and initramfs_image_bundle != "1") or \
+                   (fit_include_bootconfig == "1" and not initramfs_image):
                     req_sections[conf_name]['Init Ramdisk'] = "ramdisk-1"
                 if loadables:
                     req_sections[conf_name]['Loadables'] = ",".join(loadables)
@@ -771,7 +784,8 @@ class KernelFitImageBase(FitImageTestCase):
             req_sections[conf_name] = {
                 "Kernel": "kernel-1"
             }
-            if initramfs_image and initramfs_image_bundle != "1":
+            if (initramfs_image and initramfs_image_bundle != "1") or \
+               (fit_include_bootconfig == "1" and not initramfs_image):
                 req_sections[conf_name]['Init Ramdisk'] = "ramdisk-1"
             if loadables:
                 req_sections[conf_name]['Loadables'] = ",".join(loadables)
@@ -886,6 +900,36 @@ FIT_LOADABLE_TYPE[loadable1] = "firmware"
 FIT_LOADABLE_FILENAME[loadable2] = "linux.bin"
 FIT_LOADABLE_LOADADDRESS[loadable2] = "0x87000000"
 FIT_LOADABLE_TYPE[loadable2] = "firmware"
+"""
+        config = self._config_add_kernel_classes(config)
+        self.write_config(config)
+        bb_vars = self._fit_get_bb_vars()
+        self._test_fitimage(bb_vars)
+
+    def test_fit_image_bootconfig(self):
+        """
+        Summary:     Verifies the content of the ramdisk node in the FIT Image Tree Source (its)
+                     The FIT settings are set by the test case.
+        Expected:    1. The ITS is generated with bootconfig but without initramfs
+                     2. The ramdisk node is present in the its file with the
+                        expected load and entrypoint
+
+        Product:     oe-core
+        Author:      Francesco Valla <francesco@valla.it>
+        """
+
+        config = """
+KERNEL_IMAGETYPE = "Image"
+
+INITRAMFS_IMAGE = ""
+INITRAMFS_SCRIPTS = ""
+UBOOT_RD_LOADADDRESS = "0x88000000"
+UBOOT_RD_ENTRYPOINT = "0x88000000"
+UBOOT_LOADADDRESS = "0x80080000"
+UBOOT_ENTRYPOINT = "0x80080000"
+BOOTCONFIG_SRC = "bootconfig-test.txt"
+BOOTCONFIG_TASK = "bootconfig-test:do_deploy"
+FIT_INCLUDE_BOOTCONFIG = "1"
 """
         config = self._config_add_kernel_classes(config)
         self.write_config(config)
@@ -1156,6 +1200,7 @@ class FitImagePyTests(KernelFitImageBase):
             'FIT_CONF_PREFIX': "conf-",
             'FIT_DESC': "Kernel fitImage for a dummy distro",
             'FIT_GENERATE_KEYS': "0",
+            'FIT_INCLUDE_BOOTCONFIG': "0",
             'FIT_HASH_ALG': "sha256",
             'FIT_KEY_GENRSA_ARGS': "-F4",
             'FIT_KEY_REQ_ARGS': "-batch -new",
@@ -1173,6 +1218,8 @@ class FitImagePyTests(KernelFitImageBase):
             'UBOOT_LOADADDRESS': "0x20008000",
             'INITRAMFS_IMAGE': "",
             'INITRAMFS_IMAGE_BUNDLE': "",
+            'BOOTCONFIG_SRC': "",
+            'BOOTCONFIG_TASK': "",
             # kernel-uboot.bbclass
             'FIT_KERNEL_COMP_ALG': "gzip",
             'FIT_KERNEL_COMP_ALG_EXTENSION': ".gz",

-- 
2.53.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH RFC 1/4] bootconfig: add recipe
  2026-03-18 23:30 ` [PATCH RFC 1/4] bootconfig: add recipe Francesco Valla
@ 2026-03-19  8:54   ` Freihofer, Adrian
  2026-03-20 13:27     ` Francesco Valla
  0 siblings, 1 reply; 7+ messages in thread
From: Freihofer, Adrian @ 2026-03-19  8:54 UTC (permalink / raw)
  To: Francesco Valla, openembedded-core@lists.openembedded.org
  Cc: Francesco Castagnotto

Hi Franceso

Thank you for the patches.

On Thu, 2026-03-19 at 00:30 +0100, Francesco Valla wrote:
> Add a new recipe for the bootconfig tool, with source coming directly
> from the kernel shared workdir.
> 
> Signed-off-by: Francesco Valla <francesco@valla.it>
> ---
>  meta/recipes-kernel/bootconfig/bootconfig.bb | 44
> ++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/meta/recipes-kernel/bootconfig/bootconfig.bb
> b/meta/recipes-kernel/bootconfig/bootconfig.bb
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..77ee70dd1839ef90a292cf829f4
> f3a4353f85c28
> --- /dev/null
> +++ b/meta/recipes-kernel/bootconfig/bootconfig.bb
> @@ -0,0 +1,44 @@
> +SUMMARY = "Apply, delete or show boot config"
> +DESCRIPTION = "bootconfig is a tool that can be used to add a boot
> config block \
> +at the end of a kernel initramfs, as well as remove it or show its
> content."
> +LICENSE = "GPL-2.0-only"
> +
> +inherit kernelsrc kernel-arch
> +
> +do_populate_lic[depends] += "virtual/kernel:do_shared_workdir"
> +do_configure[depends] += "virtual/kernel:do_shared_workdir"
> +
> +EXTRA_OEMAKE = "\
> +    -C ${S}/tools/bootconfig \
> +    O=${B} \
> +    CROSS=${TARGET_PREFIX} \
> +    CC="${CC} ${DEBUG_PREFIX_MAP} -ffile-prefix-
> map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH} ${CFLAGS}" \
> +    HOSTCC="${BUILD_CC} ${BUILD_CFLAGS}" \
> +    LD="${LD}" \
> +    AR=${AR} \
> +    ARCH=${ARCH} \
> +    V=1 \
> +    'DESTDIR=${D}' \
> +    'prefix=${prefix}' \
> +    'bindir=${bindir}' \
> +"
> +
> +do_compile() {
> +	oe_runmake ${B}/bootconfig
> +}
> +
> +do_install() {
> +	install -d ${D}${bindir}
> +	oe_runmake install
> +}
> +
> +
> +PACKAGE_ARCH = "${MACHINE_ARCH}"

This is not understandable to me. From the description I would assume 
this tool runs on the host machine.

> +
> +python do_package:prepend() {
> +    d.setVar('PKGV', d.getVar("KERNEL_VERSION").split("-")[0])
> +}
> +
> +B = "${WORKDIR}/${BPN}-${PV}"
> +
> +BBCLASSEXTEND = "native nativesdk"

If the tool runs on the host machine, should this not be a pure -native
recipe without this line e.g. named bootconfig-native.bb

Is bootconfig a good name for a recipe? Or should it be e.g. linux-
bootconfig-native.bb?


Side note: We need to be careful not to create a dependency of the
initramfs on the kernel build directory. Such a dependency would
essentially invalidate the sstate-cache for the kernel, which we want
to avoid.

Regards,
Adrian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH RFC 1/4] bootconfig: add recipe
  2026-03-19  8:54   ` Freihofer, Adrian
@ 2026-03-20 13:27     ` Francesco Valla
  0 siblings, 0 replies; 7+ messages in thread
From: Francesco Valla @ 2026-03-20 13:27 UTC (permalink / raw)
  To: Freihofer, Adrian
  Cc: openembedded-core@lists.openembedded.org, Francesco Castagnotto

Hi Adrian,

On Thu, Mar 19, 2026 at 08:54:35AM +0000, Freihofer, Adrian wrote:
> Hi Franceso
> 
> Thank you for the patches.
> 
> On Thu, 2026-03-19 at 00:30 +0100, Francesco Valla wrote:
> > Add a new recipe for the bootconfig tool, with source coming directly
> > from the kernel shared workdir.
> > 
> > Signed-off-by: Francesco Valla <francesco@valla.it>
> > ---
> > �meta/recipes-kernel/bootconfig/bootconfig.bb | 44
> > ++++++++++++++++++++++++++++
> > �1 file changed, 44 insertions(+)
> > 
> > diff --git a/meta/recipes-kernel/bootconfig/bootconfig.bb
> > b/meta/recipes-kernel/bootconfig/bootconfig.bb
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..77ee70dd1839ef90a292cf829f4
> > f3a4353f85c28
> > --- /dev/null
> > +++ b/meta/recipes-kernel/bootconfig/bootconfig.bb
> > @@ -0,0 +1,44 @@
> > +SUMMARY = "Apply, delete or show boot config"
> > +DESCRIPTION = "bootconfig is a tool that can be used to add a boot
> > config block \
> > +at the end of a kernel initramfs, as well as remove it or show its
> > content."
> > +LICENSE = "GPL-2.0-only"
> > +
> > +inherit kernelsrc kernel-arch
> > +
> > +do_populate_lic[depends] += "virtual/kernel:do_shared_workdir"
> > +do_configure[depends] += "virtual/kernel:do_shared_workdir"
> > +
> > +EXTRA_OEMAKE = "\
> > +��� -C ${S}/tools/bootconfig \
> > +��� O=${B} \
> > +��� CROSS=${TARGET_PREFIX} \
> > +��� CC="${CC} ${DEBUG_PREFIX_MAP} -ffile-prefix-
> > map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH} ${CFLAGS}" \
> > +��� HOSTCC="${BUILD_CC} ${BUILD_CFLAGS}" \
> > +��� LD="${LD}" \
> > +��� AR=${AR} \
> > +��� ARCH=${ARCH} \
> > +��� V=1 \
> > +��� 'DESTDIR=${D}' \
> > +��� 'prefix=${prefix}' \
> > +��� 'bindir=${bindir}' \
> > +"
> > +
> > +do_compile() {
> > +	oe_runmake ${B}/bootconfig
> > +}
> > +
> > +do_install() {
> > +	install -d ${D}${bindir}
> > +	oe_runmake install
> > +}
> > +
> > +
> > +PACKAGE_ARCH = "${MACHINE_ARCH}"
> 
> This is not understandable to me. From the description I would assume 
> this tool runs on the host machine.
> 

I probably overthought the usecases here, with bootconfig being used on
the target for on-the-fly bootconfig modification. But this wouldn't
work with a FIT image obviously.

> > +
> > +python do_package:prepend() {
> > +��� d.setVar('PKGV', d.getVar("KERNEL_VERSION").split("-")[0])
> > +}
> > +
> > +B = "${WORKDIR}/${BPN}-${PV}"
> > +
> > +BBCLASSEXTEND = "native nativesdk"
> 
> If the tool runs on the host machine, should this not be a pure -native
> recipe without this line e.g. named bootconfig-native.bb
> 
> Is bootconfig a good name for a recipe? Or should it be e.g. linux-
> bootconfig-native.bb?
> 

linux-bootconfig is a good name, I'll go with it in the next revision.

> 
> Side note: We need to be careful not to create a dependency of the
> initramfs on the kernel build directory. Such a dependency would
> essentially invalidate the sstate-cache for the kernel, which we want
> to avoid.

Agreed, one of the unpoken reasons for the RFC label is that the
reasoning about dependencies has not been completed yes. I'm still
facing challenges e.g. for FIT vs WIC cross-dependencies when a
dm-veriry rootfs is used and its parameters are inserted into the FIT
image that lives in the boot partition.
But I wanted to gather a first round of impressions with a (working)
first version while working on it.

> 
> Regards,
> Adrian

Thank you!

Reagrds,
Francesco



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-20 13:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-18 23:30 [PATCH RFC 0/4] Add support for bootconfig on initramfs and FIT images Francesco Valla
2026-03-18 23:30 ` [PATCH RFC 1/4] bootconfig: add recipe Francesco Valla
2026-03-19  8:54   ` Freihofer, Adrian
2026-03-20 13:27     ` Francesco Valla
2026-03-18 23:30 ` [PATCH RFC 2/4] image_types: add bootconfig conversion type Francesco Valla
2026-03-18 23:30 ` [PATCH RFC 3/4] recipes-test: add bootconfig-test recipe Francesco Valla
2026-03-18 23:30 ` [PATCH RFC 4/4] kernel-fit-image: add bootconfig support Francesco Valla

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox