180 lines
7 KiB
Bash
180 lines
7 KiB
Bash
#!/bin/sh
|
|
|
|
# When installing/updating systemd-boot, if _both_ signed shim and signed systemd-boot are available, and
|
|
# signed grub is not available, then take over the ESP and the EFI boot entry, install systemd-boot as the
|
|
# second stage loader, and install signed shim as the first stage loader and add a boot entry named after
|
|
# the OS vendor pointing to it, and mark it as the default.
|
|
#
|
|
# When triggered, given dpkg does not tell us whether the trigger added or removed a file, if signed
|
|
# grub is available then do nothing and assume it will take over the ESP. If it is not, and either
|
|
# signed shim or signed systemd-boot or both are not available, then remove all of them from the ESP
|
|
# and the EFI boot entry. If both signed shim and signed systemd-boot are available, then update them
|
|
# in the ESP.
|
|
|
|
set -e
|
|
|
|
remove_shim() {
|
|
case "$(dpkg --print-architecture)" in
|
|
amd64)
|
|
efi_arch_upper=X64
|
|
efi_arch=x64
|
|
grub_arch=x86_64
|
|
;;
|
|
arm64)
|
|
efi_arch_upper=AA64
|
|
efi_arch=aa64
|
|
grub_arch=arm64
|
|
;;
|
|
*)
|
|
return
|
|
esac
|
|
|
|
# shellcheck disable=SC1091
|
|
. /etc/os-release || . /usr/lib/os-release
|
|
vendor="${ID:-debian}"
|
|
vendor_upper="$(echo "$vendor" | cut -c1 | tr '[:lower:]' '[:upper:]')$(echo "$vendor" | cut -c2-)"
|
|
|
|
esp_path="$(bootctl --quiet --print-esp-path 2>/dev/null)"
|
|
if [ -z "$esp_path" ]; then
|
|
return
|
|
fi
|
|
|
|
if [ -f "/usr/lib/grub/${grub_arch}-efi-signed/grub${efi_arch}.efi.signed" ]; then
|
|
return
|
|
fi
|
|
|
|
if [ ! -f "${esp_path}/EFI/systemd/systemd-boot${efi_arch}.efi" ]; then
|
|
return
|
|
fi
|
|
|
|
if [ -f "${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi" ] && \
|
|
[ -f "${esp_path}/EFI/${vendor}/shim${efi_arch}.efi" ] && \
|
|
[ "$(<"${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi" sha256sum)" = "$(<"${esp_path}/EFI/${vendor}/shim${efi_arch}.efi" sha256sum)" ]; then
|
|
rm -f "${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi"
|
|
fi
|
|
|
|
if [ -f "${esp_path}/EFI/BOOT/fb${efi_arch_upper}.efi" ] && \
|
|
[ -f "${esp_path}/EFI/${vendor}/fb${efi_arch}.efi" ] && \
|
|
[ "$(<"${esp_path}/EFI/BOOT/fb${efi_arch_upper}.efi" sha256sum)" = "$(<"${esp_path}/EFI/${vendor}/fb${efi_arch}.efi" sha256sum)" ]; then
|
|
rm -f "${esp_path}/EFI/BOOT/fb${efi_arch_upper}.efi"
|
|
fi
|
|
|
|
for f in shim fb mm; do
|
|
rm -f "${esp_path}/EFI/${vendor}/${f}${efi_arch}.efi"
|
|
done
|
|
|
|
rm -f "${esp_path}/EFI/${vendor}/BOOT${efi_arch_upper}.CSV"
|
|
rmdir --ignore-fail-on-non-empty "${esp_path}/EFI/${vendor}" 2>/dev/null || true
|
|
|
|
if command -v efibootmgr >/dev/null 2>&1 && efibootmgr | grep -i -q "Boot.*${vendor_upper}.*EFI\\\\${vendor}\\\\shim${efi_arch}.efi"; then
|
|
bootentry="$(efibootmgr | grep -i "Boot.*${vendor_upper}.*EFI\\\\${vendor}\\\\shim${efi_arch}.efi" | cut -d' ' -f1 | sed -e 's/Boot//' -e 's/*//')"
|
|
efibootmgr -q --delete-bootnum --bootnum "$bootentry"
|
|
fi
|
|
}
|
|
|
|
install_shim() {
|
|
case "$(dpkg --print-architecture)" in
|
|
amd64)
|
|
efi_arch_upper=X64
|
|
efi_arch=x64
|
|
grub_arch=x86_64
|
|
;;
|
|
arm64)
|
|
efi_arch_upper=AA64
|
|
efi_arch=aa64
|
|
grub_arch=arm64
|
|
;;
|
|
*)
|
|
return
|
|
esac
|
|
|
|
if [ ! -f "/usr/lib/shim/shim${efi_arch}.efi.signed" ] || [ ! -f "/usr/lib/systemd/boot/efi/systemd-boot${efi_arch}.efi.signed" ]; then
|
|
if [ "$1" = trigger ]; then
|
|
remove_shim
|
|
fi
|
|
return
|
|
fi
|
|
|
|
if [ -f "/usr/lib/grub/${grub_arch}-efi-signed/grub${efi_arch}.efi.signed" ]; then
|
|
return
|
|
fi
|
|
|
|
esp_path="$(bootctl --quiet --print-esp-path 2>/dev/null)"
|
|
if [ -z "$esp_path" ]; then
|
|
return
|
|
fi
|
|
|
|
# shellcheck disable=SC1091
|
|
. /etc/os-release || . /usr/lib/os-release
|
|
vendor="${ID:-debian}"
|
|
vendor_upper="$(echo "$vendor" | cut -c1 | tr '[:lower:]' '[:upper:]')$(echo "$vendor" | cut -c2-)"
|
|
|
|
for f in shim fb mm; do
|
|
if [ ! -f "/usr/lib/shim/${f}${efi_arch}.efi.signed" ]; then
|
|
continue
|
|
fi
|
|
if [ -f "${esp_path}/EFI/${vendor}/${f}${efi_arch}.efi" ] && [ "$(<"${esp_path}/EFI/${vendor}/${f}${efi_arch}.efi" sha256sum)" = "$(<"/usr/lib/shim/${f}${efi_arch}.efi.signed" sha256sum)" ]; then
|
|
continue
|
|
fi
|
|
install -p -D "/usr/lib/shim/${f}${efi_arch}.efi.signed" "${esp_path}/EFI/${vendor}/${f}${efi_arch}.efi"
|
|
done
|
|
|
|
if [ ! -f "${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi" ] || [ "$(<"${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi" sha256sum)" != "$(<"/usr/lib/shim/shim${efi_arch}.efi.signed" sha256sum)" ]; then
|
|
install -p -D "/usr/lib/shim/shim${efi_arch}.efi.signed" "${esp_path}/EFI/BOOT/BOOT${efi_arch_upper}.efi"
|
|
fi
|
|
|
|
if [ ! -f "${esp_path}/EFI/BOOT/fb${efi_arch}.efi" ] || [ "$(<"${esp_path}/EFI/BOOT/fb${efi_arch}.efi" sha256sum)" != "$(<"/usr/lib/shim/fb${efi_arch}.efi.signed" sha256sum)" ]; then
|
|
install -p -D "/usr/lib/shim/fb${efi_arch}.efi.signed" "${esp_path}/EFI/BOOT/fb${efi_arch}.efi"
|
|
fi
|
|
|
|
if [ ! -f "${esp_path}/EFI/${vendor}/BOOT${efi_arch_upper}.CSV" ] && command -v iconv >/dev/null 2>&1; then
|
|
printf "shim%s.efi,%s,\\\\EFI\\\\systemd\\\\systemd-boot%s.efi \\\\0,This is the boot entry for %s\n" "${efi_arch}" "${vendor_upper}" "${efi_arch}" "${vendor_upper}" | iconv -t UCS-2LE > "${esp_path}/EFI/${vendor}/BOOT${efi_arch_upper}.CSV"
|
|
fi
|
|
|
|
# 730079007300740065006d0064002d0062006f006f007400 is 'systemd-boot' encoded in UTF-16-LE"
|
|
if ! command -v efibootmgr >/dev/null 2>&1; then
|
|
echo "efibootmgr not found, skipping boot entry creation"
|
|
elif ! efibootmgr | grep -i -q "Boot.*${vendor_upper}.*EFI\\\\${vendor}\\\\shim${efi_arch}.efi.*systemd-boot${efi_arch}.efi\|Boot.*${vendor_upper}.*EFI\\\\${vendor}\\\\shim${efi_arch}.efi.*730079007300740065006d0064002d0062006f006f007400"; then
|
|
blkpart="$(findmnt -nvo SOURCE "$esp_path")"
|
|
if [ ! -L "/sys/class/block/${blkpart##*/}" ]; then
|
|
return
|
|
fi
|
|
drive="$(readlink -f "/sys/class/block/${blkpart##*/}")"
|
|
drive="${drive%/*}"
|
|
drive="/dev/${drive##*/}"
|
|
partno="$(cat "/sys/class/block/${blkpart##*/}/partition")"
|
|
efibootmgr -q --create --disk "$drive" --part "$partno" --loader "EFI/${vendor}/shim${efi_arch}.efi" --label "${vendor_upper}" --unicode "\EFI\systemd\systemd-boot${efi_arch}.efi \0"
|
|
fi
|
|
}
|
|
|
|
if [ "$1" = configure ] && bootctl --print-esp-path > /dev/null 2>&1; then
|
|
if bootctl is-installed > /dev/null 2>&1; then
|
|
bootctl update --graceful
|
|
else
|
|
bootctl install --make-machine-id-directory=auto
|
|
fi
|
|
install_shim install
|
|
|
|
if [ -z "$2" ]; then
|
|
# register existing kernel(s)
|
|
for k in /boot/vmlinuz-* ; do
|
|
[ -f "$k" ] || continue
|
|
ver=$(basename "$k" | sed s/^vmlinuz-//)
|
|
kernel-install add "$ver" "$k"
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [ "$1" = triggered ]; then
|
|
shift
|
|
for trigger in "$@"; do
|
|
case $trigger in
|
|
/usr/lib/shim|/usr/lib/grub|systemd-boot-signed)
|
|
install_shim trigger
|
|
;;
|
|
esac
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
#DEBHELPER#
|