build/extensions/grub-riscv64.sh

147 lines
7.9 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
# This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
function extension_prepare_config__prepare_grub-riscv64() {
display_alert "Prepare config" "${EXTENSION}" "info"
# Extension configuration defaults.
declare -g DISTRO_GENERIC_KERNEL=${DISTRO_GENERIC_KERNEL:-no} # if yes, does not build our own kernel, instead, uses generic one from distro
declare -g UEFI_GRUB_TERMINAL="${UEFI_GRUB_TERMINAL:-serial console}" # 'serial' forces grub menu on serial console. empty to not include
declare -g UEFI_GRUB_DISABLE_OS_PROBER="${UEFI_GRUB_DISABLE_OS_PROBER:-}" # 'true' will disable os-probing, useful for SD cards.
declare -g UEFI_GRUB_DISTRO_NAME="${UEFI_GRUB_DISTRO_NAME:-Armbian}" # Will be used on grub menu display
declare -g UEFI_GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT:-0} # Small timeout by default
declare -g GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:-""}" # Cmdline by default
# User config overrides.
declare -g 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.
declare -g IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff.
declare -g UEFISIZE=256 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions
declare -g BOOTSIZE=0 # No separate /boot when using UEFI.
declare -g CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub.
declare -g EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name.
declare -g UEFI_GRUB_TARGET="riscv64-efi" # Default for x86_64
if [[ "${DISTRIBUTION}" != "Ubuntu" && "${BUILDING_IMAGE}" == "yes" ]]; then
exit_with_error "${DISTRIBUTION} is not supported yet"
fi
add_packages_to_image efibootmgr efivar cloud-initramfs-growroot busybox os-prober "grub-efi-${ARCH}-bin" "grub-efi-${ARCH}"
display_alert "Activating" "GRUB with SERIALCON=${SERIALCON}; timeout ${UEFI_GRUB_TIMEOUT}; target=${UEFI_GRUB_TARGET}" ""
}
pre_umount_final_image__install_grub() {
configure_grub
local chroot_target="${MOUNT}"
display_alert "Installing bootloader" "GRUB" "info"
# RiscV64 specific: actually copy the DTBs to the ESP
display_alert "Copying DTBs to ESP" "${EXTENSION}" "info"
run_host_command_logged mkdir -pv "${chroot_target}"/boot/efi/dtb
run_host_command_logged cp -rpv "${chroot_target}"/boot/dtb/* "${chroot_target}"/boot/efi/dtb/
# RiscV64 specific: @TODO ??? what is this ??
sed -i 's,devicetree,echo,g' "${chroot_target}"/etc/grub.d/10_linux
# add config to disable os-prober, otherwise image will have the host's other OSes boot entries.
cat <<- grubCfgFragHostSide >> "${chroot_target}"/etc/default/grub.d/99-armbian-host-side.cfg
GRUB_DISABLE_OS_PROBER=true
grubCfgFragHostSide
# copy Armbian GRUB wallpaper
run_host_command_logged mkdir -pv "${chroot_target}"/usr/share/images/grub/
run_host_command_logged cp -pv "${SRC}"/packages/blobs/splash/grub.png "${chroot_target}"/usr/share/images/grub/wallpaper.png
# Mount the chroot...
mount_chroot "${chroot_target}/" # this already handles /boot/efi which is required for it to work.
# update-grub is secretly `grub-mkconfig` under wraps, but the actual work is done by /etc/grub.d/10-linux
# that decides based on 'test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}"' so that _must_ exist.
# If it does NOT exist, then a reference to a /dev/devYpX is used, and will fail to boot.
# Irony: let's use grub-probe to find out the UUID of the root partition, and then create a symlink to it.
# Another: on some systems (eg, not Docker) the thing might already exist due to udev actually working.
# shellcheck disable=SC2016 # some wierd escaping going on there.
chroot_custom "$chroot_target" mkdir -pv '/dev/disk/by-uuid/"$(grub-probe --target=fs_uuid /)"' "||" true
display_alert "Creating GRUB config..." "${EXTENSION}: grub-mkconfig / update-grub"
chroot_custom "$chroot_target" update-grub || {
exit_with_error "update-grub failed!"
}
local install_grub_cmdline="grub-install --target=${UEFI_GRUB_TARGET} --no-nvram --removable" # nvram is global to the host, even across chroot. take care.
display_alert "Installing GRUB EFI..." "${EXTENSION}: ${UEFI_GRUB_TARGET}"
chroot_custom "$chroot_target" "$install_grub_cmdline" || {
exit_with_error "${install_grub_cmdline} failed!"
}
### Sanity check. The produced "/boot/grub/grub.cfg" should:
declare -i has_failed_sanity_check=0
# - NOT have any mention of `/dev` inside; otherwise something is going to fail
if grep -q '/dev' "${chroot_target}/boot/grub/grub.cfg"; then
display_alert "GRUB sanity check failed" "grub.cfg contains /dev" "err"
SHOW_LOG=yes run_host_command_logged grep '/dev' "${chroot_target}/boot/grub/grub.cfg" "||" true
has_failed_sanity_check=1
else
display_alert "GRUB config sanity check passed" "no '/dev' found in grub.cfg" "info"
fi
# - HAVE references to initrd, otherwise going to fail.
if ! grep -q 'initrd.img' "${chroot_target}/boot/grub/grub.cfg"; then
display_alert "GRUB config sanity check failed" "no initrd.img references found in /boot/grub/grub.cfg" "err"
has_failed_sanity_check=1
else
display_alert "GRUB config sanity check passed" "initrd.img references found OK in /boot/grub/grub.cfg" "debug"
fi
if [[ ${has_failed_sanity_check} -gt 0 ]]; then
exit_with_error "GRUB config sanity check failed, image will be unbootable; see above errors"
fi
# Remove host-side config.
rm -f "${MOUNT}"/etc/default/grub.d/99-armbian-host-side.cfg
umount_chroot "$chroot_target/"
}
configure_grub() {
[[ -n "$SERIALCON" ]] &&
GRUB_CMDLINE_LINUX_DEFAULT+=" console=${SERIALCON}"
[[ "$BOOT_LOGO" == "yes" || "$BOOT_LOGO" == "desktop" && "$BUILD_DESKTOP" == "yes" ]] &&
GRUB_CMDLINE_LINUX_DEFAULT+=" quiet splash plymouth.ignore-serial-consoles i915.force_probe=* loglevel=3" ||
GRUB_CMDLINE_LINUX_DEFAULT+=" splash=verbose i915.force_probe=*"
# Enable Armbian Wallpaper on GRUB
if [[ "${VENDOR}" == Armbian ]]; then
mkdir -p "${MOUNT}"/usr/share/desktop-base/
cat <<- grubWallpaper >> "${MOUNT}"/usr/share/desktop-base/grub_background.sh
WALLPAPER=/usr/share/images/grub/wallpaper.png
COLOR_NORMAL=white/black
COLOR_HIGHLIGHT=black/white
grubWallpaper
run_host_command_logged chmod -v +x "${MOUNT}"/usr/share/desktop-base/grub_background.sh
fi
display_alert "GRUB EFI kernel cmdline" "'${GRUB_CMDLINE_LINUX_DEFAULT}' distro=${UEFI_GRUB_DISTRO_NAME} timeout=${UEFI_GRUB_TIMEOUT}" ""
cat <<- grubCfgFrag >> "${MOUNT}"/etc/default/grub.d/98-armbian.cfg
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT}"
GRUB_TIMEOUT_STYLE=menu # Show the menu with Kernel options (Armbian or -generic)...
GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT} # ... for ${UEFI_GRUB_TIMEOUT} seconds, then boot the Armbian default.
GRUB_DISTRIBUTOR="${UEFI_GRUB_DISTRO_NAME}" # On GRUB menu will show up as "Armbian GNU/Linux" (will show up in some UEFI BIOS boot menu (F8?) as "armbian", not on others)
GRUB_GFXMODE=1024x768
GRUB_GFXPAYLOAD=keep
grubCfgFrag
if [[ "a${UEFI_GRUB_DISABLE_OS_PROBER}" != "a" ]]; then
cat <<- grubCfgFragHostSide >> "${MOUNT}"/etc/default/grub.d/98-armbian.cfg
GRUB_DISABLE_OS_PROBER=${UEFI_GRUB_DISABLE_OS_PROBER}
grubCfgFragHostSide
fi
if [[ "a${UEFI_GRUB_TERMINAL}" != "a" ]]; then
cat <<- grubCfgFragTerminal >> "${MOUNT}"/etc/default/grub.d/98-armbian.cfg
GRUB_TERMINAL="${UEFI_GRUB_TERMINAL}"
grubCfgFragTerminal
fi
}