From efc97f6566abe86e604aeac57bebf4b4839603c4 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 4 Feb 2026 18:37:20 +0000 Subject: [PATCH] initramfs: Build initramfs capable of booting DDI images --- board/common/dracut.conf | 102 +++++++ .../initramfs/01infix-lib64/module-setup.sh | 15 + board/common/initramfs/10infix-init/init | 279 ++++++++++++++++++ .../initramfs/10infix-init/module-setup.sh | 21 ++ board/x86_64/rootfs/etc/ddi-partition-types | 3 + configs/x86_64_minimal_defconfig | 12 +- 6 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 board/common/dracut.conf create mode 100755 board/common/initramfs/01infix-lib64/module-setup.sh create mode 100755 board/common/initramfs/10infix-init/init create mode 100755 board/common/initramfs/10infix-init/module-setup.sh create mode 100644 board/x86_64/rootfs/etc/ddi-partition-types diff --git a/board/common/dracut.conf b/board/common/dracut.conf new file mode 100644 index 00000000..d0651a00 --- /dev/null +++ b/board/common/dracut.conf @@ -0,0 +1,102 @@ +#Simple dracut config for a system without systemd + +#Dracut configuration + +show_modules=yes +i18n_install_all=no +lvmconf=no +mdadmconf=no +early_microcode=no +hostonly=no +hostonly_cmdline=no +use_fstab=no +kernel_cmdline="rd.break=initqueue" +do_strip=no + +# Dracut modules needed +add_dracutmodules+=" \ +busybox \ +" + +# Modules to ignore +omit_dracutmodules+=" \ +base \ +bash \ +biosdevname \ +btrfs \ +bluetooth \ +caps \ +cifs \ +connman \ +crypt \ +crypt-gpg \ +dash \ +dbus-broker \ +dbus-daemon \ +dm \ +dmraid \ +dmsquash-live-ntfs \ +dracut-systemd \ +fcoe \ +fcoe-uefi \ +fs-lib \ +iscsi \ +i18n \ +kernel-modules \ +kernel-modules-extra \ +lvmmerge \ +lvm \ +lunmask \ +mdraid \ +memstrack \ +mksh \ +modsign \ +mount-root \ +multipath \ +nbd \ +network-legacy \ +network-wicked \ +nfs \ +nvdimm \ +nvmf \ +parse-lunmask \ +pcsc \ +qemu \ +qemu-net \ +resume \ +rootfs-block \ +rngd \ +shutdown \ +systemd \ +systemd-udevd \ +systemd-coredump \ +systemd-ask-password \ +systemd-timedated \ +systemd-rfkill \ +systemd-resolved \ +systemd-hostnamed \ +systemd-initrd \ +systemd-integritysetup \ +systemd-journald \ +systemd-ldconfig \ +systemd-networkd \ +systemd-timesyncd \ +systemd-veritysetup \ +systemd-modules-load \ +systemd-pcrphase \ +systemd-portabled \ +systemd-pstore \ +systemd-sysctl \ +systemd-repart \ +systemd-sysext \ +systemd-sysusers \ +systemd-tmpfiles \ +squash \ +ssh-client \ +stratis \ +tpm2-tss \ +udev-rules \ +url-lib \ +usrmount \ +virtiofs \ +" diff --git a/board/common/initramfs/01infix-lib64/module-setup.sh b/board/common/initramfs/01infix-lib64/module-setup.sh new file mode 100755 index 00000000..790e9d6b --- /dev/null +++ b/board/common/initramfs/01infix-lib64/module-setup.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +check() { + return 0 +} + +depends() { + return 0 +} + +install() { + # Not sure if this should be handled by buildroot's merged-usr + # module. Fix it here for now. + ln -s "lib" "${initdir?}/lib64" +} diff --git a/board/common/initramfs/10infix-init/init b/board/common/initramfs/10infix-init/init new file mode 100755 index 00000000..534a5ca4 --- /dev/null +++ b/board/common/initramfs/10infix-init/init @@ -0,0 +1,279 @@ +#!/bin/sh + +echo -ne "\e[31m●\e[0m \e[33m●\e[0m \e[32m●\e[0m Infix Initramfs — " >/dev/console +source /etc/os-release >/dev/console +echo "$VERSION" + +set -e + +getkopt() +{ + grep -q -E "(^| )$1( |$)" /proc/cmdline +} + +getkparam() +{ + sed -n "s/.*\<$1=\([^ ]*\).*/\1/p" /proc/cmdline +} + +debug_shell() +{ + [ "$(getkparam rd.shell)" = "$1" ] || return 0 + + exec /dev/console + echo "Starting debug shell at $1" + exec sh -i +} + +die() +{ + step="${*:-$step}" + + echo -e "\r\e[0K[\e[31mFAIL\e[0m] $step" >/dev/console + echo "<0>ix-initramfs: ERROR: $step" >/dev/kmsg + debug_shell error + exit 1 +} + +warn() +{ + step="${*:-$step}" + + echo -e "\r\e[0K[\e[33mWARN\e[0m] $step" >/dev/console + echo "<5>ix-initramfs: WARNING: $step" >/dev/kmsg + debug_shell warning +} + +ok() +{ + step="${*:-$step}" + + echo -e "\r\e[0K[\e[32m OK \e[0m] $step" >/dev/console + echo "<5>ix-initramfs: $step" >/dev/kmsg +} + +begin() +{ + step="$*" + echo -ne "[\e[33m ⋯ \e[0m] $step" >/dev/console +} + +debug() +{ + echo "<7>ix-initramfs: $*" >/dev/kmsg +} + +mountcore() +{ + mount -t proc proc /proc + mount -t sysfs sys /sys + mount -t devtmpfs dev /dev +} + +mountroot() +{ + mkdir /newroot + mount "$1" /newroot || \ + die "Unable to mount rootfs on $1" + + ok "Mounting root filesystem on $(basename $1)" +} + +switchroot() +{ + local innerinit=$(getkparam init) + + ok "Switching to root filesystem" + exec switch_root /newroot ${innerinit:-/sbin/init} +} + +internal_get_part() +{ + local _i _pv + + for _i in $(seq 50); do + _pv=$(lvm pvs --reportformat json \ + | jq -r '.report[].pv[] | select(.vg_name == "internal") | .pv_name') + if [ "$_pv" ]; then + [ $_i -gt 5 ] && ok + echo "$_pv" + return 0 + fi + + [ $_i -eq 5 ] && begin "Waiting for the internal volume to come online" + sleep .2 + done + + warn "Proceeding without the internal volume" + return 0 +} + +internal_inflate() +{ + local _dev _growfs _index _part + + getkopt rd.nointernal && return 0 + + GPT_PART_GROWFS_BIT=59 + + _part=$(internal_get_part) + [ "$_part" ] || return 0 + + _index=$(cat /sys/class/block/$(basename "$_part")/partition) + [ "$_index" ] || return 1 + + _dev=/dev/$(basename $(realpath /sys/class/block/$(basename "$_part")/../)) + [ -b "$_dev" ] || return 1 + + sgdisk "$_dev" -A "$_index":get:$GPT_PART_GROWFS_BIT \ + | grep -q "$_index:$GPT_PART_GROWFS_BIT:1" \ + || return 0 + + begin "Inflating internal VG in $_part" + + # First, expand the GPT to cover the entire disk and expand the + # LVM partition as much as possible. + if ! sgdisk "$_dev" \ + --disk-guid=random \ + --set-alignment=1 \ + --move-second-header \ + --delete="$_index" \ + --largest-new="$_index" --typecode="$_index":8e00 \ + >/tmp/internal-inflate.log 2>&1; then + warn "Failed to inflate GPT on $_dev" + return 0 + fi + + if ! lvm pvresize "$_part" >>/tmp/internal-inflate.log 2>&1; then + warn "Failed to resize PV $_part" + return 0 + fi + + ok "Inflated internal VG in $_part" +} + +addparts() +{ + local _disk="$1" + local _partscan="/sys/class/block/"$(basename "$_disk")/partscan + + [ -f "$_partscan" ] && [ $(cat "$_partscan") -eq 1 ] && return + + kpartx -a "$_disk" 2>/dev/null || die "addparts: Unable to add partitions from $_disk" +} + +gptuuid_probe() +{ + local _uuid=$(echo "$1" | sed -e 's/^GPTUUID=//' | tr ABCDEF abcdef) + local _cand _disk _initrd + + [ -f /initrd.image ] && _initrd=/initrd.image + + for _disk in $_initrd $(find /dev/ -type b); do + _cand=$(ddi "$_disk" inspect uuid | tr ABCDEF abcdef) + [ $? -eq 0 ] || continue + + if [ "$_cand" = "$_uuid" ]; then + ok "Located $_uuid in $_disk" + echo "$_disk" + return + fi + done + + die "gptuuid_probe: Unable to find disk $_uuid" +} + +ddi_probe() +{ + local _disk="$1" + local _dm="$(basename $_disk).root" + local _hash=$(getkparam rd.ddi.roothash) + local _v _trust + + if [ -n "$_hash" ]; then + ok "Trusting pre-authenticated root hash" + _v="-V $_hash" + else + _v="-v" + fi + + _trust=$(ddi "$_disk" part root open $_v "$_dm" 2>&1 \ + || die "ddi_probe: veritysetup of $_disk failed") + + ok "$_trust" + ok "Opened verity protected root from $(basename $_disk)" + echo /dev/mapper/"$_dm" +} + +lvm_probe() +{ + local _vg=$(dirname "$1") _lv=$(basename "$1") + + lvm vgchange -ay "$_vg" &>/dev/null || \ + die "lvm_probe: Failed to activate the $_vg VG" + + [ -b /dev/"$1" ] || die "lvm_probe: Unable to locate the $_lv LV in $_vg" + + echo /dev/"$1" +} + +lo_probe() +{ + local _lo=$(losetup -f || die "probe_lo: found no free loop device for $1") + losetup -P "$_lo" "$1" || die "probe_lo: losetup of $1 to $_lo failed" + + debug "lo_probe: setup $_lo backed by $1" + echo "$_lo" +} + +probe() +{ + local _real _kind + + case "$1" in + /*) + _real=$(realpath "$1") + _kind=$(stat -c %F "$_real" 2>/dev/null || true) + case "$_kind" in + "block special file") + addparts "$_real" + echo "$_real" + ;; + "regular file") + lo_probe "$_real" + ;; + "") + die "Unknown root \"$1\"" + ;; + *) + die "Unsupported root \"$1\": $_kind" + ;; + esac + ;; + lvm) + shift + probe $(lvm_probe "$@") + ;; + ddi) + shift + ddi_probe $(probe "$@") + ;; + GPTUUID=*) + gptuuid_probe "$@" + ;; + esac +} + +mountcore + +debug_shell internal +internal_inflate + +debug_shell probe +rootdev=$(probe $(getkparam root | sed -e 's/:/ /g')) + +debug_shell mount +mountroot "$rootdev" + +debug_shell switchroot +switchroot diff --git a/board/common/initramfs/10infix-init/module-setup.sh b/board/common/initramfs/10infix-init/module-setup.sh new file mode 100755 index 00000000..aa13656e --- /dev/null +++ b/board/common/initramfs/10infix-init/module-setup.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +progs="blkid ddi dmsetup kpartx jq lvm openssl sgdisk veritysetup" + +check() { + require_binaries $progs || return 1 + + return 0 +} + +depends() { + return 0 +} + +install() { + inst_multiple $progs + inst '/etc/os-release' + inst '/etc/rauc/keys/*' + + cp "$moddir/init" "${initdir?}/init" +} diff --git a/board/x86_64/rootfs/etc/ddi-partition-types b/board/x86_64/rootfs/etc/ddi-partition-types new file mode 100644 index 00000000..7731d5b8 --- /dev/null +++ b/board/x86_64/rootfs/etc/ddi-partition-types @@ -0,0 +1,3 @@ +CODE_ROOT=0x8304 +CODE_ROOT_VERITY=0x830c +CODE_ROOT_VERITY_SIG=0x8370 diff --git a/configs/x86_64_minimal_defconfig b/configs/x86_64_minimal_defconfig index acdabf97..0b9414d4 100644 --- a/configs/x86_64_minimal_defconfig +++ b/configs/x86_64_minimal_defconfig @@ -37,6 +37,7 @@ BR2_PACKAGE_STRESS_NG=y BR2_PACKAGE_JQ=y BR2_PACKAGE_E2FSPROGS=y BR2_PACKAGE_E2FSPROGS_RESIZE2FS=y +BR2_PACKAGE_CRYPTSETUP=y BR2_PACKAGE_DBUS_CXX=y BR2_PACKAGE_DBUS_GLIB=y BR2_PACKAGE_EUDEV_RULES_GEN=y @@ -87,6 +88,7 @@ BR2_PACKAGE_BASH_COMPLETION=y BR2_PACKAGE_SUDO=y BR2_PACKAGE_GETENT=y BR2_PACKAGE_KMOD_TOOLS=y +BR2_PACKAGE_MULTIPATH_TOOLS=y BR2_PACKAGE_PWGEN=y BR2_PACKAGE_RAUC=y BR2_PACKAGE_RAUC_DBUS=y @@ -95,6 +97,7 @@ BR2_PACKAGE_RAUC_NETWORK=y BR2_PACKAGE_RAUC_JSON=y BR2_PACKAGE_SYSKLOGD=y BR2_PACKAGE_SYSKLOGD_LOGGER=y +BR2_PACKAGE_UTIL_LINUX_PARTX=y BR2_PACKAGE_WATCHDOGD=y BR2_PACKAGE_WATCHDOGD_GENERIC=y BR2_PACKAGE_WATCHDOGD_LOADAVG=y @@ -105,6 +108,10 @@ BR2_PACKAGE_WATCHDOGD_TEMPMON=y BR2_PACKAGE_LESS=y BR2_PACKAGE_MG=y BR2_PACKAGE_NANO=y +BR2_TARGET_ROOTFS_CPIO_DRACUT=y +BR2_TARGET_ROOTFS_CPIO_DRACUT_MODULES="${BR2_EXTERNAL_INFIX_PATH}/board/common/initramfs" +BR2_TARGET_ROOTFS_CPIO_DRACUT_CONF_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/dracut.conf" +BR2_TARGET_ROOTFS_INITRAMFS=y # BR2_TARGET_ROOTFS_TAR is not set BR2_TARGET_EDK2=y BR2_TARGET_GRUB2=y @@ -150,9 +157,6 @@ BR2_PACKAGE_MDNS_ALIAS=y BR2_PACKAGE_ONIEPROM=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y -IMAGE_ITB_AUX=y -IMAGE_ITB_QCOW=y -IMAGE_ITB_RAUC=y -IMAGE_README=y +IMAGE_DDI=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y