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")
