diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index ff3cd737..8523a662 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -67,6 +67,8 @@ inherit essential
 
 ROOTFSDIR = "${IMAGE_ROOTFS}"
 ROOTFS_FEATURES += "clean-package-cache clean-pycache generate-manifest export-dpkg-status clean-log-files clean-debconf-cache"
+# when using a custom initrd, do not generate one as part of the image rootfs
+ROOTFS_FEATURES += "${@ '' if d.getVar('INITRD_IMAGE') == '' else 'no-generate-initrd'}"
 ROOTFS_PACKAGES += "${IMAGE_PREINSTALL} ${@isar_multiarch_packages('IMAGE_INSTALL', d)}"
 ROOTFS_MANIFEST_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
 ROOTFS_DPKGSTATUS_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
@@ -341,17 +343,6 @@ do_copy_boot_files() {
         sudo cat "$kernel" > "${DEPLOYDIR}/${KERNEL_IMAGE}"
     fi
 
-    if [ -z "${INITRD_IMAGE}" ]; then
-        # deploy default initrd if no custom one is build
-        initrd="$(realpath -q '${IMAGE_ROOTFS}/initrd.img')"
-        if [ ! -f "$initrd" ]; then
-            initrd="$(realpath -q '${IMAGE_ROOTFS}/boot/initrd.img')"
-        fi
-        if [ -f "$initrd" ]; then
-            cp -f "$initrd" '${DEPLOYDIR}/${INITRD_DEPLOY_FILE}'
-        fi
-    fi
-
     for file in ${DTB_FILES}; do
         dtb="$(find '${IMAGE_ROOTFS}/usr/lib' -type f \
                     -iwholename '*linux-image-*/'${file} | head -1)"
@@ -450,7 +441,7 @@ EOSUDO
         -exec touch '{}' -h -d@${SOURCE_DATE_EPOCH} ';'
 }
 do_rootfs_finalize[network] = "${TASK_USE_SUDO}"
-addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess
+addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess do_generate_initramfs
 
 ROOTFS_QA_FIND_ARGS ?= ""
 
@@ -461,6 +452,8 @@ do_rootfs_quality_check() {
     args="${ROOTFS_QA_FIND_ARGS}"
     # rootfs_finalize chroot-setup.sh
     args="${args} ! -path ${ROOTFSDIR}/var/lib/dpkg/diversions"
+    # initramfs is generated outside of the image rootfs
+    args="${args} ! -path ${ROOTFSDIR}/boot/initrd.img*"
     for cmd in ${ROOTFS_POSTPROCESS_COMMAND}; do
         case "${cmd}" in
 	    image_postprocess_mark)
