common: Unify disk image generation across aarch64 and amd64

On amd64, we use grub instead of U-Boot, because yours truly can't
figure out how to handle ACPI handover to the kernel.

The resulting image is now called disk.img instead of the old mmc.img,
since we can use it over any interface (e.g. virtio or SCSI).
This commit is contained in:
Tobias Waldekranz
2023-03-13 09:57:03 +01:00
parent 515d9f6e84
commit f3304a6539
12 changed files with 369 additions and 30 deletions
+1
View File
@@ -0,0 +1 @@
set prefix=(hd0,gpt2)/grub
+29
View File
@@ -0,0 +1,29 @@
set timeout="1"
set default="primary"
set log="loglevel=4"
load_env ORDER DEBUG
for slot in $ORDER; do
set default="$slot"
break
done
if [ "$DEBUG" ]; then
set log="debug"
fi
submenu "primary" "$log" {
set slot="$1"
set append="$2"
set root=(hd0,gpt3)
source /boot/grub/grub.cfg
}
submenu "secondary" "$log" {
set slot="$1"
set append="$2"
set root=(hd0,gpt4)
source /boot/grub/grub.cfg
}
+1
View File
@@ -31,6 +31,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PROFILING=y
CONFIG_SMP=y
CONFIG_EFI=y
# CONFIG_GCC_PLUGINS is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+3
View File
@@ -0,0 +1,3 @@
menuentry "Infix" --id infix {
linux /boot/bzImage root=PARTLABEL=$slot rauc.slot=$slot console=ttyS0 $append nokaslr
}
+40 -2
View File
@@ -16,10 +16,48 @@ config SIGN_KEY
string "Signing key"
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/dev-key" if SIGN_SRC_DIR
comment "Development Images"
comment "Additional Artifacts"
menuconfig DISK_IMAGE
bool "Disk image"
help
Compose a full disk image with redundant firmware 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
config DISK_IMAGE_SIZE
string "Image size"
depends on DISK_IMAGE
default "512M"
help
Create a disk image of this size. Suffixes like K/M/G may be
used to multiply by powers of 1024. Suffixes like KB/MB/GB may
be used to multiply by powers of 1000.
Minimum supported size is 512M.
config GNS3_APPLIANCE
bool "GNS3 Appliance"
select DISK_IMAGE
default y if BR2_x86_64
help
Create a GNS3 appliance description that, together with the
disk image, can be imported into GNS3.
menuconfig FIT_IMAGE
bool "Build FIT image"
bool "Traditional FIT image"
help
Create a "regular" FIT image where the kernel and DTBs are
stored in the FIT rather than inside the rootfs (like it
normally is in Infix).
This is useful when trying out Infix on targets whose
bootloader might not be capable of booting a raw Squash, but
is able to handle an FIT.
config FIT_ARCH
string
+66
View File
@@ -0,0 +1,66 @@
@BOOTIMG@
image aux.ext4 {
mountpoint = "/aux"
temporary = true
size = @AUXSIZE@
ext4 {
label = "aux"
}
}
image cfg.ext4 {
empty = true
temporary = true
size = @CFGSIZE@
ext4 {
label = "cfg"
}
}
image var.ext4 {
empty = true
temporary = true
size = @VARSIZE@
ext4 {
label = "var"
}
}
image disk.img {
size = @TOTALSIZE@
hdimage {
partition-table-type = "gpt"
}
@BOOTPART@
partition aux {
offset = @AUXOFFS@
image = "aux.ext4"
}
partition primary {
image = "rootfs.squashfs"
size = @IMGSIZE@
}
partition secondary {
image = "rootfs.squashfs"
size = @IMGSIZE@
}
partition cfg {
image = "cfg.ext4"
}
partition var {
image = "var.ext4"
}
}
# Silence genimage warnings
config {}
+14
View File
@@ -0,0 +1,14 @@
die()
{
echo "$@" >&2
exit 1
}
load_cfg()
{
local tmp=$(mktemp -p /tmp)
grep "$1" $BR2_CONFIG >$tmp
. $tmp
rm $tmp
}
+182
View File
@@ -0,0 +1,182 @@
#!/bin/sh
set -e
K=10
M=20
G=30
size2int()
{
# Use truncate's error message to convert input like "1K to "1024"
# for us.
#
# - What do you mean by "fragile"?!
truncate -s $1 /dev/null 2>&1 | awk '{ print($7); }'
}
dimension()
{
if [ $total -ge $((4 << G)) ]; then
bootsize=$(( 8 << M))
auxsize=$(( 8 << M))
imgsize=$(( 1 << G))
cfgsize=$((512 << M))
# var is at least ~1.5G
elif [ $total -ge $((2 << G)) ]; then
bootsize=$(( 8 << M))
auxsize=$(( 8 << M))
imgsize=$((512 << M))
cfgsize=$((256 << M))
# var is at least ~1.75G
elif [ $total -ge $((1 << G)) ]; then
bootsize=$(( 4 << M))
auxsize=$(( 4 << M))
imgsize=$((256 << M))
cfgsize=$(( 64 << M))
# var is at least ~0.5G
elif [ $total -ge $((512 << M)) ]; then
bootsize=$(( 4 << M))
auxsize=$(( 4 << M))
imgsize=$((192 << M))
cfgsize=$(( 16 << M))
# var is at least ~100M
else
echo "Can't create disk images smaller than 512M"
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)))
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
}
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))
fi
}
genboot()
{
if [ -d $BINARIES_DIR/efi-part/EFI ]; then
bootimg=$(cat <<EOF
image efi-part.vfat {
size = $bootsize
vfat {
file EFI {
image = $BINARIES_DIR/efi-part/EFI
}
}
}
EOF
)
bootpart=$(cat <<EOF
partition efi {
offset = $bootoffs
partition-type-uuid = U
bootable = true
image = efi-part.vfat
}
EOF
)
fi
}
common=$(dirname $(readlink -f "$0"))
root=$BUILD_DIR/genimage.root
tmp=$BUILD_DIR/genimage.tmp
total=$((512 << M))
bootoffs=
bootimg=
bootpart=
while getopts "a:s:" opt; do
case ${opt} in
a)
arch=$OPTARG
;;
s)
total=$(size2int $OPTARG)
;;
esac
done
shift $((OPTIND - 1))
mkdir -p $root
probeboot
dimension
genboot
# Use awk over sed because replacement text may contain newlines,
# which sed does not approve of.
awk \
-vtotal=$total \
-vauxsize=$auxsize -vauxoffs=$auxoffs \
-vimgsize=$imgsize \
-vcfgsize=$cfgsize \
-vvarsize=$varsize \
-vbootimg="$bootimg" -vbootpart="$bootpart" \
'{
sub(/@TOTALSIZE@/, total);
sub(/@AUXSIZE@/, auxsize);
sub(/@AUXOFFS@/, auxoffs);
sub(/@IMGSIZE@/, imgsize);
sub(/@CFGSIZE@/, cfgsize);
sub(/@VARSIZE@/, varsize);
sub(/@BOOTIMG@/, bootimg);
sub(/@BOOTPART@/, bootpart);
}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
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/amd64/grub.cfg $root/aux/grub/grub.cfg
;;
*)
;;
esac
rm -rf $tmp
genimage \
--rootpath $root \
--tmppath $tmp \
--inputpath $BINARIES_DIR \
--outputpath $BINARIES_DIR \
--config $root/genimage.cfg
+18 -14
View File
@@ -1,21 +1,25 @@
#!/bin/sh
# shellcheck disable=SC1090
. "$BR2_CONFIG" 2>/dev/null
common=$(dirname "$(readlink -f "$0")")
. $common/lib.sh
# Temporary, separate handling of aarch64 and amd64 images.
# Best would be to have the same for both, i.e., boot GNS3
# with u-boot.
if [ "$BR2_ARCH" = "aarch64" ]; then
# shellcheck disable=SC2034
imgdir=$1
arch=$2
signkey=$3
load_cfg BR2_EXTERNAL_INFIX_PATH
$common/sign.sh $arch $signkey
load_cfg BR2_ARCH
load_cfg SIGN_KEY
$common/sign.sh $BR2_ARCH $SIGN_KEY
load_cfg DISK_IMAGE
if [ "$DISK_IMAGE" = "y" ]; then
$common/mkdisk.sh -a $BR2_ARCH
fi
load_cfg GNS3_APPLIANCE
if [ "$GNS3_APPLIANCE" = "y" ]; then
$common/mkgns3a.sh
fi
load_cfg FIT_IMAGE
if [ "$FIT_IMAGE" = "y" ]; then
$common/mkfit.sh
$common/mkmmc.sh
elif [ "$BR2_ARCH" = "x86_64" ]; then
"$common/mkgns3a.sh"
fi
+10 -9
View File
@@ -99,20 +99,21 @@ BR2_PACKAGE_WATCHDOGD=y
BR2_PACKAGE_MG=y
BR2_PACKAGE_MOST=y
BR2_PACKAGE_NANO=y
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_SIZE="128M"
BR2_TARGET_ROOTFS_ISO9660=y
BR2_TARGET_ROOTFS_ISO9660_BOOT_MENU="$(BR2_EXTERNAL_INFIX_PATH)/board/amd64/isolinux.cfg"
BR2_TARGET_ROOTFS_ISO9660_HYBRID=y
BR2_TARGET_ROOTFS_SQUASHFS=y
BR2_TARGET_ROOTFS_SQUASHFS4_ZSTD=y
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_SYSLINUX=y
BR2_TARGET_SYSLINUX_ISOLINUX=y
BR2_TARGET_SYSLINUX_MBR=y
BR2_TARGET_EDK2=y
BR2_TARGET_GRUB2=y
BR2_TARGET_GRUB2_X86_64_EFI=y
BR2_TARGET_GRUB2_BUILTIN_MODULES_EFI="boot linux ext2 fat squash4 part_gpt normal efi_gop configfile loadenv test terminfo terminal echo"
BR2_TARGET_GRUB2_BUILTIN_CONFIG_EFI="${BR2_EXTERNAL_INFIX_PATH}/board/amd64/grub-embed.cfg"
BR2_TARGET_GRUB2_INSTALL_TOOLS=y
BR2_PACKAGE_HOST_E2FSPROGS=y
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
BR2_PACKAGE_HOST_GENEXT2FS=y
BR2_PACKAGE_HOST_GENIMAGE=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_CLIXON_RESTCONF_FCGI=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
+4 -4
View File
@@ -47,16 +47,16 @@ config QEMU_BIOS
string
depends on !QEMU_LOADER_KERNEL
default "images/u-boot.bin" if QEMU_LOADER_UBOOT
default "OVMF.fd" if QEMU_LOADER_OVMF
default "images/OVMF.fd" if QEMU_LOADER_OVMF
config QEMU_ROOTFS
string
default "images/mmc.img" if QEMU_LOADER_UBOOT
default "images/rootfs.squashfs" if QEMU_LOADER_KERNEL
default "images/disk.img" if !QEMU_ROOTFS_INITRD
default "images/rootfs.squashfs" if QEMU_ROOTFS_INITRD
config QEMU_RW
string "Writable layer"
depends on !QEMU_ROOTFS_MMC
depends on QEMU_ROOTFS_INITRD
default "images/cfg.ext4"
config QEMU_CONSOLE
+1 -1
View File
@@ -42,7 +42,7 @@ append_args()
local size=$((($(stat -c %s $QEMU_ROOTFS) + 1023) >> 10))
echo -n "root=/dev/ram ramdisk_size=${size} "
elif [ "$QEMU_ROOTFS_VSCSI" = "y" ]; then
echo -n "root=/dev/vda "
echo -n "root=PARTLABEL=primary "
fi
if [ "$V" != "1" ]; then