c1b1534c87
Without this change DIB appends a second command line entry to the GRUB config. This causes the original command line entry to be ignored when Linux is booted. The expected behaviour is that DIB appends to the existing entry as it does for Ubuntu and SUSE. Following discussion on the review, this also removes the distro specific switch statement, as update-grub just calls grub-mkconfig, meaning that there was nothing distro specific in the first place. Change-Id: I2298675dda1f699c572b3423e7274bc8bd7c1c9d Closes-Bug: #1771366
234 lines
8.2 KiB
Bash
Executable file
234 lines
8.2 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Configure grub. Note that the various conditionals here are to handle
|
|
# different distributions gracefully.
|
|
|
|
if [ ${DIB_DEBUG_TRACE:-1} -gt 0 ]; then
|
|
set -x
|
|
fi
|
|
set -eu
|
|
set -o pipefail
|
|
|
|
BOOT_DEV=$IMAGE_BLOCK_DEVICE
|
|
|
|
# All available devices, handy for some bootloaders...
|
|
declare -A DEVICES
|
|
eval DEVICES=( $IMAGE_BLOCK_DEVICES )
|
|
|
|
function install_extlinux {
|
|
install-packages -m bootloader extlinux
|
|
|
|
echo "Installing Extlinux..."
|
|
|
|
# Find and install mbr.bin
|
|
for MBR in /usr/share/syslinux/mbr.bin /usr/lib/syslinux/mbr.bin \
|
|
/usr/lib/extlinux/mbr.bin /usr/lib/EXTLINUX/mbr.bin ; do
|
|
if [ -f $MBR ]; then
|
|
break
|
|
fi
|
|
done
|
|
if [ ! -f $MBR ]; then
|
|
echo "mbr.bin (from EXT/SYSLINUX) not found."
|
|
exit 1
|
|
fi
|
|
|
|
dd if=$MBR of=$BOOT_DEV
|
|
|
|
# Find any pre-created extlinux install directory
|
|
for EXTDIR in /boot/extlinux /boot/syslinux ; do
|
|
if [ -d $EXTDIR ] ; then
|
|
break
|
|
fi
|
|
done
|
|
if [ ! -d $EXTDIR ] ; then
|
|
# No install directory found so default to /boot/syslinux
|
|
EXTDIR=/boot/syslinux
|
|
mkdir -p $EXTDIR
|
|
fi
|
|
|
|
# Finally install extlinux
|
|
extlinux --install $EXTDIR
|
|
}
|
|
|
|
function install_grub2 {
|
|
|
|
# Check for offline installation of grub
|
|
if [ -f "/tmp/grub/install" ] ; then
|
|
source /tmp/grub/install
|
|
|
|
# Right now we can't use pkg-map to branch by arch, so tag an
|
|
# architecture specific virtual package so we can install the
|
|
# rigth thing based on distribution.
|
|
elif [[ "$ARCH" =~ "ppc" ]]; then
|
|
install-packages -m bootloader grub-ppc64
|
|
elif [[ "${DIB_BLOCK_DEVICE}" == "mbr" ||
|
|
"${DIB_BLOCK_DEVICE}" == "gpt" ]]; then
|
|
install-packages -m bootloader grub-pc
|
|
elif [[ "${DIB_BLOCK_DEVICE}" == "efi" ]]; then
|
|
install-packages -m bootloader grub-efi-$ARCH
|
|
else
|
|
echo "Failure: I'm not sure what bootloader to install"
|
|
echo "Ensure you have included a block-device-* element"
|
|
exit 1
|
|
fi
|
|
|
|
# XXX: grub-probe on the nbd0/loop0 device returns nothing - workaround, manually
|
|
# specify modules. https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1073731
|
|
GRUBNAME=$(type -p grub-install) || echo "trying grub2-install"
|
|
if [ -z "$GRUBNAME" ]; then
|
|
GRUBNAME=$(type -p grub2-install)
|
|
fi
|
|
|
|
# If no GRUB2 is found, fallback to extlinux
|
|
if [ -z "$GRUBNAME" ] || [ $($GRUBNAME --version | grep "0.97" | wc -l) -ne 0 ]; then
|
|
echo "No GRUB2 found. Fallback to Extlinux..."
|
|
install_extlinux
|
|
exit 0
|
|
fi
|
|
|
|
echo "Installing GRUB2..."
|
|
|
|
# We need --force so grub does not fail due to being installed on the
|
|
# root partition of a block device.
|
|
GRUB_OPTS=${GRUB_OPTS:-"--force"}
|
|
# XXX: This is buggy:
|
|
# - --target=i386-pc is invalid for non-i386/amd64 architectures
|
|
# - and for UEFI too.
|
|
# GRUB_OPTS="$GRUB_OPTS --target=i386-pc"
|
|
if [[ ! $GRUB_OPTS == *--target* ]] && [[ $($GRUBNAME --version) =~ ' 2.' ]]; then
|
|
# /sys/ comes from the host machine. If the host machine is using EFI
|
|
# but the image being built doesn't have EFI boot-images installed we
|
|
# should set the --target to use a BIOS-based boot-image.
|
|
#
|
|
# * --target tells grub what's the target platform
|
|
# * the boot images are placed in /usr/lib/grub/<cpu>-<platform>
|
|
# * i386-pc is used for BIOS-based machines
|
|
# http://www.gnu.org/software/grub/manual/grub.html#Installation
|
|
#
|
|
if [ -d /sys/firmware/efi ]; then
|
|
if [ ! -d /usr/lib/grub/*-efi ]; then
|
|
case $ARCH in
|
|
"x86_64"|"amd64")
|
|
GRUB_OPTS="$GRUB_OPTS --target=i386-pc"
|
|
;;
|
|
"i386")
|
|
target=i386-pc
|
|
if [ -e /proc/device-tree ]; then
|
|
for x in /proc/device-tree/*; do
|
|
if [ -e "$x" ]; then
|
|
target="i386-ieee1275"
|
|
fi
|
|
done
|
|
fi
|
|
GRUB_OPTS="$GRUB_OPTS --target=$target"
|
|
;;
|
|
esac
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [[ "$ARCH" =~ "ppc" ]] ; then
|
|
# For PPC (64-Bit regardless of Endian-ness), we use the "boot"
|
|
# partition as the one to point grub-install to, not the loopback
|
|
# device. ppc has a dedicated PReP boot partition.
|
|
# For grub2 < 2.02~beta3 this needs to be a /dev/mapper/... node after
|
|
# that a dev/loopXpN node will work fine.
|
|
$GRUBNAME --modules="part_msdos" $GRUB_OPTS ${DEVICES[boot]} --no-nvram
|
|
else
|
|
# This set of modules is sufficient for all installs (mbr/gpt/efi)
|
|
modules="part_msdos part_gpt lvm"
|
|
extra_options=""
|
|
if [[ ${DIB_BLOCK_DEVICE} == "mbr" || ${DIB_BLOCK_DEVICE} == "gpt" ]]; then
|
|
modules="$modules biosdisk"
|
|
elif [[ ${DIB_BLOCK_DEVICE} == "efi" ]]; then
|
|
# This tells the EFI install to put the EFI binaries into
|
|
# the generic /BOOT directory and avoids trying to update
|
|
# nvram settings.
|
|
extra_options="--removable"
|
|
# We need to manually set the target if it's different to
|
|
# the host. Setup for EFI
|
|
case $ARCH in
|
|
"x86_64"|"amd64")
|
|
GRUB_OPTS="--target=x86_64-efi"
|
|
;;
|
|
# At this point, we don't need to override the target
|
|
# for any other architectures.
|
|
esac
|
|
fi
|
|
$GRUBNAME --modules="$modules" $extra_options $GRUB_OPTS $BOOT_DEV
|
|
fi
|
|
|
|
# This might be better factored out into a per-distro 'install-bootblock'
|
|
# helper.
|
|
if [ -d /boot/grub2 ]; then
|
|
GRUB_CFG=/boot/grub2/grub.cfg
|
|
elif [ -d /boot/grub ]; then
|
|
GRUB_CFG=/boot/grub/grub.cfg
|
|
fi
|
|
|
|
# Override the root device to the default label, and disable uuid
|
|
# lookup.
|
|
echo "GRUB_DEVICE=LABEL=${DIB_ROOT_LABEL}" >> /etc/default/grub
|
|
echo 'GRUB_DISABLE_LINUX_UUID=true' >> /etc/default/grub
|
|
echo "GRUB_TIMEOUT=${DIB_GRUB_TIMEOUT:-5}" >>/etc/default/grub
|
|
echo 'GRUB_TERMINAL="serial console"' >>/etc/default/grub
|
|
echo 'GRUB_GFXPAYLOAD_LINUX=auto' >>/etc/default/grub
|
|
|
|
# Serial console on Power is hvc0
|
|
if [[ "powerpc ppc64 ppc64le" =~ "$ARCH" ]]; then
|
|
SERIAL_CONSOLE="hvc0"
|
|
elif [[ "arm64" =~ "$ARCH" ]]; then
|
|
SERIAL_CONSOLE="ttyAMA0,115200"
|
|
else
|
|
SERIAL_CONSOLE="ttyS0,115200"
|
|
fi
|
|
|
|
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=${SERIAL_CONSOLE} no_timer_check"
|
|
|
|
echo "GRUB_CMDLINE_LINUX_DEFAULT=\"${GRUB_CMDLINE_LINUX_DEFAULT}\"" >>/etc/default/grub
|
|
echo 'GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"' >>/etc/default/grub
|
|
sed -i -e "s/\(^GRUB_CMDLINE_LINUX.*\)\"$/\1 ${DIB_BOOTLOADER_DEFAULT_CMDLINE}\"/" /etc/default/grub
|
|
|
|
if type grub2-mkconfig >/dev/null; then
|
|
GRUB_MKCONFIG="grub2-mkconfig -o $GRUB_CFG"
|
|
else
|
|
GRUB_MKCONFIG="grub-mkconfig -o $GRUB_CFG"
|
|
fi
|
|
|
|
# os-prober leaks /dev/sda into config file in dual-boot host
|
|
# Disable grub-os-prober to avoid the issue while running
|
|
# grub-mkconfig
|
|
# Setting a flag to track whether the entry is already there in grub config
|
|
PROBER_DISABLED=
|
|
if ! grep -qe "^\s*GRUB_DISABLE_OS_PROBER=true" /etc/default/grub; then
|
|
PROBER_DISABLED=true
|
|
echo 'GRUB_DISABLE_OS_PROBER=true' >> /etc/default/grub
|
|
fi
|
|
|
|
$GRUB_MKCONFIG
|
|
|
|
# Remove the fix to disable os_prober
|
|
if [ -n "$PROBER_DISABLED" ]; then
|
|
sed -i '$d' /etc/default/grub
|
|
fi
|
|
|
|
# grub-mkconfig generates a config with the device in it,
|
|
# This shouldn't be needed, but old code has bugs
|
|
DIB_RELEASE=${DIB_RELEASE:-}
|
|
if [ "$DIB_RELEASE" = 'wheezy' ]; then
|
|
sed -i "s%search --no.*%%" $GRUB_CFG
|
|
sed -i "s%set root=.*%set root=(hd0,1)%" $GRUB_CFG
|
|
fi
|
|
|
|
# Fix efi specific instructions in grub config file
|
|
if [ -d /sys/firmware/efi ]; then
|
|
sed -i 's%\(initrd\|linux\)efi /boot%\1 /boot%g' $GRUB_CFG
|
|
fi
|
|
}
|
|
|
|
DIB_EXTLINUX=${DIB_EXTLINUX:-0}
|
|
if [ "$DIB_EXTLINUX" != "0" ]; then
|
|
install_extlinux
|
|
else
|
|
install_grub2
|
|
fi
|