From f3304a6539fbd0630d802df9e9ab98403199a8e7 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Fri, 10 Mar 2023 16:15:32 +0100 Subject: [PATCH] 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). --- board/amd64/grub-embed.cfg | 1 + board/amd64/grub.cfg | 29 ++++ board/amd64/linux_defconfig | 1 + board/amd64/rootfs/boot/grub/grub.cfg | 3 + board/common/Config.in | 42 +++++- board/common/genimage.cfg.in | 66 ++++++++++ board/common/lib.sh | 14 ++ board/common/mkdisk.sh | 182 ++++++++++++++++++++++++++ board/common/post-image.sh | 32 +++-- configs/amd64_defconfig | 19 +-- qemu/Config.in | 8 +- qemu/qemu.sh | 2 +- 12 files changed, 369 insertions(+), 30 deletions(-) create mode 100644 board/amd64/grub-embed.cfg create mode 100644 board/amd64/grub.cfg create mode 100644 board/amd64/rootfs/boot/grub/grub.cfg create mode 100644 board/common/genimage.cfg.in create mode 100644 board/common/lib.sh create mode 100755 board/common/mkdisk.sh diff --git a/board/amd64/grub-embed.cfg b/board/amd64/grub-embed.cfg new file mode 100644 index 00000000..b1c22b75 --- /dev/null +++ b/board/amd64/grub-embed.cfg @@ -0,0 +1 @@ +set prefix=(hd0,gpt2)/grub diff --git a/board/amd64/grub.cfg b/board/amd64/grub.cfg new file mode 100644 index 00000000..ee62c6e4 --- /dev/null +++ b/board/amd64/grub.cfg @@ -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 +} diff --git a/board/amd64/linux_defconfig b/board/amd64/linux_defconfig index 67821568..ae0a17af 100644 --- a/board/amd64/linux_defconfig +++ b/board/amd64/linux_defconfig @@ -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 diff --git a/board/amd64/rootfs/boot/grub/grub.cfg b/board/amd64/rootfs/boot/grub/grub.cfg new file mode 100644 index 00000000..6fd71f72 --- /dev/null +++ b/board/amd64/rootfs/boot/grub/grub.cfg @@ -0,0 +1,3 @@ +menuentry "Infix" --id infix { + linux /boot/bzImage root=PARTLABEL=$slot rauc.slot=$slot console=ttyS0 $append nokaslr +} diff --git a/board/common/Config.in b/board/common/Config.in index d45da6ea..4351ed1a 100644 --- a/board/common/Config.in +++ b/board/common/Config.in @@ -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 diff --git a/board/common/genimage.cfg.in b/board/common/genimage.cfg.in new file mode 100644 index 00000000..70b6a8ec --- /dev/null +++ b/board/common/genimage.cfg.in @@ -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 {} diff --git a/board/common/lib.sh b/board/common/lib.sh new file mode 100644 index 00000000..fc836cb5 --- /dev/null +++ b/board/common/lib.sh @@ -0,0 +1,14 @@ +die() +{ + echo "$@" >&2 + exit 1 +} + +load_cfg() +{ + local tmp=$(mktemp -p /tmp) + + grep "$1" $BR2_CONFIG >$tmp + . $tmp + rm $tmp +} diff --git a/board/common/mkdisk.sh b/board/common/mkdisk.sh new file mode 100755 index 00000000..c17c51c4 --- /dev/null +++ b/board/common/mkdisk.sh @@ -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 <$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 diff --git a/board/common/post-image.sh b/board/common/post-image.sh index 26458756..e037f7ef 100755 --- a/board/common/post-image.sh +++ b/board/common/post-image.sh @@ -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 diff --git a/configs/amd64_defconfig b/configs/amd64_defconfig index 51ce91d0..aad22c9d 100644 --- a/configs/amd64_defconfig +++ b/configs/amd64_defconfig @@ -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 diff --git a/qemu/Config.in b/qemu/Config.in index 147d2e6b..691a07f0 100644 --- a/qemu/Config.in +++ b/qemu/Config.in @@ -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 diff --git a/qemu/qemu.sh b/qemu/qemu.sh index 13c518b5..fed4ecb7 100755 --- a/qemu/qemu.sh +++ b/qemu/qemu.sh @@ -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