diff --git a/.github/workflows/matrix.json b/.github/workflows/matrix.json index 1c816041f..135563d72 100644 --- a/.github/workflows/matrix.json +++ b/.github/workflows/matrix.json @@ -11,6 +11,12 @@ "runner": "x86-64-runner", "label": "board/generic-x86-64" }, + { + "id": "generic-aarch64", + "defconfig": "generic_aarch64", + "runner": "aarch64-runner", + "label": "board/generic-aarch64" + }, { "id": "khadas-vim3", "defconfig": "khadas_vim3", diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 54fb6475a..5860c5925 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -119,7 +119,7 @@ jobs: asset_content_type: application/x-tar - name: Upload qcow2 image - if: ${{ matrix.board.name == 'ova' }} + if: ${{ matrix.board.name == 'ova' || matrix.board.name == 'generic-aarch64' }} uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -152,7 +152,7 @@ jobs: asset_content_type: application/zip - name: Upload vmdk image - if: ${{ matrix.board.name == 'ova' }} + if: ${{ matrix.board.name == 'ova' || matrix.board.name == 'generic-aarch64' }} uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Documentation/boards/generic-aarch64/README.md b/Documentation/boards/generic-aarch64/README.md new file mode 100644 index 000000000..8cf8e9f8e --- /dev/null +++ b/Documentation/boards/generic-aarch64/README.md @@ -0,0 +1,36 @@ +# Generic aarch64 + +## Supported Hardware + +This board configuration aims to support most aarch64 systems with UEFI boot +Hardware it has been tested with is listed below. + +## Tested Hardware + +| Device | Release Date | Support | Config | +|-----------------------|--------------|---------|-------------| +| QEMU | QEMU | yes | [generic_aarch64](../../../buildroot-external/configs/generic_aarch64_defconfig) | + + +## Requirements + +- aarch64 support +- UEFI boot + +## Wifi + +WiFi is untested. + +## Bluetooth + +Bluetooth is untested. + +## Installation + +Make sure secure boot is disabled in the UEFI BIOS settings. + +Currently there is no shiny installation method. Checklist: +- Boot PC to live environment using PXE or USB +- Copy or download the Home Assistant OS image into your live environment +- unxz the image and dd to the local hard disk +- Reboot diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/cmdline.txt b/buildroot-external/board/arm-uefi/generic-aarch64/cmdline.txt new file mode 100644 index 000000000..5f4472675 --- /dev/null +++ b/buildroot-external/board/arm-uefi/generic-aarch64/cmdline.txt @@ -0,0 +1 @@ +cmdline="" diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/grub.cfg b/buildroot-external/board/arm-uefi/generic-aarch64/grub.cfg new file mode 100644 index 000000000..bf92b1bfe --- /dev/null +++ b/buildroot-external/board/arm-uefi/generic-aarch64/grub.cfg @@ -0,0 +1,59 @@ +set default=99 +set timeout=5 + +set ORDER="A B" +set A_OK=0 +set B_OK=0 +set A_TRY=0 +set B_TRY=0 +set MACHINE_ID="" +load_env + +# select bootable slot +for SLOT in $ORDER; do + if [ "$SLOT" == "A" ]; then + INDEX=0 + OK=$A_OK + TRY=$A_TRY + A_TRY=1 + fi + if [ "$SLOT" == "B" ]; then + INDEX=1 + OK=$B_OK + TRY=$B_TRY + B_TRY=1 + fi + if [ "$OK" -eq 1 -a "$TRY" -eq 0 ]; then + default=$INDEX + break + fi +done + +# reset booted flags +if [ "$default" -eq 99 ]; then + if [ "$A_OK" -eq 1 -a "$A_TRY" -eq 1 ]; then + A_TRY=0 + fi + if [ "$B_OK" -eq 1 -a "$B_TRY" -eq 1 ]; then + B_TRY=0 + fi + default=0 +fi + +save_env A_TRY A_OK B_TRY B_OK ORDER MACHINE_ID + +default_cmdline="rootwait zram.enabled=1 zram.num_devices=3 apparmor=1 security=apparmor systemd.machine_id=$MACHINE_ID cgroup_enable=memory fsck.repair=yes" +source ($root)/cmdline.txt + +# root is a full HDD/partition definition in GRUB format like hd0,gpt1 +# We extract the part before the comma to then append our own partition index +# at the end. This is hacky but the best way I found +regexp --set 1:boothd (.+),.+ ${root} + +menuentry "Slot A (OK=$A_OK TRY=$A_TRY)" { + linux (${boothd},gpt2)/Image root=PARTUUID=8d3d53e3-6d49-4c38-8349-aff6859e82fd $default_cmdline $cmdline rauc.slot=A +} + +menuentry "Slot B (OK=$B_OK TRY=$B_TRY)" { + linux (${boothd},gpt4)/Image root=PARTUUID=a3ec664e-32ce-4665-95ea-7ae90ce9aa20 $default_cmdline $cmdline rauc.slot=B +} diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/hassos-hook.sh b/buildroot-external/board/arm-uefi/generic-aarch64/hassos-hook.sh new file mode 100755 index 000000000..b67b6322b --- /dev/null +++ b/buildroot-external/board/arm-uefi/generic-aarch64/hassos-hook.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# shellcheck disable=SC2155 + +function hassos_pre_image() { + local BOOT_DATA="$(path_boot_dir)" + local EFIPART_DATA="${BINARIES_DIR}/efi-part" + + mkdir -p "${BOOT_DATA}/EFI/BOOT" + + cp "${BOARD_DIR}/grub.cfg" "${EFIPART_DATA}/EFI/BOOT/grub.cfg" + cp "${BOARD_DIR}/cmdline.txt" "${EFIPART_DATA}/cmdline.txt" + grub-editenv "${EFIPART_DATA}/EFI/BOOT/grubenv" create + + cp -r "${EFIPART_DATA}/"* "${BOOT_DATA}/" +} + + +function hassos_post_image() { + convert_disk_image_virtual vmdk + convert_disk_image_virtual qcow2 + + convert_disk_image_zip vmdk + convert_disk_image_xz qcow2 + + convert_disk_image_xz +} + diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/kernel.config b/buildroot-external/board/arm-uefi/generic-aarch64/kernel.config new file mode 100644 index 000000000..e05f1da2d --- /dev/null +++ b/buildroot-external/board/arm-uefi/generic-aarch64/kernel.config @@ -0,0 +1,16 @@ +CONFIG_EFI_STUB=y + +CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_NET=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_BLK_SCSI=y +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_MMIO=y +CONFIG_SCSI_VIRTIO=y +CONFIG_HW_RANDOM_VIRTIO=y + +CONFIG_DRM_VIRTIO_GPU=m diff --git a/buildroot-external/board/arm-uefi/generic-aarch64/meta b/buildroot-external/board/arm-uefi/generic-aarch64/meta new file mode 100644 index 000000000..52c938087 --- /dev/null +++ b/buildroot-external/board/arm-uefi/generic-aarch64/meta @@ -0,0 +1,10 @@ +BOARD_ID=generic-aarch64 +BOARD_NAME="Generic aarch64" +CHASSIS=embedded +BOOTLOADER=grub +KERNEL_FILE=Image +BOOT_SYS=efi +BOOT_SPL=false +DISK_SIZE=6 +SUPERVISOR_MACHINE=qemuarm-64 +SUPERVISOR_ARCH=aarch64 diff --git a/buildroot-external/board/pc/ova/hassos-hook.sh b/buildroot-external/board/pc/ova/hassos-hook.sh index 4f2278a9c..24fe6e923 100755 --- a/buildroot-external/board/pc/ova/hassos-hook.sh +++ b/buildroot-external/board/pc/ova/hassos-hook.sh @@ -17,7 +17,10 @@ function hassos_post_image() { local hdd_img="$(hassos_image_name img)" # Virtual Disk images - convert_disk_image_virtual + convert_disk_image_virtual vmdk + convert_disk_image_virtual vhdx + convert_disk_image_virtual vdi + convert_disk_image_virtual qcow2 convert_disk_image_zip vmdk convert_disk_image_zip vhdx diff --git a/buildroot-external/configs/generic_aarch64_defconfig b/buildroot-external/configs/generic_aarch64_defconfig new file mode 100644 index 000000000..f92ca769f --- /dev/null +++ b/buildroot-external/configs/generic_aarch64_defconfig @@ -0,0 +1,140 @@ + +# Architecture +BR2_aarch64=y +BR2_ARM_FPU_FP_ARMV8=y + +# Misc +BR2_SYSTEM_DHCP="eth0" +BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_HASSOS_PATH)/scripts/post-image.sh" +BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_HASSOS_PATH)/board/arm-uefi/generic-aarch64 $(BR2_EXTERNAL_HASSOS_PATH)/board/arm-uefi/generic-aarch64/hassos-hook.sh" + +# Needed for grub2 +BR2_TOOLCHAIN_BUILDROOT_WCHAR=y + +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_MTOOLS=y + +BR2_DL_DIR="/cache/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="/cache/cc" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_HASSOS_PATH)/patches $(BR2_EXTERNAL_HASSOS_PATH)/board/pc/patches" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_GCC_VERSION_9_X=y +BR2_OPTIMIZE_2=y +BR2_SSP_REGULAR=y +BR2_SSP_OPTION="-fstack-protector" +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_BINUTILS_ENABLE_LTO=y +BR2_GCC_ENABLE_LTO=y +BR2_TARGET_GENERIC_HOSTNAME="homeassistant" +BR2_TARGET_GENERIC_ISSUE="Welcome to Home Assistant" +BR2_INIT_SYSTEMD=y +# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_HASSOS_PATH)/rootfs-overlay" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_VERSION=y +BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.10.98" +BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y +BR2_LINUX_KERNEL_USE_DEFCONFIG=n +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_HASSOS_PATH)/kernel/hassos.config $(BR2_EXTERNAL_HASSOS_PATH)/kernel/docker.config $(BR2_EXTERNAL_HASSOS_PATH)/kernel/device-support.config $(BR2_EXTERNAL_HASSOS_PATH)/board/arm-uefi/generic-aarch64/kernel.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y +BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_10=y +BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_HASSOS_PATH)/busybox.config" +BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y +BR2_PACKAGE_PROCPS_NG=y +BR2_PACKAGE_JQ=y +BR2_PACKAGE_E2FSPROGS=y +BR2_PACKAGE_E2FSPROGS_E2IMAGE=y +BR2_PACKAGE_SQUASHFS=y +BR2_PACKAGE_OS_AGENT=y +BR2_PACKAGE_UDISKS2=y +# BR2_PACKAGE_LVM2_STANDARD_INSTALL is not set +BR2_PACKAGE_LINUX_FIRMWARE=y +BR2_PACKAGE_LINUX_FIRMWARE_BNX2=y +BR2_PACKAGE_LINUX_FIRMWARE_BNX2X=y +BR2_PACKAGE_LINUX_FIRMWARE_IBT=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_22260=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_3160=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_3168=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_5000=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_6000G2A=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_6000G2B=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_7260=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_7265=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_7265D=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_8000C=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_8265=y +BR2_PACKAGE_LINUX_FIRMWARE_IWLWIFI_9XXX=y +BR2_PACKAGE_LINUX_FIRMWARE_I915=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT73=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_8169=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_USB_NIC_RTL_815X=y +BR2_PACKAGE_LINUX_FIRMWARE_USB_SERIAL_TI=y +BR2_PACKAGE_DT_UTILS=y +BR2_PACKAGE_GPTFDISK=y +BR2_PACKAGE_GPTFDISK_SGDISK=y +BR2_PACKAGE_CA_CERTIFICATES=y +BR2_PACKAGE_LIBCGROUP=y +BR2_PACKAGE_LIBCGROUP_TOOLS=y +BR2_PACKAGE_BLUEZ5_UTILS=y +BR2_PACKAGE_BLUEZ5_UTILS_CLIENT=y +BR2_PACKAGE_BLUEZ5_UTILS_TOOLS=y +BR2_PACKAGE_DHCP=y +BR2_PACKAGE_DHCP_CLIENT=y +BR2_PACKAGE_WIREGUARD_LINUX_COMPAT=y +BR2_PACKAGE_DROPBEAR=y +BR2_PACKAGE_DROPBEAR_CLIENT=y +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +BR2_PACKAGE_NETWORK_MANAGER=y +BR2_PACKAGE_WIRELESS_REGDB=y +BR2_PACKAGE_TINI=y +BR2_PACKAGE_DOCKER_ENGINE=y +BR2_PACKAGE_DOCKER_CLI=y +BR2_PACKAGE_OPENVMTOOLS=y +BR2_PACKAGE_RAUC=y +BR2_PACKAGE_RAUC_NETWORK=y +BR2_PACKAGE_RNG_TOOLS=y +# BR2_PACKAGE_SYSTEMD_HWDB is not set +# BR2_PACKAGE_SYSTEMD_NETWORKD is not set +BR2_PACKAGE_SYSTEMD_RANDOMSEED=y +BR2_PACKAGE_SYSTEMD_RESOLVED=y +BR2_PACKAGE_SYSTEMD_COREDUMP=y +BR2_PACKAGE_SYSTEMD_JOURNAL_REMOTE=y +BR2_PACKAGE_SYSTEMD_LOGIND=y +BR2_PACKAGE_UTIL_LINUX_PARTX=y +BR2_PACKAGE_UTIL_LINUX_ZRAMCTL=y +BR2_PACKAGE_UTIL_LINUX_LOGIN=y +BR2_PACKAGE_UTIL_LINUX_NOLOGIN=y +BR2_PACKAGE_UTIL_LINUX_SULOGIN=y +BR2_PACKAGE_USB_MODESWITCH=y +BR2_PACKAGE_USB_MODESWITCH_DATA=y +BR2_PACKAGE_HOST_E2FSPROGS=y +BR2_PACKAGE_HOST_GPTFDISK=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HASSIO=y +BR2_PACKAGE_HASSIO_ARCH="aarch64" +BR2_PACKAGE_HASSIO_MACHINE="qemuarm-64" +BR2_PACKAGE_APPARMOR=y +BR2_PACKAGE_APPARMOR_PROFILES=y +BR2_PACKAGE_LIBCURL_CURL=y +BR2_PACKAGE_DOSFSTOOLS=y +BR2_PACKAGE_DOSFSTOOLS_FSCK_FAT=y +BR2_PACKAGE_RPI_RF_MOD=y + +# Bootloader +BR2_TARGET_GRUB2=y +BR2_TARGET_GRUB2_ARM64_EFI=y +BR2_TARGET_GRUB2_BUILTIN_MODULES="boot linux ext2 fat squash4 part_msdos part_gpt normal efi_gop regexp loadenv echo cat test configfile" +BR2_TARGET_GRUB2_INSTALL_TOOLS=y + +# Filesystem image +BR2_TARGET_ROOTFS_SQUASHFS=y +# BR2_TARGET_ROOTFS_TAR is not set diff --git a/buildroot-external/rootfs-overlay/usr/libexec/hassos-persists b/buildroot-external/rootfs-overlay/usr/libexec/hassos-persists index 305cdc95e..df8dbe62b 100755 --- a/buildroot-external/rootfs-overlay/usr/libexec/hassos-persists +++ b/buildroot-external/rootfs-overlay/usr/libexec/hassos-persists @@ -15,6 +15,18 @@ if [ -e /usr/sbin/fw_setenv ]; then echo "[INFO] machine-id is okay" fi +### +# GRUB +elif [ -e /usr/bin/grub-editenv ]; then + GRUBENV_FILE="$(grep '^grubenv=' < /etc/rauc/system.conf | cut -d= -f2)" + # machine-id + if [ "$(/usr/bin/grub-editenv "$GRUBENV_FILE" list | grep '^MACHINE_ID=' | cut -d= -f2)" != "${MACHINE_ID}" ]; then + echo "[INFO] set machine-id to ${MACHINE_ID}" + /usr/bin/grub-editenv "$GRUBENV_FILE" set "MACHINE_ID=${MACHINE_ID}" + else + echo "[INFO] machine-id is okay" + fi + ### # Barebox else diff --git a/buildroot-external/scripts/hdd-image.sh b/buildroot-external/scripts/hdd-image.sh index 4ae46a8f3..3d7a90135 100755 --- a/buildroot-external/scripts/hdd-image.sh +++ b/buildroot-external/scripts/hdd-image.sh @@ -293,21 +293,18 @@ function _fix_disk_spl_mbr() { function convert_disk_image_virtual() { + local hdd_ext="${1}" local hdd_img="$(hassos_image_name img)" - local hdd_vmdk="$(hassos_image_name vmdk)" - local hdd_vhdx="$(hassos_image_name vhdx)" - local hdd_vdi="$(hassos_image_name vdi)" - local hdd_qcow2="$(hassos_image_name qcow2)" + local hdd_virt="$(hassos_image_name "${hdd_ext}")" + local -a qemu_img_opts=() - rm -f "${hdd_vmdk}" - rm -f "${hdd_vhdx}" - rm -f "${hdd_vdi}" - rm -f "${hdd_qcow2}" + if [ "${hdd_ext}" == "vmdk" ]; then + qemu_img_opts=("-o" "adapter_type=lsilogic") + fi - qemu-img convert -O vmdk -o adapter_type=lsilogic "${hdd_img}" "${hdd_vmdk}" - qemu-img convert -O vhdx "${hdd_img}" "${hdd_vhdx}" - qemu-img convert -O vdi "${hdd_img}" "${hdd_vdi}" - qemu-img convert -O qcow2 "${hdd_img}" "${hdd_qcow2}" + rm -f "${hdd_virt}" + + qemu-img convert -O "${hdd_ext}" "${qemu_img_opts[@]}" "${hdd_img}" "${hdd_virt}" } function convert_disk_image_ova() { diff --git a/buildroot-external/scripts/rauc.sh b/buildroot-external/scripts/rauc.sh index 3be7c110d..dd9b8ca33 100755 --- a/buildroot-external/scripts/rauc.sh +++ b/buildroot-external/scripts/rauc.sh @@ -8,7 +8,14 @@ function _create_rauc_header() { echo "mountprefix=/run/rauc" echo "statusfile=/mnt/data/rauc.db" echo "bootloader=${BOOTLOADER}" - + if [ "${BOOTLOADER}" == "grub" ]; then + if [ "${BOOT_SYS}" == "efi" ]; then + echo "grubenv=/mnt/boot/EFI/BOOT/grubenv" + else + echo "grubenv=/mnt/boot/grubenv" + fi + fi + echo "[keyring]" echo "path=/etc/rauc/keyring.pem" ) > "${TARGET_DIR}/etc/rauc/system.conf" @@ -77,7 +84,7 @@ function install_bootloader_config() { if [ "${BOOTLOADER}" == "uboot" ]; then # shellcheck disable=SC1117 echo -e "/dev/disk/by-partlabel/hassos-bootstate\t0x0000\t${BOOT_ENV_SIZE}" > "${TARGET_DIR}/etc/fw_env.config" - else + elif [ "${BOOTLOADER}" == "barebox" ]; then cp -f "${BR2_EXTERNAL_HASSOS_PATH}/bootloader/barebox-state-efi.dtb" "${TARGET_DIR}/etc/barebox-state.dtb" fi