board/common: Move QEMU disk creation to separate make target

This commit is contained in:
Tobias Waldekranz
2025-12-03 16:46:04 +01:00
parent 290bdfcedb
commit aee053c94b
11 changed files with 160 additions and 253 deletions
+1 -77
View File
@@ -2,6 +2,7 @@ menu "Images"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rootfs/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rauc/Config.in"
endmenu
@@ -24,83 +25,6 @@ config TRUSTED_KEYS_EXTRA_PATH
string "Path to extra keys to include in image"
depends on TRUSTED_KEYS
menuconfig DISK_IMAGE
bool "Disk image"
help
Compose a full disk image with redundant Linux OS partitions,
configuration partition, etc.
This is useful when:
- Bringing up a blank system during manufacturing
- Creating a GNS3 appliance
- Developing/debugging issues in the boot process in QEMU
menuconfig DISK_IMAGE_SIZE
string "Image size"
depends on DISK_IMAGE
default "512M"
help
Create a disk image of this size. A K/M/G suffix may be used
to multiply by powers of 1024. Suffixes like KB/MB/GB may be
used to multiply by powers of 1000. The image will be split
proportionally to fit the two rootfs, a kernel, a writable
/cfg and /var partiotions.
Minimum supported size is 512M.
choice
prompt "Bootloader"
depends on DISK_IMAGE
default DISK_IMAGE_BOOT_EFI if BR2_x86_64
default DISK_IMAGE_BOOT_NONE
config DISK_IMAGE_BOOT_NONE
bool "None"
help
Do not create any bootloader partition in the disk image.
config DISK_IMAGE_BOOT_EFI
bool "EFI"
help
Create a boot partition from a directory containing an EFI
boot application, e.g. GRUB.
config DISK_IMAGE_BOOT_BIN
bool "Binary"
help
Create a boot partition from a raw image containing the boot
application, e.g. U-Boot.
endchoice
config DISK_IMAGE_BOOT_DATA
string "Bootloader data"
depends on DISK_IMAGE
depends on DISK_IMAGE_BOOT_EFI || DISK_IMAGE_BOOT_BIN
default "${BINARIES_DIR}/efi-part/EFI" if BR2_x86_64
help
Path to the directory or file holding the bootloader data.
config DISK_IMAGE_BOOT_OFFSET
hex "Bootloader offset"
depends on DISK_IMAGE
depends on DISK_IMAGE_BOOT_EFI || DISK_IMAGE_BOOT_BIN
default 0x8000
help
Offset at which the bootloader partition is placed. Remember
to make sure that the GPT still fits at the start of the
image.
config DISK_IMAGE_RELEASE_URL
string "Infix URL"
depends on DISK_IMAGE
depends on !BR2_TARGET_ROOTFS_SQUASHFS
default "https://github.com/kernelkit/infix/releases/download/latest/infix-${BR2_ARCH}.tar.gz"
help
In situations where Infix itself is not being built, but a
disk image is, i.e. when building a bootloader: place this
Infix release in the primary and secondary partitions.
menuconfig GNS3_APPLIANCE
bool "GNS3 Appliance"
select DISK_IMAGE
@@ -0,0 +1,80 @@
menuconfig IMAGE_ITB_QCOW
bool "QEMU disk image (ITB)"
default y
select IMAGE_ITB_ROOTFS
select IMAGE_ITB_AUX
select BR2_PACKAGE_HOST_GENIMAGE
help
Compose a full disk image with redundant Linux OS partitions,
configuration partition, etc., for systems using ITB images.
This is useful when:
- Bringing up a blank system during manufacturing
- Creating a GNS3 appliance
- Developing/debugging issues in the boot process in QEMU
menuconfig IMAGE_ITB_QCOW_SIZE
string "Image size"
depends on IMAGE_ITB_QCOW
default "512M"
help
Create a disk image of this size. A K/M/G suffix may be used
to multiply by powers of 1024. Suffixes like KB/MB/GB may be
used to multiply by powers of 1000. The image will be split
proportionally to fit the two rootfs, a kernel, a writable
/cfg and /var partiotions.
Minimum supported size is 512M.
choice
prompt "Bootloader"
depends on IMAGE_ITB_QCOW
default IMAGE_ITB_QCOW_BOOT_EFI if BR2_x86_64
default IMAGE_ITB_QCOW_BOOT_NONE
config IMAGE_ITB_QCOW_BOOT_NONE
bool "None"
help
Do not create any bootloader partition in the disk image.
config IMAGE_ITB_QCOW_BOOT_EFI
bool "EFI"
help
Create a boot partition from a directory containing an EFI
boot application, e.g. GRUB.
config IMAGE_ITB_QCOW_BOOT_BIN
bool "Binary"
help
Create a boot partition from a raw image containing the boot
application, e.g. U-Boot.
endchoice
config IMAGE_ITB_QCOW_BOOT_DATA
string "Bootloader data"
depends on IMAGE_ITB_QCOW
depends on IMAGE_ITB_QCOW_BOOT_EFI || IMAGE_ITB_QCOW_BOOT_BIN
default "${BINARIES_DIR}/efi-part/EFI" if BR2_x86_64
help
Path to the directory or file holding the bootloader data.
config IMAGE_ITB_QCOW_BOOT_OFFSET
hex "Bootloader offset"
depends on IMAGE_ITB_QCOW
depends on IMAGE_ITB_QCOW_BOOT_EFI || IMAGE_ITB_QCOW_BOOT_BIN
default 0x8000
help
Offset at which the bootloader partition is placed. Remember
to make sure that the GPT still fits at the start of the
image.
config IMAGE_ITB_QCOW_RELEASE_URL
string "Infix URL"
depends on IMAGE_ITB_QCOW
depends on !BR2_TARGET_ROOTFS_SQUASHFS
default "https://github.com/kernelkit/infix/releases/download/latest/infix-${BR2_ARCH}.tar.gz"
help
In situations where Infix itself is not being built, but a
disk image is, i.e. when building a bootloader: place this
Infix release in the primary and secondary partitions.
@@ -1,8 +1,6 @@
#!/bin/sh
set -e
. $BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/etc/partition-uuid
K=10
M=20
G=30
@@ -47,43 +45,32 @@ dimension()
exit 1
fi
# Size var to fit whatever is left over. Also reserve another 32K
# at the end to make room for the backup GPT.
varsize=$(($total - $auxsize - 2 * $imgsize - $cfgsize))
if [ "$bootoffs" ]; then
varsize=$(($varsize - $bootsize))
fi
varsize=$(($varsize - (32 << K)))
# Place aux right after the GPT...
auxoffs=$((32 << K))
if [ "$bootoffs" ]; then
# Align the end of the boot partition to an even MiB. E.g. if
# boot was dimensioned to 4M, and bootoffs is 32K, then the
# final bootsize becomes 4M - 32K, meaning aux will start on
# exactly 4M.
auxoffs=$bootsize
bootsize=$(($bootsize - $bootoffs))
else
# No bootloader, place aux after GPT, resize it to end on an
# even MiB (as is done for boot above).
auxoffs=$((32 << K))
auxsize=$(($auxsize - $auxoffs))
fi
}
if [ $((bootoffs)) -lt $((32 << K)) ]; then
echo "Boot partition collides with GPT"
exit 1
fi
probeboot()
{
# If we have built an EFI app, typically grub, make sure to
# include it.
if [ -d $BINARIES_DIR/efi-part/EFI ]; then
bootoffs=$((32 << K))
# ...unless we have a boot partition, in which case we place
# it after that.
auxoffs=$((auxoffs + bootsize))
fi
# Finally, size var to fit whatever is left over by subtracting
# all other images, plus another 32K at the end for the backup
# GPT.
varsize=$((total - auxoffs - auxsize - 2 * imgsize - cfgsize - (32 << K)))
}
genboot()
{
if [ -d "$bootdata" ]; then
bootimg=$(cat <<EOF
image $BINARIES_DIR/efi-part.vfat {
image efi-part.vfat {
temporary = true
size = $bootsize
vfat {
file EFI {
@@ -98,7 +85,7 @@ EOF
offset = $bootoffs
partition-type-uuid = U
bootable = true
image = $BINARIES_DIR/efi-part.vfat
image = efi-part.vfat
}
EOF
)
@@ -117,44 +104,29 @@ EOF
fi
}
common=$(dirname $(readlink -f "$0"))
root=$BUILD_DIR/genimage.root
tmp=$BUILD_DIR/genimage.tmp
mkdir -p "${WORKDIR}"/root
rm -rf "${WORKDIR}"/tmp
mkdir -p "${WORKDIR}"/tmp
total=$((512 << M))
bootoffs=$((32 << K))
bootdata=
diskimg=disk.img
qcowimg="${ARTIFACT}.qcow2"
total=$(size2int $SIZE)
bootoffs=
bootdata=$BOOT_DATA
bootimg=
bootpart=
tmpimage=$(mktemp)
while getopts "a:b:B:n:s:" opt; do
case ${opt} in
a)
arch=$OPTARG
;;
b)
bootdata=$OPTARG
;;
B)
bootoffs=$(($OPTARG))
;;
n)
diskimg=${OPTARG}
;;
s)
total=$(size2int $OPTARG)
;;
esac
done
shift $((OPTIND - 1))
mkdir -p $root
if [ -n "${BOOT_OFFSET}" ]; then
bootoffs=$(($BOOT_OFFSET))
fi
probeboot
dimension
genboot
. $BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/etc/partition-uuid
[ -n "${AUX_UUID}" ]
[ -n "${PRIMARY_UUID}" ]
[ -n "${SECONDARY_UUID}" ]
# Use awk over sed because replacement text may contain newlines,
# which sed does not approve of.
awk \
@@ -166,7 +138,7 @@ awk \
-vimgsize=$imgsize \
-vcfgsize=$cfgsize \
-vvarsize=$varsize \
-vdiskimg=$tmpimage \
-vqcowimg=$qcowimg \
-vbootimg="$bootimg" -vbootpart="$bootpart" \
'{
sub(/@TOTALSIZE@/, total);
@@ -175,7 +147,7 @@ awk \
sub(/@IMGSIZE@/, imgsize);
sub(/@CFGSIZE@/, cfgsize);
sub(/@VARSIZE@/, varsize);
sub(/@DISKIMG@/, diskimg);
sub(/@QCOWIMG@/, qcowimg);
sub(/@BOOTIMG@/, bootimg);
sub(/@BOOTPART@/, bootpart);
sub(/@AUXUUID@/, auxuuid);
@@ -183,35 +155,11 @@ awk \
sub(/@SECONDARYUUID@/, secondaryuuid);
}1' \
< $common/genimage.cfg.in >$root/genimage.cfg
mkdir -p $root/aux
cp -f $BINARIES_DIR/rootfs.itbh $root/aux/primary.itbh
cp -f $BINARIES_DIR/rootfs.itbh $root/aux/secondary.itbh
cp -f $BINARIES_DIR/rauc.status $root/aux/rauc.status
case "$arch" in
aarch64)
mkenvimage -s 0x4000 -o "$root/aux/uboot.env" \
"$BR2_EXTERNAL_INFIX_PATH/board/common/uboot/aux-env.txt"
;;
x86_64)
mkdir -p "$root/aux/grub"
cp -f "$BR2_EXTERNAL_INFIX_PATH/board/$arch/grub.cfg" \
"$BR2_EXTERNAL_INFIX_PATH/board/$arch/grubenv" \
"$root/aux/grub/"
;;
*)
;;
esac
rm -rf "$tmp"
< $PKGDIR/genimage.cfg.in >$WORKDIR/genimage.cfg
genimage \
--rootpath "$root" \
--tmppath "$tmp" \
--inputpath "$BINARIES_DIR" \
--config "$root/genimage.cfg"
qemu-img convert -c -O qcow2 "$tmpimage" "$BINARIES_DIR/$diskimg"
rm "$tmpimage"
--tmppath "${WORKDIR}"/tmp \
--rootpath "${WORKDIR}"/root \
--inputpath "$BINARIES_DIR" \
--outputpath "$BINARIES_DIR" \
--config "${WORKDIR}"/genimage.cfg
@@ -1,16 +1,5 @@
@BOOTIMG@
image aux.ext4 {
mountpoint = "/aux"
temporary = true
size = @AUXSIZE@
ext4 {
label = "aux"
use-mke2fs = true
}
}
image cfg.ext4 {
empty = true
temporary = true
@@ -33,7 +22,8 @@ image var.ext4 {
}
}
image @DISKIMG@ {
image disk.img {
temporary = true
size = @TOTALSIZE@
hdimage {
partition-table-type = "gpt"
@@ -68,5 +58,15 @@ image @DISKIMG@ {
}
}
image @QCOWIMG@ {
qemu {
format = "qcow2"
}
partition disk {
image = "disk.img"
}
}
# Silence genimage warnings
config {}
@@ -0,0 +1,10 @@
################################################################################
#
# image-itb-qcow
#
################################################################################
IMAGE_ITB_QCOW_DEPENDENCIES := host-genimage image-itb-rootfs image-itb-aux
IMAGE_ITB_QCOW_CONFIG_VARS := BOOT_DATA BOOT_OFFSET SIZE
$(eval $(ix-image))
+1
View File
@@ -10,6 +10,7 @@ $(1): $$($(2)_DEPENDENCIES)
PKGDIR=$$($(2)_DIR) \
WORKDIR=$$(BUILD_DIR)/$(1) \
BINARIES_DIR=$$(BINARIES_DIR) \
BR2_EXTERNAL_INFIX_PATH=$$(BR2_EXTERNAL_INFIX_PATH) \
ARTIFACT=$$(INFIX_ARTIFACT) \
COMPATIBLE=$$(INFIX_COMPATIBLE) \
VERSION=$$(INFIX_VERSION) \
-35
View File
@@ -1,35 +0,0 @@
#!/bin/sh
set -e
# Bootstrap a RAUC status file showing the newly created image
# installed to both the primary and secondary slots. This then bundled
# in the aux partition in mkdisk.sh, so that RAUC (on the target) can
# always report the installed versions.
rauc info --no-verify --output-format=shell $1 >/tmp/rauc-$$.info
. /tmp/rauc-$$.info
rm /tmp/rauc-$$.info
tstamp=$(date -u +%FT%TZ)
cat <<EOF
[slot.rootfs.0]
bundle.compatible=$RAUC_MF_COMPATIBLE
bundle.version=$RAUC_MF_VERSION
status=ok
sha256=$RAUC_IMAGE_DIGEST_0
size=$RAUC_IMAGE_SIZE_0
installed.timestamp=$tstamp
installed.count=1
activated.timestamp=$tstamp
activated.count=1
[slot.rootfs.1]
bundle.compatible=$RAUC_MF_COMPATIBLE
bundle.version=$RAUC_MF_VERSION
status=ok
sha256=$RAUC_IMAGE_DIGEST_0
size=$RAUC_IMAGE_SIZE_0
installed.timestamp=$tstamp
installed.count=1
activated.timestamp=$tstamp
activated.count=1
EOF
+1 -22
View File
@@ -14,7 +14,6 @@ load_cfg BR2_DEFCONFIG
load_cfg BR2_EXTERNAL_INFIX_PATH
load_cfg BR2_TARGET_ROOTFS
load_cfg INFIX_ID
load_cfg INFIX_COMPATIBLE
# The default IMAGE_ID is infix-$BR2_ARCH but can be overridden
# for imaage names, and compat strings, like infix-r2s
@@ -23,7 +22,6 @@ if [ -n "$IMAGE_ID" ]; then
else
NAME="$INFIX_ID"-$(echo "$BR2_ARCH" | tr _ - | sed 's/x86-64/x86_64/')
fi
diskimg=disk.qcow2
ver()
{
@@ -33,26 +31,7 @@ ver()
fi
}
load_cfg DISK_IMAGE
if [ "$DISK_IMAGE" = "y" ]; then
ixmsg "Creating Disk Image"
diskimg="${NAME}-disk$(ver).qcow2"
bootcfg=
if [ "$DISK_IMAGE_BOOT_DATA" ]; then
bootcfg="-b $DISK_IMAGE_BOOT_DATA -B $DISK_IMAGE_BOOT_OFFSET"
fi
if [ "$BR2_TARGET_ROOTFS_SQUASHFS" != "y" ] && \
[ ! -f "$BINARIES_DIR/rootfs.squashfs" ]; then
ixmsg " Injecting $DISK_IMAGE_RELEASE_URL"
archive="$BINARIES_DIR/$(basename $DISK_IMAGE_RELEASE_URL)"
[ -f "$archive" ] || wget -O"$archive" "$DISK_IMAGE_RELEASE_URL"
tar -xa --strip-components=1 -C "$BINARIES_DIR" -f "$archive"
fi
$common/mkrauc-status.sh "$BINARIES_DIR/${NAME}.pkg" >"$BINARIES_DIR/rauc.status"
$common/mkdisk.sh -a $BR2_ARCH -n $diskimg -s $DISK_IMAGE_SIZE $bootcfg
fi
diskimg="${NAME}$(ver).qcow2"
load_cfg GNS3_APPLIANCE
if [ "$GNS3_APPLIANCE" = "y" ]; then
+10 -10
View File
@@ -74,7 +74,7 @@ get_base_img()
{
local files="$1"
local base_img_file
base_img_file=$(echo "$files" | tr ' ' '\n' | grep -- '-disk.qcow2$')
base_img_file=$(echo "$files" | tr ' ' '\n' | grep -- '.qcow2$')
echo "$envdir/qeneth/$(basename "$base_img_file")"
}
@@ -95,16 +95,16 @@ start_topology()
ln -sf "$file" "$envdir/qeneth/$filename"
done
base_img=$(get_base_img "$files")
test_img_name="${base_img%-disk.qcow2}-disk-test"
base_img_name="${base_img%-disk.qcow2}-disk"
test_img_raw="${test_img_name}.img"
base_img_raw="${base_img_name}.img"
test_img_qcow2="${test_img_name}.qcow2"
base_img_qcow2=$(get_base_img "$files")
base_img_disk="${base_img_qcow2%.qcow2}.disk"
test_img_disk="${base_img_qcow2%.qcow2}-test.disk"
test_img_qcow2="${test_img_disk%.disk}.qcow2"
qemu-img convert -f qcow2 -O raw "$base_img_qcow2" "$base_img_disk"
$testdir/inject-test-mode -b "$base_img_disk" -o "$test_img_disk"
qemu-img convert -f raw -O qcow2 "$test_img_disk" "$test_img_qcow2"
qemu-img convert -f qcow2 -O raw "$base_img" "$base_img_raw"
$testdir/inject-test-mode -b "$base_img_raw" -o "$test_img_raw"
qemu-img convert -f raw -O qcow2 "$test_img_raw" "$test_img_qcow2"
img_name=$(basename $test_img_qcow2)
sed -i "s/qn_image=\".*\"/qn_image=\"$img_name\"/" "$envdir/qeneth/topology.dot.in"
+4 -4
View File
@@ -17,11 +17,11 @@ mode-qeneth := -q $(test-dir)/virt/quad
mode-host := -t $(or $(TOPOLOGY),/etc/infamy.dot)
mode-run := -t $(BINARIES_DIR)/qemu.dot
mode := $(mode-$(TEST_MODE))
INFIX_IMAGE_ID := $(call qstrip,$(INFIX_IMAGE_ID))
binaries-$(ARCH) := $(addprefix $(INFIX_IMAGE_ID),.img -disk.qcow2)
pkg-$(ARCH) := -p $(O)/images/$(addprefix $(INFIX_IMAGE_ID),.pkg)
pkg-$(ARCH) := -p $(O)/images/$(INFIX_ARTIFACT).pkg
binaries-$(ARCH) := $(INFIX_ARTIFACT).qcow2
binaries-x86_64 += OVMF.fd
binaries := $(foreach bin,$(binaries-$(ARCH)),-f $(BINARIES_DIR)/$(bin))
binaries := $(foreach bin,$(binaries-$(ARCH)),-f $(BINARIES_DIR)/$(bin))
# Common transport override for minimal defconfigs
ifneq ($(BR2_PACKAGE_ROUSETTE),y)
+1 -1
View File
@@ -9,7 +9,7 @@ graph "quad" {
edge [color="cornflowerblue", penwidth="2"];
qn_template="infix-bios-x86_64";
qn_image="infix-x86_64-disk-test.qcow2"
qn_image="infix-x86_64-test.qcow2"
qn_oui="00:a0:85";
qn_append="quiet";