From: "'Felix Moessbauer' via isar-users" <isar-users@googlegroups.com>
To: isar-users@googlegroups.com
Cc: quirin.gylstorff@siemens.com, jan.kiszka@siemens.com,
Felix Moessbauer <felix.moessbauer@siemens.com>
Subject: [PATCH 7/8] dracut: add support for cross initrd generation
Date: Tue, 15 Sep 2026 12:01:24 +0200 [thread overview]
Message-ID: <20260915100125.1991311-8-felix.moessbauer@siemens.com> (raw)
In-Reply-To: <20260915100125.1991311-1-felix.moessbauer@siemens.com>
For cross-initrd generation, a cross variant of the ldd tool needs to
be provided. As there is no such tool, but this is THE performance
critical part (it needs to scan each binary and all transitive dependencies),
we provide a custom one which uses readelf to determine the shared library
dependencies.
Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
meta/classes-recipe/host-tooling.bbclass | 4 +-
meta/classes-recipe/initrd-dracut.bbclass | 36 +++++++++-
meta/classes-recipe/rootfs.bbclass | 4 +-
.../dracut-cross-ldd/dracut-cross-ldd.bb | 16 +++++
.../dracut-cross-ldd/files/dracut-cross-ldd | 65 +++++++++++++++++++
5 files changed, 121 insertions(+), 4 deletions(-)
create mode 100644 meta/recipes-devtools/dracut-cross-ldd/dracut-cross-ldd.bb
create mode 100644 meta/recipes-devtools/dracut-cross-ldd/files/dracut-cross-ldd
diff --git a/meta/classes-recipe/host-tooling.bbclass b/meta/classes-recipe/host-tooling.bbclass
index b76f8898..5e81dfda 100644
--- a/meta/classes-recipe/host-tooling.bbclass
+++ b/meta/classes-recipe/host-tooling.bbclass
@@ -5,8 +5,8 @@
LICENSE = "gpl-2.0"
LIC_FILES_CHKSUM = "file://${LAYERDIR_core}/licenses/COPYING.GPLv2;md5=751419260aa954499f7abaabaa882bbe"
-HOST_TOOLING_PACKAGES ?= ""
-HOST_TOOLING_DEPENDS ?= ""
+HOST_TOOLING_PACKAGES ?= "dracut-core binutils zstd dracut-cross-ldd"
+HOST_TOOLING_DEPENDS ?= "dracut-cross-ldd"
# dependency to build the host-tooling-chroot
HOST_TOOLING_DEP ?= "host-tooling-chroot:do_build"
diff --git a/meta/classes-recipe/initrd-dracut.bbclass b/meta/classes-recipe/initrd-dracut.bbclass
index 00999b91..ffc71db6 100644
--- a/meta/classes-recipe/initrd-dracut.bbclass
+++ b/meta/classes-recipe/initrd-dracut.bbclass
@@ -56,8 +56,42 @@ def extend_dracut_cmdline(d):
ROOTFS_INITRAMFS_GENERATOR_CMDLINE = "dracut --force --kver $kernel_version -L 5 --reproducible"
ROOTFS_INITRAMFS_GENERATOR_CMDLINE:append = " ${@ extend_dracut_cmdline(d)}"
+# Cross-assemble the initramfs, requires preparation of dracut module definitions
+def dracut_cross_default(d):
+ return bb.utils.to_boolean(d.getVar('ISAR_CROSS_COMPILE')) \
+ and bb.utils.to_boolean(d.getVar('ROOTFS_USE_DRACUT')) \
+ and d.getVar('ROOTFS_ARCH') != d.getVar('HOST_ARCH')
+
+ROOTFS_DRACUT_CROSS ??= "${@ '1' if dracut_cross_default(d) else '0' }"
+ROOTFS_DRACUT_CROSS:bookworm = "0"
+OVERRIDES:append = "${@':dracut-cross' if bb.utils.to_boolean(d.getVar('ROOTFS_DRACUT_CROSS')) else ''}"
+
+ROOTFS_INSTALL_DEPENDS:append:dracut-cross = " ${HOST_TOOLING_DEP}"
+ROOTFS_INITRAMFS_GENERATOR_CMDLINE:append:dracut-cross = " --sysroot /mnt/rootfs"
+DRACUT_MOUNTS = ""
+DRACUT_MOUNTS:append:dracut-cross = " ${ROOTFSDIR}:/mnt/rootfs"
+DRACUT_ROOTFS = "${ROOTFSDIR}"
+DRACUT_ROOTFS:dracut-cross = "${WORKDIR}/host-tooling"
+DRACUT_ENV = "DRACUT_ARCH=${QEMU_ARCH}"
+DRACUT_ENV:append:dracut-cross = " \
+ DRACUT_INSTALL=/usr/lib/dracut/dracut-install \
+ DRACUT_LDD=/usr/libexec/dracut-cross-ldd \
+"
+
run_initrd_generator() {
mods_total="$(find ${ROOTFSDIR}/usr/lib/dracut/modules.d/ -maxdepth 1 -type d | wc -l)"
echo "Total number of modules: $mods_total (dracut)"
- run_in_chroot "${ROOTFSDIR}" sh -c "${ROOTFS_INITRAMFS_GENERATOR_CMDLINE}"
+ if [ "${ROOTFS_DRACUT_CROSS}" = "1" ]; then
+ mkdir -p ${DRACUT_ROOTFS}
+ run_privileged tar -xf ${HOST_TOOLING_CHROOT} -C ${DRACUT_ROOTFS}
+ trap 'run_privileged rm -rf ${DRACUT_ROOTFS}' EXIT
+ fi
+ ${@ insert_isar_umounts(d, d.getVar('DRACUT_ROOTFS'), d.getVar('DRACUT_MOUNTS')) }
+ run_privileged_heredoc <<'EOF'
+ ${@ insert_isar_mounts(d, d.getVar('DRACUT_ROOTFS'), d.getVar('DRACUT_MOUNTS')) }
+ export ${DRACUT_ENV}
+ chroot ${DRACUT_ROOTFS} ${ROOTFS_INITRAMFS_GENERATOR_CMDLINE}
+EOF
}
+
+inherit_defer ${@'host-tooling' if bb.utils.to_boolean(d.getVar('ROOTFS_DRACUT_CROSS')) else ''}
diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass
index 1de27d7b..cea85626 100644
--- a/meta/classes-recipe/rootfs.bbclass
+++ b/meta/classes-recipe/rootfs.bbclass
@@ -452,6 +452,8 @@ rootfs_capture_apt_state() {
var/lib/dpkg/status
}
+ROOTFS_INSTALL_DEPENDS ?= ""
+
do_rootfs_install[root_cleandirs] = "${ROOTFSDIR}"
do_rootfs_install[cleandirs] += "${DEPLOYDIR}"
do_rootfs_install[sstate-inputdirs] = "${DEPLOYDIR}"
@@ -459,7 +461,7 @@ do_rootfs_install[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
do_rootfs_install[vardeps] += "${ROOTFS_CONFIGURE_COMMAND} ${ROOTFS_INSTALL_COMMAND} ${ROOTFS_POSTPROCESS_COMMAND} ${ROOTFS_VARDEPS}"
do_rootfs_install[vardepsexclude] += "IMAGE_ROOTFS"
do_rootfs_install[depends] = "bootstrap-${@'target' if d.getVar('ROOTFS_ARCH') == d.getVar('DISTRO_ARCH') else 'host'}:do_build"
-do_rootfs_install[depends] += "base-apt:do_cache isar-apt:do_cache_config"
+do_rootfs_install[depends] += "base-apt:do_cache isar-apt:do_cache_config ${ROOTFS_INSTALL_DEPENDS}"
do_rootfs_install[deptask] = "do_deploy_deb"
do_rootfs_install[rdeptask] = "do_deploy_deb"
do_rootfs_install[network] = "${TASK_USE_SUDO}"
diff --git a/meta/recipes-devtools/dracut-cross-ldd/dracut-cross-ldd.bb b/meta/recipes-devtools/dracut-cross-ldd/dracut-cross-ldd.bb
new file mode 100644
index 00000000..327a5c82
--- /dev/null
+++ b/meta/recipes-devtools/dracut-cross-ldd/dracut-cross-ldd.bb
@@ -0,0 +1,16 @@
+# This software is a part of Isar.
+# Copyright (C) 2026 Siemens AG
+
+inherit dpkg-raw
+
+MAINTAINER = "isar-users <isar-users@googlegroups.com>"
+DESCRIPTION = "Minimal ldd replacement for dracut cross builds"
+
+SRC_URI = "file://${BPN}"
+
+DEBIAN_DEPENDS .= ",python3, binutils"
+
+do_install[cleandirs] += "${D}/usr/libexec"
+do_install() {
+ install -v -m 755 "${WORKDIR}/${BPN}" "${D}/usr/libexec/${BPN}"
+}
diff --git a/meta/recipes-devtools/dracut-cross-ldd/files/dracut-cross-ldd b/meta/recipes-devtools/dracut-cross-ldd/files/dracut-cross-ldd
new file mode 100644
index 00000000..ef60b3fa
--- /dev/null
+++ b/meta/recipes-devtools/dracut-cross-ldd/files/dracut-cross-ldd
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# This software is a part of Isar.
+# Copyright (C) 2026 Siemens AG
+import re
+import subprocess
+import sys
+from pathlib import Path
+
+# glob patterns relative to the sysroot, including multiarch directories
+LIB_DIRS = ["lib", "lib/*", "usr/lib", "usr/lib/*"]
+
+
+def find_sysroot(binary):
+ for parent in binary.parents:
+ if (parent / "usr/lib").is_dir():
+ return parent
+ return Path("/")
+
+
+def find_library(name, search_dirs, sysroot):
+ for directory in search_dirs:
+ for path in sysroot.glob(f"{directory.strip('/')}/{name}"):
+ return "/" + str(path.relative_to(sysroot))
+ return None
+
+
+def read_dynamic_section(path):
+ return subprocess.check_output(["readelf", "-d", path], text=True)
+
+
+def get_needed(dynamic):
+ runpaths = re.findall(r'\((?:RUNPATH|RPATH)\).*?\[(.*?)\]', dynamic)
+ search_dirs = [d for paths in runpaths for d in paths.split(":")]
+ needed = re.findall(r'\(NEEDED\).*?\[(.*?)\]', dynamic)
+ return search_dirs + LIB_DIRS, needed
+
+
+binary = Path(sys.argv[-1]).absolute()
+try:
+ dynamic = read_dynamic_section(binary)
+except subprocess.SubprocessError:
+ sys.exit(1)
+
+sysroot = find_sysroot(binary)
+resolved = {}
+pending = [get_needed(dynamic)]
+
+# ldd reports the whole dependency tree, so resolve it transitively
+while pending:
+ search_dirs, needed = pending.pop()
+ for library in needed:
+ if library in resolved:
+ continue
+ path = find_library(library, search_dirs, sysroot)
+ resolved[library] = path
+ if path:
+ try:
+ pending.append(get_needed(
+ read_dynamic_section(sysroot / path.strip("/"))))
+ except subprocess.SubprocessError:
+ pass
+
+for library, path in resolved.items():
+ print(f"\t{library} => {path} (0x0000000000000000)" if path
+ else f"\t{library} => not found")
--
2.55.0
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/isar-users/20260915100125.1991311-8-felix.moessbauer%40siemens.com.
next prev parent reply other threads:[~2026-09-15 10:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 10:01 [PATCH 0/8] Add support to cross-compile a dracut initramfs 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 1/8] rootfs: generalize deployment of rootfs artifact 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 2/8] dracut-module: make module-setup compatible with sysroot 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 3/8] initramfs: move dracut logic to initrd-dracut class 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 4/8] dracut: use fixed log level on generation for progress reporting 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 5/8] dracut: enforce build of reproducible initrd 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` [PATCH 6/8] add host-tooling chroot for generic host tooling 'Felix Moessbauer' via isar-users
2026-09-15 10:01 ` 'Felix Moessbauer' via isar-users [this message]
2026-09-15 10:01 ` [PATCH 8/8] rootfs: stub both dracut and update-initramfs on dracut 'Felix Moessbauer' via isar-users
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260915100125.1991311-8-felix.moessbauer@siemens.com \
--to=isar-users@googlegroups.com \
--cc=felix.moessbauer@siemens.com \
--cc=jan.kiszka@siemens.com \
--cc=quirin.gylstorff@siemens.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox