From 4a9529dd347c2db69a7df63632dc1f40f14df696 Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Thu, 11 Aug 2022 10:51:18 +0200 Subject: [PATCH] armbian-next: `qemu-uboot-arm64` and `qemu-uboot-x86` new boards - sharing most UEFI code, will replace the `virtual` one soon - x86: patch uboot defconfig to use the `q35` machine type, not `i440fx` - separate x86 bootscript, due to non-uInitrd-ness of it - hack ramdisk load address both in u-boot source and bootscript - use 32-bit u-boot, not 64-bit - grub: introduce `UEFI_GRUB=skip`, does not deploy GRUB (but does the kernel packages, etc) - auto-enable qcow2 output for these - works with both distro's and Armbian's kernels --- config/boards/qemu-uboot-arm64.wip | 8 +++ config/boards/qemu-uboot-x86.wip | 11 ++++ config/bootscripts/boot-qemu-x86.cmd | 19 ++++++ .../sources/families/include/uefi_common.inc | 36 ++++++++++ extensions/grub.sh | 66 ++++++++++++------- extensions/image-output-qcow2.sh | 2 +- lib/functions/compilation/uboot.sh | 3 +- lib/functions/image/partitioning.sh | 17 ++++- ...6_ramdisk_addr_and_boot_virtio_first.patch | 46 +++++++++++++ .../use_q35_dts_for_qemu-x86_defconfig.patch | 25 +++++++ 10 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 config/boards/qemu-uboot-arm64.wip create mode 100644 config/boards/qemu-uboot-x86.wip create mode 100644 config/bootscripts/boot-qemu-x86.cmd create mode 100644 patch/u-boot/u-boot-qemu-x86/hack_x86_ramdisk_addr_and_boot_virtio_first.patch create mode 100644 patch/u-boot/u-boot-qemu-x86/use_q35_dts_for_qemu-x86_defconfig.patch diff --git a/config/boards/qemu-uboot-arm64.wip b/config/boards/qemu-uboot-arm64.wip new file mode 100644 index 0000000000..d0679f085d --- /dev/null +++ b/config/boards/qemu-uboot-arm64.wip @@ -0,0 +1,8 @@ +# qemu via uboot on arm64, for "virt" qemu machine type +export BOARD_NAME="uefi-arm64" +export BOARDFAMILY="uefi-arm64" +export KERNEL_TARGET="current,edge" + +export UEFI_GRUB="skip" # Skip GRUB for this board +export SERIALCON="ttyS0" +export QEMU_UBOOT_BOOTCONFIG="qemu_arm64_defconfig" diff --git a/config/boards/qemu-uboot-x86.wip b/config/boards/qemu-uboot-x86.wip new file mode 100644 index 0000000000..2758b1e55a --- /dev/null +++ b/config/boards/qemu-uboot-x86.wip @@ -0,0 +1,11 @@ +# x86_64 via qemu + u-boot firmware, for q35 machine type +export UEFI_GRUB="skip" # Skip GRUB for this board +export BOARD_NAME="uefi-x86" +export BOARDFAMILY="uefi-x86" +export KERNEL_TARGET="current,edge" + +export SERIALCON="ttyS0" + +# u-boot's "x86_64" is incomplete; use the 32-bit version. +export QEMU_UBOOT_BOOTCONFIG="qemu-x86_defconfig" +export INITRD_ARCH='x86' # not really needed, but just in case diff --git a/config/bootscripts/boot-qemu-x86.cmd b/config/bootscripts/boot-qemu-x86.cmd new file mode 100644 index 0000000000..bdab869624 --- /dev/null +++ b/config/bootscripts/boot-qemu-x86.cmd @@ -0,0 +1,19 @@ +# do the virtio dance +${devtype} scan +${devtype} info +ls virtio ${devnum}:${distro_bootpart} /boot + +# higher load address; the default causes the initrd to be overwritten when the bzImage is unpacked.... +setenv ramdisk_addr_r 0x8000000 +echo KERNEL LOAD ADDRESS: kernel_addr_r: ${kernel_addr_r} +echo INITRD LOAD ADDRESS: ramdisk_addr_r: ${ramdisk_addr_r} + +load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /boot/vmlinuz +# Attention, this is the raw initrd.img, NOT uInitrd for uboot/ARM +load ${devtype} ${devnum}:${distro_bootpart} ${ramdisk_addr_r} /boot/initrd.img + +# boot params +setenv bootargs root=LABEL=armbi_root ro console=ttyS0 + +# zboot knows how to handle bzImage... +zboot ${kernel_addr_r} - ${ramdisk_addr_r} ${filesize} diff --git a/config/sources/families/include/uefi_common.inc b/config/sources/families/include/uefi_common.inc index 57db51f7ef..aed91744cf 100644 --- a/config/sources/families/include/uefi_common.inc +++ b/config/sources/families/include/uefi_common.inc @@ -26,3 +26,39 @@ case "${BRANCH}" in export KERNELPATCHDIR="uefi-${LINUXFAMILY}-${BRANCH}" # Might be empty. ;; esac + +if [[ "${QEMU_UBOOT_BOOTCONFIG}" != "" ]]; then + # Allowance for using the UEFI kernels, but not an UEFI bootloader, instead, use qemu with uboot. + # Used in the qemu-uboot-x86 and qemu-uboot-arm64 "boards". + display_alert "Using UEFI as base for qemu-uboot-${LINUXFAMILY}" "Using BOOTCONFIG: ${QEMU_UBOOT_BOOTCONFIG}" "debug" + export ATF_COMPILE="no" + export BOOTSCRIPT="boot-qemu-${LINUXFAMILY}.cmd:boot.cmd" + export BOOTDIR="qemu-uboot-${LINUXFAMILY}" + export BOOTSOURCE='https://source.denx.de/u-boot/u-boot.git' + export BOOTBRANCH='tag:v2022.10' + export UBOOT_TARGET_MAP="all;;u-boot.rom" # Can't find the target that produces 'u-boot.rom', so for now 'make all' + export PACKAGE_LIST_FAMILY="spice-vdagent qemu-guest-agent" # Nice-to-have packages for running under qemu + export BOOTCONFIG="${QEMU_UBOOT_BOOTCONFIG}" + export PACKAGE_LIST_FAMILY_REMOVE="plymouth" # Nice-to-have packages for running under qemu + export PLYMOUTH="no" # try with smaller initrd? + + # A patch to convert to `q35` machine type DTS (x86 only) + export BOOTPATCHDIR="u-boot-qemu-${LINUXFAMILY}" + + # Config for the qcow2 image + declare -g QCOW2_RESIZE_AMOUNT="+50G" # resize the qcow2 image to be 50G bigger + declare -g QCOW2_KEEP_IMG="no" # produce only the .qcow2 image, not raw .img + + # Enable the qcow2 output extension. + enable_extension "image-output-qcow2" + + write_uboot_platform() { + echo "Not writing uboot for qemu-uboot-xxxx platform" + } + + function pre_umount_final_image__export_uboot_rom() { + local uboot_name="${CHOSEN_UBOOT}_${REVISION}_${ARCH}" + display_alert "Exporting u-boot.rom" "${uboot_name} - ${version}.u-boot.rom" "debug" + run_host_command_logged cp -pv "${MOUNT}/usr/lib/${uboot_name}/u-boot.rom" "${DESTIMG}/${version}.u-boot.rom" || true + } +fi diff --git a/extensions/grub.sh b/extensions/grub.sh index ab4fecac26..b8350c43b6 100644 --- a/extensions/grub.sh +++ b/extensions/grub.sh @@ -10,32 +10,37 @@ function extension_prepare_config__prepare_flash_kernel() { export GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:-}" # Cmdline by default export UEFI_ENABLE_BIOS_AMD64="${UEFI_ENABLE_BIOS_AMD64:-yes}" # Enable BIOS too if target is amd64 export UEFI_EXPORT_KERNEL_INITRD="${UEFI_EXPORT_KERNEL_INITRD:-no}" # Export kernel and initrd for direct kernel boot "kexec" - # User config overrides. - export BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot. - unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot. - export IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff. - export UEFISIZE=256 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions - export BOOTSIZE=0 # No separate /boot when using UEFI. - export CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub. - export EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name. - export UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64 - local uefi_packages="efibootmgr efivar cloud-initramfs-growroot" # Use growroot, add some efi-related packages - uefi_packages="os-prober grub-efi-${ARCH}-bin ${uefi_packages}" # This works for Ubuntu and Debian, by sheer luck; common for EFI and BIOS - # BIOS-compatibility for amd64 - if [[ "${ARCH}" == "amd64" ]]; then - export UEFI_GRUB_TARGET="x86_64-efi" # Default for x86_64 - if [[ "${UEFI_ENABLE_BIOS_AMD64}" == "yes" ]]; then - export uefi_packages="${uefi_packages} grub-pc-bin grub-pc" - export UEFI_GRUB_TARGET_BIOS="i386-pc" - export BIOSSIZE=4 # 4 MiB BIOS partition - else - export uefi_packages="${uefi_packages} grub-efi-${ARCH}" + if [[ "${UEFI_GRUB}" != "skip" ]]; then + # User config overrides for GRUB. + export BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot. + unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot. + export IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff. + export UEFISIZE=256 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions + export BOOTSIZE=0 # No separate /boot when using UEFI. + export CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub. + export EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name. + export UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64 + local uefi_packages="" # Use growroot, add some efi-related packages + + uefi_packages="efibootmgr efivar cloud-initramfs-growroot" # Use growroot, add some efi-related packages + uefi_packages="os-prober grub-efi-${ARCH}-bin ${uefi_packages}" # This works for Ubuntu and Debian, by sheer luck; common for EFI and BIOS + + # BIOS-compatibility for amd64 + if [[ "${ARCH}" == "amd64" ]]; then + export UEFI_GRUB_TARGET="x86_64-efi" # Default for x86_64 + if [[ "${UEFI_ENABLE_BIOS_AMD64}" == "yes" ]]; then + export uefi_packages="${uefi_packages} grub-pc-bin grub-pc" + export UEFI_GRUB_TARGET_BIOS="i386-pc" + export BIOSSIZE=4 # 4 MiB BIOS partition + else + export uefi_packages="${uefi_packages} grub-efi-${ARCH}" + fi fi - fi - [[ "${ARCH}" == "arm64" ]] && export uefi_packages="${uefi_packages} grub-efi-${ARCH}" - [[ "${ARCH}" == "arm64" ]] && export UEFI_GRUB_TARGET="arm64-efi" # Default for arm64-efi + [[ "${ARCH}" == "arm64" ]] && export uefi_packages="${uefi_packages} grub-efi-${ARCH}" + [[ "${ARCH}" == "arm64" ]] && export UEFI_GRUB_TARGET="arm64-efi" # Default for arm64-efi + fi if [[ "${DISTRIBUTION}" == "Ubuntu" ]]; then DISTRO_KERNEL_PACKAGES="linux-image-generic" @@ -65,7 +70,7 @@ function extension_prepare_config__prepare_flash_kernel() { # shellcheck disable=SC2086 add_packages_to_image ${DISTRO_FIRMWARE_PACKAGES} ${DISTRO_KERNEL_PACKAGES} ${uefi_packages} - display_alert "Activating" "GRUB with SERIALCON=${SERIALCON}; timeout ${UEFI_GRUB_TIMEOUT}; BIOS=${UEFI_GRUB_TARGET_BIOS}" "" + display_alert "${UEFI_GRUB} activating" "GRUB with SERIALCON=${SERIALCON}; timeout ${UEFI_GRUB_TIMEOUT}; BIOS=${UEFI_GRUB_TARGET_BIOS}" "" } # @TODO: extract u-boot into an extension, so that core bsps don't have this stuff in there to begin with. @@ -74,7 +79,9 @@ post_family_tweaks_bsp__remove_uboot_grub() { display_alert "Removing uboot from BSP" "${EXTENSION}" "info" # Simply remove everything with 'uboot' or 'u-boot' in their filenames from the BSP package. # shellcheck disable=SC2154 # $destination is the target dir of the bsp building function - find "$destination" -type f | grep -e "uboot" -e "u-boot" | xargs rm + pushd "${destination}" || exit_with_error "cray-cray about destination: ${destination}" + run_host_command_logged find "." -type f "|" grep -e "uboot" -e "u-boot" "|" xargs rm -v + popd } pre_umount_final_image__remove_uboot_initramfs_hook_grub() { @@ -84,6 +91,15 @@ pre_umount_final_image__remove_uboot_initramfs_hook_grub() { } pre_umount_final_image__install_grub() { + if [[ "${UEFI_GRUB}" == "skip" ]]; then + display_alert "Skipping GRUB install" "due to UEFI_GRUB:${UEFI_GRUB}" "debug" + if [[ "${DISTRO_GENERIC_KERNEL}" == "yes" ]]; then + display_alert "Skipping GRUB install" "due to UEFI_GRUB:${UEFI_GRUB} - calling update_initramfs directly" "debug" + VER="generic" update_initramfs "${MOUNT}" + fi + return 0 + fi + configure_grub local chroot_target=$MOUNT display_alert "Installing bootloader" "GRUB" "info" diff --git a/extensions/image-output-qcow2.sh b/extensions/image-output-qcow2.sh index d79505b034..72ade02768 100644 --- a/extensions/image-output-qcow2.sh +++ b/extensions/image-output-qcow2.sh @@ -1,4 +1,4 @@ -add_host_dependencies__ovf_host_deps() { +function add_host_dependencies__qcow2_host_deps() { [[ "${SKIP_QCOW2}" == "yes" ]] && return 0 export EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} qemu-utils" } diff --git a/lib/functions/compilation/uboot.sh b/lib/functions/compilation/uboot.sh index 7ccef1df40..60cc5265bc 100644 --- a/lib/functions/compilation/uboot.sh +++ b/lib/functions/compilation/uboot.sh @@ -237,7 +237,8 @@ function deploy_built_uboot_bins_for_one_target_to_packaging_area() { done } -compile_uboot() { +function compile_uboot() { + display_alert "Compiling u-boot" "BOOTSOURCE: ${BOOTSOURCE}" "debug" if [[ -n $BOOTSOURCE ]] && [[ "${BOOTSOURCE}" != "none" ]]; then display_alert "Downloading sources" "u-boot" "git" GIT_SKIP_SUBMODULES="${UBOOT_GIT_SKIP_SUBMODULES}" fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes" # fetch_from_repo diff --git a/lib/functions/image/partitioning.sh b/lib/functions/image/partitioning.sh index cbba950fa7..8acca242b3 100644 --- a/lib/functions/image/partitioning.sh +++ b/lib/functions/image/partitioning.sh @@ -329,11 +329,22 @@ function prepare_partitions() { fi # recompile .cmd to .scr if boot.cmd exists - if [[ -f $SDCARD/boot/boot.cmd ]]; then - if [ -z $BOOTSCRIPT_OUTPUT ]; then + if [[ -f "${SDCARD}/boot/boot.cmd" ]]; then + if [ -z ${BOOTSCRIPT_OUTPUT} ]; then BOOTSCRIPT_OUTPUT=boot.scr fi - run_host_command_logged mkimage -C none -A arm -T script -d $SDCARD/boot/boot.cmd $SDCARD/boot/${BOOTSCRIPT_OUTPUT} + case ${LINUXFAMILY} in + x86) + : + display_alert "Compiling boot.scr" "boot/${BOOTSCRIPT_OUTPUT} x86" "debug" + run_host_command_logged cat "${SDCARD}/boot/boot.cmd" + run_host_command_logged mkimage -T script -C none -n "'Boot script'" -d "${SDCARD}/boot/boot.cmd" "${SDCARD}/boot/${BOOTSCRIPT_OUTPUT}" + ;; + *) + display_alert "Compiling boot.scr" "boot/${BOOTSCRIPT_OUTPUT} ARM" "debug" + run_host_command_logged mkimage -C none -A arm -T script -d "${SDCARD}/boot/boot.cmd" "${SDCARD}/boot/${BOOTSCRIPT_OUTPUT}" + ;; + esac fi # complement extlinux config if it exists; remove armbianEnv in this case. diff --git a/patch/u-boot/u-boot-qemu-x86/hack_x86_ramdisk_addr_and_boot_virtio_first.patch b/patch/u-boot/u-boot-qemu-x86/hack_x86_ramdisk_addr_and_boot_virtio_first.patch new file mode 100644 index 0000000000..6d0ebdc19b --- /dev/null +++ b/patch/u-boot/u-boot-qemu-x86/hack_x86_ramdisk_addr_and_boot_virtio_first.patch @@ -0,0 +1,46 @@ +Index: include/configs/qemu-x86.h +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h +--- a/include/configs/qemu-x86.h (revision 4debc57a3da6c3f4d3f89a637e99206f4cea0a96) ++++ b/include/configs/qemu-x86.h (date 1669899370752) +@@ -13,10 +13,9 @@ + #include + + #define BOOT_TARGET_DEVICES(func) \ ++ func(VIRTIO, virtio, 0) \ + func(USB, usb, 0) \ + func(SCSI, scsi, 0) \ +- func(VIRTIO, virtio, 0) \ +- func(IDE, ide, 0) \ + func(DHCP, dhcp, na) + + #include +Index: include/configs/x86-common.h +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h +--- a/include/configs/x86-common.h (revision 4debc57a3da6c3f4d3f89a637e99206f4cea0a96) ++++ b/include/configs/x86-common.h (date 1669899456091) +@@ -50,7 +50,7 @@ + /* Default environment */ + #define CONFIG_ROOTPATH "/opt/nfsroot" + #define CONFIG_HOSTNAME "x86" +-#define CONFIG_RAMDISK_ADDR 0x4000000 ++#define CONFIG_RAMDISK_ADDR 0x8000000 + #if defined(CONFIG_GENERATE_ACPI_TABLE) || defined(CONFIG_EFI_STUB) + #define CONFIG_OTHBOOTARGS "othbootargs=\0" + #else +@@ -77,7 +77,7 @@ + CONFIG_OTHBOOTARGS \ + "scriptaddr=0x7000000\0" \ + "kernel_addr_r=0x1000000\0" \ +- "ramdisk_addr_r=0x4000000\0" \ ++ "ramdisk_addr_r=0x8000000\0" \ + "ramdiskfile=initramfs.gz\0" + + diff --git a/patch/u-boot/u-boot-qemu-x86/use_q35_dts_for_qemu-x86_defconfig.patch b/patch/u-boot/u-boot-qemu-x86/use_q35_dts_for_qemu-x86_defconfig.patch new file mode 100644 index 0000000000..9c5024e232 --- /dev/null +++ b/patch/u-boot/u-boot-qemu-x86/use_q35_dts_for_qemu-x86_defconfig.patch @@ -0,0 +1,25 @@ +--- a/configs/qemu-x86_defconfig 2022-12-01 12:44:02.389010874 +0000 ++++ b/configs/qemu-x86_defconfig 2022-12-01 12:52:35.218984706 +0000 +@@ -4,7 +4,7 @@ + CONFIG_NR_DRAM_BANKS=8 + CONFIG_ENV_SIZE=0x40000 + CONFIG_MAX_CPUS=2 +-CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx" ++CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_q35" + CONFIG_SMP=y + CONFIG_GENERATE_PIRQ_TABLE=y + CONFIG_GENERATE_MP_TABLE=y +@@ -50,11 +50,13 @@ + CONFIG_SYS_64BIT_LBA=y + CONFIG_CPU=y + CONFIG_NVME_PCI=y ++CONFIG_DM_RNG=y + CONFIG_SPI=y + CONFIG_USB_KEYBOARD=y + CONFIG_FRAMEBUFFER_SET_VESA_MODE=y + CONFIG_FRAMEBUFFER_VESA_MODE_USER=y + CONFIG_FRAMEBUFFER_VESA_MODE=0x144 + CONFIG_CONSOLE_SCROLL_LINES=5 ++CONFIG_VIRTIO_MMIO=y + CONFIG_GENERATE_ACPI_TABLE=y + # CONFIG_GZIP is not set