This repository has been archived on 2024-09-01. You can view files and clone it, but cannot push or open issues or pull requests.
al-installer/src/lib/boot.sh

234 lines
6.9 KiB
Bash

#!/usr/bin/bash
# vim:ft=sh:fdm=marker:fmr={,}
# shellcheck disable=2034,2154
# archlabs installer library script file
# this file is not meant to be run directly
# sourcing this file in a non bash shell is not advised
# command used to install each bootloader
declare -Ag BCMDS=(
[UEFI-syslinux]='efibootmgr -c -d $BOOT_DEVICE -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST'
[BIOS-syslinux]='syslinux-install_update -iam'
[UEFI-grub]='grub-install --recheck --force --bootloader-id=$DIST && grub-mkconfig -o /boot/grub/grub.cfg'
[BIOS-grub]='grub-install --recheck --force --bootloader-id=$DIST --target=i386-pc $BOOT_DEVICE && grub-mkconfig -o /boot/grub/grub.cfg'
[systemd-boot]='bootctl --path=/boot install'
)
# boot partition mount points for each bootloader
declare -Ag BMNTS=(
[BIOS-grub]="/boot"
[UEFI-grub]="/boot/efi"
[BIOS-syslinux]="/boot"
[UEFI-syslinux]="/boot"
[UEFI-systemd-boot]="/boot"
)
# bootloader options with respective boot partition mountpoint
declare -Ag BOOTLDRS=(
[BIOS]="grub ${BMNTS[BIOS-grub]} syslinux ${BMNTS[BIOS-syslinux]}"
[UEFI]="systemd-boot ${BMNTS[UEFI-systemd-boot]} grub ${BMNTS[UEFI-grub]} syslinux ${BMNTS[UEFI-syslinux]}"
)
pre_grub()
{
FILES[9]="/etc/default/grub"
if [[ $SYS == 'BIOS' && $BOOT_DEVICE == "" ]]; then
select_device 'boot' || return 1
elif [[ $SYS == 'UEFI' && $ROOT_PART =~ /dev/mapper && ! $LVM && ! $LUKS_PASS ]]; then
luks_pass "$_LuksOpen" "$ROOT_PART" || return 1
fi
return 0
}
pre_syslinux()
{
if [[ $SYS == 'BIOS' ]]; then
FILES[9]="/boot/syslinux/syslinux.cfg"
else
FILES[9]="/boot/EFI/syslinux/syslinux.cfg"
fi
}
pre_systemd-boot()
{
FILES[9]="/boot/loader/entries/$DIST.conf"
}
prerun_grub()
{
local cfg="$MNT/etc/default/grub"
sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g;
s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $cfg
if [[ $LUKS_DEV ]]; then
sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $cfg
fi
if [[ $SYS == 'BIOS' && $LVM && $SEPERATE_BOOT == false ]]; then
sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $cfg
fi
# needed for os-prober module to work properly in the chroot
if [[ $SYS == 'UEFI' ]]; then
# mkdir -p /run/lvm $MNT/hostrun/lvm
# mount --bind /run/lvm $MNT/hostrun/lvm
mkdir -p /run/udev $MNT/hostrun/udev
mount --bind /run/udev $MNT/hostrun/udev
BCMDS[grub]="mkdir -p /run/udev &&
mount --bind /hostrun/udev /run/udev &&
${BCMDS[grub]} &&
umount /run/udev"
fi
return 0
}
prerun_systemd-boot()
{
# no LVM then systemd-boot uses PARTUUID
[[ $ROOT_PART =~ /dev/mapper ]] || ROOT_PART_ID="PART$ROOT_PART_ID"
# create the boot entry configs
mkdir -p ${MNT}${BMNTS[$SYS-$BOOTLDR]}/loader/entries
cat > ${MNT}${BMNTS[$SYS-$BOOTLDR]}/loader/loader.conf << EOF
default $DIST
timeout 5
editor no
EOF
cat > ${MNT}${BMNTS[$SYS-$BOOTLDR]}/loader/entries/${DIST}.conf << EOF
title $DIST Linux
linux /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd %s" "/${UCODE}.img")
initrd /initramfs-$KERNEL.img
options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
EOF
# add pacman hook to update the bootloader when systemd receives an update
mkdir -p $MNT/etc/pacman.d/hooks
cat > $MNT/etc/pacman.d/hooks/systemd-boot.hook << EOF
[Trigger]
Type = Package
Operation = Upgrade
Target = systemd
[Action]
Description = Updating systemd-boot
When = PostTransaction
Exec = /usr/bin/bootctl update
EOF
# systemd-boot requires this before running bootctl
systemd-machine-id-setup --root="$MNT" >/dev/null 2>&1
return 0
}
prerun_syslinux()
{
if [[ $SYS == 'UEFI' ]]; then
local cfgdir="${MNT}${BMNTS[$SYS-$BOOTLDR]}/EFI/syslinux"
local cfgsrcdir="/usr/lib/syslinux/efi32/"
[[ $IS_64BIT == true ]] && cfgsrcdir="/usr/lib/syslinux/efi64/"
else
local cfgdir="$MNT${BMNTS[$SYS-$BOOTLDR]}/syslinux"
local cfgsrcdir="/usr/lib/syslinux/bios/"
fi
mkdir -p $cfgdir
cp -r $cfgsrcdir $cfgdir/
cat > $cfgdir/syslinux.cfg << EOF
UI menu.c32
PROMPT 0
MENU TITLE $DIST Syslinux Boot Menu
TIMEOUT 50
DEFAULT $DIST
LABEL $DIST
MENU LABEL $DIST Linux
LINUX ../vmlinuz-$KERNEL
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
INITRD ../initramfs-$KERNEL.img$([[ $UCODE ]] && printf "\nINITRD %s" "../${UCODE}.img")
LABEL ${DIST}fallback
MENU LABEL $DIST Linux Fallback
LINUX ../vmlinuz-$KERNEL
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
INITRD ../initramfs-$KERNEL-fallback.img$([[ $UCODE ]] && printf "\nINITRD %s" "../${UCODE}.img")
EOF
return 0
}
install_bootloader()
{
if ! [[ $ROOT_PART =~ /dev/mapper ]]; then
ROOT_PART_ID="UUID=$(blkid -s PARTUUID -o value $ROOT_PART)"
else
# for LVM we just use the partition label
ROOT_PART_ID="$ROOT_PART"
fi
# remove old UEFI boot entries
if [[ $SYS == 'UEFI' ]]; then
find ${MNT}${BMNTS[$SYS-$BOOTLDR]}/EFI/ \
-maxdepth 1 -mindepth 1 -name '[aA][rR][cC][hH][lL]abs' \
-type d -exec rm -rf '{}' \; >/dev/null 2>&1
fi
prerun_$BOOTLDR
printf "\nInstalling and setting up $BOOTLDR in ${BMNTS[$SYS-$BOOTLDR]}\n\n"
chrun "eval ${BCMDS[$SYS-$BOOTLDR]}"
if [[ -d $MNT/hostrun/udev ]]; then
umount $MNT/hostrun/udev
rm -rf $MNT/hostrun
fi
# copy efi stub to generic catch all
[[ $SYS == 'UEFI' && $BOOTLDR =~ (grub|syslinux) ]] && uefi_boot_fallback
return 0
}
uefi_boot_fallback()
{
# some UEFI firmware requires a dir in the ESP with a generic bootx64.efi
# see: https://wiki.archlinux.org/index.php/GRUB#UEFI
# also: https://wiki.archlinux.org/index.php/syslinux#UEFI_Systems
local esp="${MNT}${BMNTS[$SYS-$BOOTLDR]}"
local default="boot"
default="$(find $esp/EFI/ -maxdepth 1 -mindepth 1 \
-name '[Bb][oO][oO][tT]' -type d)"
[[ $default ]] && default="$(basename $default)"
if [[ -d $esp/EFI/$default ]]; then
rm -rf $esp/EFI/$default/*
else
mkdir -p $esp/EFI/$default
fi
if [[ $BOOTLDR == 'syslinux' ]]; then
cp -rf $esp/EFI/syslinux/* $esp/EFI/$default/
cp -f $esp/EFI/syslinux/syslinux.efi $esp/EFI/$default/bootx64.efi
elif [[ $BOOTLDR == 'grub' && $IS_64BIT == true ]]; then
cp -f $esp/EFI/$DIST/grubx64.efi $esp/EFI/$default/bootx64.efi
elif [[ $BOOTLDR == 'grub' ]]; then
cp -f $esp/EFI/$DIST/grubia32.efi $esp/EFI/$default/bootia32.efi
fi
return 0
}
shim_secure_boot()
{
# still a W.I.P
local shim_file="shim.efi"
[[ $IS_64BIT == true ]] && shim_file="shim64.efi"
efibootmgr -c -w -L $DIST -d $BOOT_DEVICE -p $BOOT_PART_NUM -l ${MNT}${BMNTS[$SYS-$BOOTLDR]}/$shim_file
return 0
}