From 654b2baef50635a65c5f89fd5c171ac7f53cdd0f Mon Sep 17 00:00:00 2001 From: Gardouille Date: Wed, 16 Dec 2020 07:17:24 +0100 Subject: [PATCH] Script to create EFI blob with initrd and kernel --- debian/create.efi.kernel.sh | 104 ++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 debian/create.efi.kernel.sh diff --git a/debian/create.efi.kernel.sh b/debian/create.efi.kernel.sh new file mode 100755 index 0000000..10a871a --- /dev/null +++ b/debian/create.efi.kernel.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# EFI related vars +EFI_BASE_LABEL="Debian unified" +EFI_MOUNT_PATH="/boot/efi" + +temp_efi_list_file="/tmp/efibootmgr.label.entry.temp" + +# OS related vars +ROOT_UUID=$(findmnt -kno UUID /) +ROOT_FSTYPE=$(findmnt -kno FSTYPE /) +CRYPT_PART_UUID=$(blkid | sed -n 's;/dev/.*_crypt.*UUID="\(.*\)".*TYPE=.*;\1;p') + +temp_kernel_list_file="/tmp/kernel.list.temp" +temp_kernel_command_file="/tmp/kernel.command.temp" + + +# Clean old entries {{{ + +## Install efibootmgr tool if not available +command -v efibootmgr > /dev/null || aptitude install -y efibootmgr + +## Get all old entries list with base label +rm -f -- "${temp_efi_list_file}" ; touch "${temp_efi_list_file}" +efibootmgr | grep -E ".*${EFI_BASE_LABEL}.*" | cut -c 5-8 > "${temp_efi_list_file}" + +## Remove all matching entries +while IFS= read -r OLD_EFI_ENTRY; do + printf "%s\n" "Deleting efiboot entry ${OLD_EFI_ENTRY}" + efibootmgr --delete-bootnum --bootnum "${OLD_EFI_ENTRY}" > /dev/null || exit 1 + #printf "%s\n" "efibootmgr --delete-bootnum --bootnum ${EFI_ENTRY}" +done < "${temp_efi_list_file}" +# }}} +# Clean old kernels {{{ +## Remove all unified kernels +find "${EFI_MOUNT_PATH}"/EFI/debian -iname "linux.debian.*.efi" -delete +# }}} + +# Create unified kernels blob and efiboot entries {{{ + +## Install objcopy tool if not available +command -v objcopy > /dev/null || aptitude install -y binutils + +## Put Kernel command line in temp file +rm -f -- "${temp_kernel_command_file}" ; touch "${temp_kernel_command_file}" +printf "%s" "root=UUID=${ROOT_UUID} rootfstype=${ROOT_FSTYPE} add_efi_memmap \ +ro cryptdevice=UUID=${CRYPT_PART_UUID}:lvm" >> "${temp_kernel_command_file}" + +## Get all kernel versions starting with the oldest +rm -f -- "${temp_kernel_list_file}" ; touch "${temp_kernel_list_file}" +ls -1tr /boot/vmlinuz-* >> "${temp_kernel_list_file}" + +## For each version of the kernel {{{ +while IFS= read -r KERNEL; do + ### Get kernel version + KERNEL_VERSION=$(printf "%s" "${KERNEL}" | sed 's;.*vmlinuz-\(.*\);\1;') + + ### Ensure EFI device is mounted (excluding systemd-automount line) + if ! mount | grep -v "autofs" | grep --quiet "${EFI_MOUNT_PATH}"; then + mount "${EFI_MOUNT_PATH}" || exit 2 + fi + + ESP=$(findmnt -kno SOURCE "${EFI_MOUNT_PATH}" | grep -v systemd | sed s-/dev/--) + ESP_DISK=$(lsblk /dev/"${ESP}" -no pkname) + ESP_PART=$(cat /sys/class/block/"${ESP}"/partition) + + ### Create a unified kernel + printf "%s\n" "Creating unified kernel for version ${KERNEL_VERSION}..." + objcopy \ + --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \ + --add-section .cmdline="${temp_kernel_command_file}" --change-section-vma .cmdline=0x30000 \ + --add-section .linux="/boot/vmlinuz-${KERNEL_VERSION}" --change-section-vma .linux=0x2000000 \ + --add-section .initrd="/boot/initrd.img-${KERNEL_VERSION}" --change-section-vma .initrd=0x3000000 \ + /usr/lib/systemd/boot/efi/linuxx64.efi.stub "${EFI_MOUNT_PATH}/EFI/debian/linux.debian.${KERNEL_VERSION}.efi" + + ### Create a efiboot entry + printf "%s\n" "Creating efiboot entry for kernel ${KERNEL_VERSION}" + efibootmgr --disk /dev/"${ESP_DISK}" --part "${ESP_PART}" --create --label "${EFI_BASE_LABEL} ${KERNEL_VERSION}" --loader "\\EFI\\debian\\linux.debian.${KERNEL_VERSION}.efi" + #printf "%s\n" "efibootmgr --disk /dev/\"${ESP_DISK}\" --part \"${ESP_PART}\" --create --label \"${EFI_BASE_LABEL} ${KERNEL_VERSION}\" --loader \"\\EFI\\debian\\linux.${KERNEL_VERSION}.efi\"" + +done < "${temp_kernel_list_file}" +## }}} +## Create generic entry for the last version of the kernel {{{ +### Create a unified kernel +printf "%s\n" "Creating unified generic kernel for the last version (${KERNEL_VERSION})..." +objcopy \ + --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \ + --add-section .cmdline="${temp_kernel_command_file}" --change-section-vma .cmdline=0x30000 \ + --add-section .linux="/boot/vmlinuz-${KERNEL_VERSION}" --change-section-vma .linux=0x2000000 \ + --add-section .initrd="/boot/initrd.img-${KERNEL_VERSION}" --change-section-vma .initrd=0x3000000 \ + /usr/lib/systemd/boot/efi/linuxx64.efi.stub "${EFI_MOUNT_PATH}/EFI/debian/linux.debian.efi" + +### Create a efiboot entry +printf "%s\n" "Creating efiboot generic entry for the last version (${KERNEL_VERSION})" +efibootmgr --disk /dev/"${ESP_DISK}" --part "${ESP_PART}" --create --label "${EFI_BASE_LABEL}" --loader "\\EFI\\debian\\linux.debian.efi" +#printf "%s\n" "efibootmgr --disk /dev/\"${ESP_DISK}\" --part \"${ESP_PART}\" --create --label \"${EFI_BASE_LABEL} ${KERNEL_VERSION}\" --loader \"\\EFI\\debian\\linux.efi\"" + +## }}} +# }}} + +## Remove temp files +rm -f -- "${temp_efi_list_file}" "${temp_kernel_list_file}" "${temp_kernel_command_file}" + +exit 0