146 lines
7.4 KiB
Bash
146 lines
7.4 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# @TODO: rpardini: there's no good reason for this ("grub-sbc-media") to exist. "grub" could be refactored to allow configuration to do the same.
|
|
|
|
# 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-sbc-media() {
|
|
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_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:-3} # Small timeout by default
|
|
declare -g UEFI_GRUB_RECORDFAIL_TIMEOUT=${UEFI_GRUB_RECORDFAIL_TIMEOUT:-3}
|
|
declare -g GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:-}" # Cmdline by default
|
|
declare -g UEFI_ENABLE_BIOS_AMD64="${UEFI_ENABLE_BIOS_AMD64:-no}" # Enable BIOS too if target is amd64
|
|
# User config overrides.
|
|
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_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64
|
|
|
|
# local
|
|
declare -a packages=()
|
|
|
|
packages+=(efibootmgr efivar os-prober "grub-efi-${ARCH}-bin")
|
|
|
|
if [[ "${ARCH}" == "arm64" ]]; then
|
|
packages+=("grub-efi-${ARCH}")
|
|
declare -g UEFI_GRUB_TARGET="arm64-efi" # Default for arm64-efi
|
|
fi
|
|
|
|
add_packages_to_image "${packages[@]}"
|
|
}
|
|
|
|
pre_umount_final_image__install_grub() {
|
|
configure_grub
|
|
local chroot_target=$MOUNT
|
|
display_alert "Installing bootloader" "GRUB" "info"
|
|
|
|
# SBC-MEDIA: copy the dtbs to ESP
|
|
display_alert "Copying DTBs to ESP" "${EXTENSION}" "info"
|
|
run_host_command_logged mkdir -pv "$MOUNT"/boot/efi/dtb
|
|
run_host_command_logged cp -vr "$MOUNT"/boot/dtb/* "$MOUNT"/boot/efi/dtb/
|
|
display_alert "Copying Splash to ESP" "${EXTENSION}" "info"
|
|
run_host_command_logged cp -rv ${SRC}/packages/blobs/splash/grub.png "$MOUNT"/boot/grub
|
|
|
|
# add config to disable os-prober, otherwise image will have the host's other OSes boot entries.
|
|
cat <<- grubCfgFragHostSide >> "${MOUNT}"/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 -v "${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.
|
|
|
|
# SBC-MEDIA specific...
|
|
sed -i '/devicetree/c echo' "$MOUNT"/etc/grub.d/10_linux
|
|
|
|
# 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
|
|
|
|
if [[ $BOARD == jetson-nano ]]; then
|
|
run_host_command_logged cp -v "${SRC}/packages/blobs/jetson/boot.scr" "${MOUNT}"/boot/efi/boot.scr
|
|
fi
|
|
|
|
umount_chroot "$chroot_target/"
|
|
|
|
}
|
|
|
|
configure_grub() {
|
|
[[ -n "$SRC_CMDLINE" ]] &&
|
|
GRUB_CMDLINE_LINUX_DEFAULT+=" ${SRC_CMDLINE}"
|
|
[[ -n "$MAIN_CMDLINE" ]] &&
|
|
GRUB_CMDLINE_LINUX_DEFAULT+=" ${MAIN_CMDLINE}"
|
|
|
|
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_RECORDFAIL_TIMEOUT=${UEFI_GRUB_RECORDFAIL_TIMEOUT}
|
|
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_BACKGROUND="/boot/grub/grub.png"
|
|
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
|
|
}
|