diff --git a/meta/classes/initramfs.bbclass b/meta/classes/initramfs.bbclass
index 0197a60b..3a996f78 100644
--- a/meta/classes/initramfs.bbclass
+++ b/meta/classes/initramfs.bbclass
@@ -6,14 +6,11 @@ DEPLOYDIR = "${WORKDIR}/deploy"
 STAMP = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/${PV}-${PR}"
 STAMPCLEAN = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/*-*"
 
-# Sstate also needs to be machine-specific
-SSTATE_MANIFESTS = "${TMPDIR}/sstate-control/${MACHINE}-${DISTRO}-${DISTRO_ARCH}"
-SSTATETASKS += "do_generate_initramfs"
-
 INITRAMFS_INSTALL ?= ""
 INITRAMFS_PREINSTALL ?= ""
 INITRAMFS_ROOTFS ?= "${WORKDIR}/rootfs"
 INITRAMFS_IMAGE_NAME = "${INITRAMFS_FULLNAME}.initrd.img"
+INITRD_DEPLOY_FILE = "${INITRAMFS_IMAGE_NAME}"
 
 # Install proper kernel
 INITRAMFS_INSTALL += "${@ ("linux-image-" + d.getVar("KERNEL_NAME")) if d.getVar("KERNEL_NAME") else ""}"
@@ -28,37 +25,3 @@ ROOTFS_FEATURES = ""
 ROOTFS_PACKAGES = "initramfs-tools ${INITRAMFS_PREINSTALL} ${INITRAMFS_INSTALL}"
 
 inherit rootfs
-
-do_generate_initramfs[network] = "${TASK_USE_SUDO}"
-do_generate_initramfs[cleandirs] += "${DEPLOYDIR}"
-do_generate_initramfs[sstate-inputdirs] = "${DEPLOYDIR}"
-do_generate_initramfs[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
-do_generate_initramfs() {
-    rootfs_do_mounts
-
-    trap 'exit 1' INT HUP QUIT TERM ALRM USR1
-    trap 'rootfs_do_umounts' EXIT
-
-    rootfs_do_qemu
-
-    sudo -E chroot "${INITRAMFS_ROOTFS}" sh -c '\
-        export kernel_version=$(basename /boot/vmlinu[xz]* | cut -d'-' -f2-); \
-        if [ -n "$kernel_version" ]; then \
-          update-initramfs -u -v -k "$kernel_version"; \
-        else \
-          update-initramfs -u -v ;  \
-        fi'
-
-    rootfs_do_umounts
-
-    if [ ! -e "${INITRAMFS_ROOTFS}/initrd.img" ]; then
-        bberror "No initramfs was found after generation!"
-    fi
-    cp ${INITRAMFS_ROOTFS}/initrd.img ${DEPLOYDIR}/${INITRAMFS_IMAGE_NAME}
-}
-addtask generate_initramfs after do_rootfs before do_build
-
-python do_generate_initramfs_setscene () {
-    sstate_setscene(d)
-}
-addtask do_generate_initramfs_setscene
diff --git a/meta/classes/rootfs.bbclass b/meta/classes/rootfs.bbclass
index 446d92d6..8ab44472 100644
--- a/meta/classes/rootfs.bbclass
+++ b/meta/classes/rootfs.bbclass
@@ -14,6 +14,7 @@ ROOTFS_BASE_DISTRO ?= "${BASE_DISTRO}"
 # 'generate-manifest' - generate a package manifest of the rootfs into ${ROOTFS_MANIFEST_DEPLOY_DIR}
 # 'export-dpkg-status' - exports /var/lib/dpkg/status file to ${ROOTFS_DPKGSTATUS_DEPLOY_DIR}
 # 'clean-log-files' - delete log files that are not owned by packages
+# 'no-generate-initrd' - do not generate debian default initrd
 ROOTFS_FEATURES ?= ""
 
 ROOTFS_APT_ARGS="install --yes -o Debug::pkgProblemResolver=yes"
@@ -165,6 +166,15 @@ rootfs_configure_apt() {
 EOSUDO
 }
 
+ROOTFS_CONFIGURE_COMMAND += "rootfs_disable_initrd_generation"
+rootfs_disable_initrd_generation[weight] = "1"
+rootfs_disable_initrd_generation() {
+    # fully disable initrd generation
+    echo "replace update-initramfs with stub"
+    sudo mv "${ROOTFSDIR}/usr/sbin/update-initramfs" \
+            "${ROOTFSDIR}/usr/sbin/update-initramfs.isar"
+    sudo chroot "${ROOTFSDIR}" ln -s "/usr/bin/true" "/usr/sbin/update-initramfs"
+}
 
 ROOTFS_INSTALL_COMMAND += "rootfs_install_pkgs_update"
 rootfs_install_pkgs_update[weight] = "5"
@@ -395,6 +405,15 @@ rootfs_cleanup_base_apt() {
 EOSUDO
 }
 
+ROOTFS_POSTPROCESS_COMMAND += "rootfs_restore_initrd_tooling"
+rootfs_restore_initrd_tooling[weight] = "1"
+rootfs_restore_initrd_tooling() {
+    if [ -e "${ROOTFSDIR}/usr/sbin/update-initramfs.isar" ]; then
+        sudo mv -f "${ROOTFSDIR}/usr/sbin/update-initramfs.isar" \
+            "${ROOTFSDIR}/usr/sbin/update-initramfs"
+    fi
+}
+
 do_rootfs_postprocess[vardeps] = "${ROOTFS_POSTPROCESS_COMMAND}"
 do_rootfs_postprocess[network] = "${TASK_USE_SUDO}"
 python do_rootfs_postprocess() {
@@ -421,6 +440,51 @@ python do_rootfs_postprocess() {
 }
 addtask rootfs_postprocess before do_rootfs after do_unpack
 
+ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'no-generate-initrd', 'rootfs_clear_initrd', '', d)}"
+rootfs_clear_initrd() {
+    sudo rm -f ${ROOTFSDIR}/initrd.img
+    sudo rm -f ${ROOTFSDIR}/initrd.img.old
+}
+
+SSTATETASKS += "do_generate_initramfs"
+do_generate_initramfs[network] = "${TASK_USE_SUDO}"
+do_generate_initramfs[cleandirs] += "${DEPLOYDIR}"
+do_generate_initramfs[sstate-inputdirs] = "${DEPLOYDIR}"
+do_generate_initramfs[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
+python do_generate_initramfs() {
+    bb.build.exec_func('rootfs_do_mounts', d)
+    bb.build.exec_func('rootfs_do_qemu', d)
+    try:
+        bb.build.exec_func('rootfs_generate_initramfs', d)
+    finally:
+        bb.build.exec_func('rootfs_do_umounts', d)
+}
+
+python do_generate_initramfs_setscene () {
+    sstate_setscene(d)
+}
+
+rootfs_generate_initramfs[progress] = "custom:rootfs_progress.InitrdProgressHandler"
+rootfs_generate_initramfs() {
+    if [ -n "$(sudo find '${ROOTFSDIR}/boot' -type f -name 'vmlinu[xz]*')" ]; then
+        sudo -E chroot "${ROOTFSDIR}" sh -c '\
+            export kernel_version=$(basename /boot/vmlinu[xz]* | cut -d'-' -f2-); \
+            echo "Generating initrd"; \
+            update-initramfs -u -v -k "$kernel_version";'
+        if [ -n "${INITRD_DEPLOY_FILE}" ]; then
+            cp ${ROOTFSDIR}/initrd.img ${DEPLOYDIR}/${INITRD_DEPLOY_FILE}
+        fi
+    else
+        echo "no kernel in this rootfs, do not generate initrd"
+    fi
+}
+
+python() {
+    if 'no-generate-initrd' not in d.getVar('ROOTFS_FEATURES', True).split():
+        bb.build.addtask('do_generate_initramfs', 'do_rootfs', 'do_rootfs_postprocess', d)
+        bb.build.addtask('do_generate_initramfs_setscene', None, None, d)
+}
+
 python do_rootfs() {
     """Virtual task"""
     pass
diff --git a/meta/recipes-core/isar-bootstrap/isar-bootstrap.inc b/meta/recipes-core/isar-bootstrap/isar-bootstrap.inc
index 7fd67f8b..e4a3813c 100644
--- a/meta/recipes-core/isar-bootstrap/isar-bootstrap.inc
+++ b/meta/recipes-core/isar-bootstrap/isar-bootstrap.inc
@@ -16,6 +16,8 @@ ROOTFSDIR = "${WORKDIR}/rootfs"
 DISTRO_BOOTSTRAP_BASE_PACKAGES += "locales"
 DISTRO_BOOTSTRAP_BASE_PACKAGES:append:gnupg = " gnupg"
 DISTRO_BOOTSTRAP_BASE_PACKAGES:append:https-support = " ca-certificates"
+# install early, so we can stub the update-initramfs script before rootfs install
+DISTRO_BOOTSTRAP_BASE_PACKAGES += "initramfs-tools"
 
 inherit deb-dl-dir
 
diff --git a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
index 2c07d098..ea3755f6 100644
--- a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
+++ b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
@@ -13,6 +13,8 @@ FILESEXTRAPATHS:append = ":${LAYERDIR_core}/recipes-core/isar-bootstrap/files"
 
 DISTRO_BOOTSTRAP_BASE_PACKAGES += "locales apt"
 DISTRO_BOOTSTRAP_BASE_PACKAGES:append:https-support = " ca-certificates"
+# install early, so we can stub the update-initramfs script before rootfs install
+DISTRO_BOOTSTRAP_BASE_PACKAGES += "initramfs-tools"
 
 BOOTSTRAP_TMPDIR = "${WORKDIR}/tempdir"
 
diff --git a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
index 6478d3a6..98e427e5 100644
--- a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
+++ b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
@@ -55,6 +55,7 @@ SBUILD_CHROOT_PREINSTALL_COMMON = " \
 SBUILD_CHROOT_DIR = "${WORKDIR}/rootfs"
 ROOTFSDIR = "${SBUILD_CHROOT_DIR}"
 ROOTFS_PACKAGES = "${SBUILD_CHROOT_PREINSTALL}"
+ROOTFS_FEATURES += "no-generate-initrd"
 
 ROOTFS_POSTPROCESS_COMMAND:remove = "rootfs_cleanup_isar_apt"
 
