Files
molecules/scripts/make_grub_efi.sh
2012-12-03 23:38:26 +01:00

143 lines
4.8 KiB
Bash
Executable File

#!/bin/bash
# Expected env variables:
# CHROOT_DIR
# CDROOT_DIR
# This scripts generates an EFI-enabled boot structure
# Path to molecules.git dir
SABAYON_MOLECULE_HOME="${SABAYON_MOLECULE_HOME:-/sabayon}"
export SABAYON_MOLECULE_HOME
MOUNT_DIRS=()
EFI_BOOT_DIR="${CDROOT_DIR}/efi/boot"
# This is not /boot/grub for a very good reason:
# Our Live media uses /boot/sabayon instead of /boot/grub
# and this has also the side effect that we can put
# /boot/sabayon into the EFI Boot Partition avoiding
# name clashing. Our /boot/sabayon inside that partition
# will contain a simple grub.cfg doing two things:
#
# 1. set the correct prefix to the real grub boot partition
# (via set prefix=(hdX,X)/boot/grub
# 2. load the real grub.cfg file (via configfile (hdX,X)/...)
#
# In this way, we can ship a SecureBoot signed grubx64.efi
# file and have it working with all the partition layouts.
# The "bootstrap" grub.cfg file is created by our scripts
# that are sourced by grub-mkconfig.
GRUB_BOOT_DIR_PREFIX="/boot/sabayon"
GRUB_LOCALE_DIR_PREFIX="${GRUB_BOOT_DIR_PREFIX}/locale"
GRUB_BOOT_DIR="${CDROOT_DIR}${GRUB_BOOT_DIR_PREFIX}"
GRUB_LOCALE_DIR="${CDROOT_DIR}${GRUB_LOCALE_DIR_PREFIX}"
mkdir -p "${EFI_BOOT_DIR}" || exit 1
mkdir -p "${GRUB_BOOT_DIR}" || exit 1
mkdir -p "${GRUB_LOCALE_DIR}" || exit 1
x86_64_EFI_DIR_PREFIX="/usr/lib/grub/x86_64-efi"
i386_EFI_DIR_PREFIX="/usr/lib/grub/i386-efi"
x86_64_EFI_DIR="${CHROOT_DIR}${x86_64_EFI_DIR_PREFIX}"
i386_EFI_DIR="${CHROOT_DIR}${i386_EFI_DIR_PREFIX}"
pre_iso_signal_handler() {
for mount_dir in "${MOUNT_DIRS[@]}"; do
if [ -d "${mount_dir}" ]; then
umount -f "${mount_dir}" || \
umount -l "${mount_dir}" # best effort
rmdir "${mount_dir}"
fi
done
}
trap "pre_iso_signal_handler" EXIT SIGINT SIGQUIT SIGILL SIGTERM SIGHUP
if [ -d "${x86_64_EFI_DIR}" ]; then
# create the EFI image
chroot "${CHROOT_DIR}" grub2-mkimage \
-p "${GRUB_BOOT_DIR_PREFIX}" \
-d "${x86_64_EFI_DIR_PREFIX}" \
-o /bootx64.efi \
-O x86_64-efi ext2 fat lvm part_msdos \
part_gpt search_fs_uuid normal \
chain iso9660 configfile loadenv \
reboot cat \
|| exit 1
mv "${CHROOT_DIR}"/bootx64.efi "${EFI_BOOT_DIR}/" || exit 1
cp -Rp "${x86_64_EFI_DIR}" "${GRUB_BOOT_DIR}/" || exit 1
fi
if [ -d "${i386_EFI_DIR}" ]; then
# create the EFI image
chroot "${CHROOT_DIR}" grub2-mkimage \
-p "${GRUB_BOOT_DIR_PREFIX}" \
-d "${i386_EFI_DIR_PREFIX}" \
-o /boota32.efi \
-O i386-efi ext2 fat lvm part_msdos \
part_gpt search_fs_uuid normal \
chain iso9660 configfile loadenv \
reboot cat \
|| exit 1
mv "${CHROOT_DIR}"/boota32.efi "${EFI_BOOT_DIR}/" || exit 1
cp -Rp "${i386_EFI_DIR}" "${GRUB_BOOT_DIR}/" || exit 1
fi
# now setup SecureBoot for x86_64 using shim:
# See: http://mjg59.dreamwidth.org/20303.html
efi_x86_64_file="${EFI_BOOT_DIR}"/bootx64.efi
grub_efi_file="${EFI_BOOT_DIR}"/grubx64.efi
if [ -f "${efi_x86_64_file}" ]; then
shim_dir="${SABAYON_MOLECULE_HOME}"/boot/shim-uefi-secure-boot
# This is on the ISO build server, not on the repos
sbsign_private_key="${shim_dir}"/private.key
# actually, UEFI SecureBoot needs the cert in DER
# format (sabayon.cer), while sbsign requires a
# plain old text-based x509 certificate (sabayon.crt)
sabayon_der="${shim_dir}"/sabayon.cer
sabayon_cert="${shim_dir}"/sabayon.crt
mv "${efi_x86_64_file}" "${grub_efi_file}" || exit 1
cp "${shim_dir}"/shim.efi "${efi_x86_64_file}" || exit 1
cp "${shim_dir}"/MokManager.efi "${EFI_BOOT_DIR}"/ || exit 1
# Copy the Sabayon SecureBoot certificate to a nice dir
mkdir "${CDROOT_DIR}"/SecureBoot || exit 1
cp "${sabayon_der}" "${CDROOT_DIR}"/SecureBoot/ || exit 1
# Sign
sbsign --key "${sbsign_private_key}" --cert "${sabayon_cert}" \
--output "${grub_efi_file}.signed" \
"${grub_efi_file}" || exit 1
mv "${grub_efi_file}.signed" "${grub_efi_file}" || exit 1
fi
# now the tricky part, create an eltorito alternative image
_efi_img="${GRUB_BOOT_DIR}"/efi.img
# 3 floppies = 2880 x 3, we need more space for SecureBoot stuff
dd bs=512 count=$((2880 * 3)) if=/dev/zero of="${_efi_img}" || exit 1
mkfs.msdos "${_efi_img}" || exit 1
tmp_dir=$(mktemp -d --suffix="make_grub_efi")
[[ -z "${tmp_dir}" ]] && exit 1
MOUNT_DIRS+=( "${tmp_dir}" )
mount -o loop "${_efi_img}" "${tmp_dir}" || exit 1
mkdir -p "${tmp_dir}/efi/boot" || exit 1
if [ -f "${efi_x86_64_file}" ]; then
cp -Rp "${EFI_BOOT_DIR}"/* "${tmp_dir}/efi/boot"/ || exit 1
fi
umount "${tmp_dir}" || exit 1
rmdir "${tmp_dir}" # best effort
# These must exist.
cp "${CHROOT_DIR}/usr/share/grub/unicode.pf2" "${GRUB_BOOT_DIR}"/ || exit 1
# Copy locale files
localedir="${CHROOT_DIR}/usr/share/locale"
for dir in "${localedir}"/*; do
if [ -f "${dir}/LC_MESSAGES/grub.mo" ]; then
cp -f "${dir}/LC_MESSAGES/grub.mo" "${GRUB_LOCALE_DIR}/${dir##*/}.mo"
fi
done
# Copy splash, this is in sabayon-artwork-grub, we expect to find it
cp "${CHROOT_DIR}/usr/share/grub/default-splash.png" "${GRUB_BOOT_DIR}"/ \
|| exit 1