­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ # Use Grub 2 to create an EFI bootloader # ### Check prerequisites # (1) An EFI bootloader must not have been created yet [[ -n "$RAWDISK_BOOT_EFI_STAGING_ROOT" ]] && return 0 # (2) Grub 2 (which has a *-probe executable while Grub 1 does not) must exist if has_binary grub-probe; then grub2_name="grub" # The name prefixes executables and determines the installation directory under /boot elif has_binary grub2-probe; then grub2_name="grub2" else return 0 fi # (3) Grub 2 EFI components must exist # Since openSUSE Leap 15.1 things were moved from /usr/lib/grub2/ to /usr/share/grub2/ # cf. https://github.com/rear/rear/issues/2338#issuecomment-594432946 local efi_modules_directory local dir for dir in /usr/lib/grub/x86_64-efi /usr/lib/grub2/x86_64-efi /usr/share/grub2/x86_64-efi; do if [[ -d "$dir" ]]; then efi_modules_directory="$dir" break fi done [[ -z "$efi_modules_directory" ]] && return 0 # (4) Grub 2 must not have been excluded if is_true "${RAWDISK_BOOT_EXCLUDE_GRUB2_EFI:-no}"; then LogPrint "DISABLED: Using Grub 2 to create an EFI bootloader" return 0 fi ### Copy Grub 2 files into the staging directory LogPrint "Using Grub 2 to create an EFI bootloader" if is_true $USING_UEFI_BOOTLOADER && [[ -z "$SECURE_BOOT_BOOTLOADER" ]]; then LogPrint "TIP: You can achieve a faster EFI boot by installing syslinux for EFI on this system" fi RAWDISK_BOOT_EFI_STAGING_ROOT="$TMP_DIR/EFI" # Set up contents of a Grub 2 configuration file local new_grub_configuration read -r -d '' new_grub_configuration << EOF set timeout=0 set default=0 menuentry "${RAWDISK_BOOT_GRUB_MENUENTRY_TITLE:-Recovery System}" { linux /$(basename "$KERNEL_FILE") $KERNEL_CMDLINE initrd /$REAR_INITRD_FILENAME } EOF if [[ -n "$SECURE_BOOT_BOOTLOADER" ]]; then # Using Secure Boot: # We use '$SECURE_BOOT_BOOTLOADER' as a pointer into the original system's EFI tree, which should consist of # signed EFI executables (and possibly companion files). We cannot touch those signed executables without # breaking Secure Boot and we cannot know which companion files are actually required, so we play it safe # and copy the entire EFI tree as is. local original_efi_root="$(findmnt --noheadings --output TARGET --target "$SECURE_BOOT_BOOTLOADER")/EFI" [[ "$original_efi_root" == "/EFI" ]] && Error "Could not find original EFI root directory" LogPrint "Secure Boot: Using the original EFI configuration from '$original_efi_root'" cp -a $v "$original_efi_root/." "$RAWDISK_BOOT_EFI_STAGING_ROOT" || Error "Could not copy EFI configuration" # If /boot/$grub2_name exists, it contains additional Grub modules, which are not compiled into the grub core image. # Pick required ones from there, too. local additional_grub_directory="/boot/$grub2_name" local grub_modules_directory="x86_64-efi" local additional_grub_modules=( all_video.mod ) if [[ -d "$additional_grub_directory/$grub_modules_directory" ]]; then local grub_target_directory="$(dirname "$(find "$RAWDISK_BOOT_EFI_STAGING_ROOT" -iname grubx64.efi -print)")" [[ "$grub_target_directory" == "." ]] && Error "Could not find Grub executable" # dirname "" returns "." mkdir "$grub_target_directory/$grub_modules_directory" || Error "Could not create Grub modules directory" for module in "${additional_grub_modules[@]}"; do cp -a $v "$additional_grub_directory/$grub_modules_directory/$module" "$grub_target_directory/$grub_modules_directory" StopIfError "Could not copy additional Grub module '$module'" new_grub_configuration="insmod ${module%.mod}"$'\n'"$new_grub_configuration" done fi # Now we look for existing Grub configuration files and overwrite those with our own configuration. Again, to # be safe, we are prepared for the situation where we might find more than one grub.cfg without knowing which # one is effective, so we overwrite each one. for target_config_path in $(find "$RAWDISK_BOOT_EFI_STAGING_ROOT" -iname grub.cfg -print); do echo "$new_grub_configuration" > "$target_config_path" StopIfError "Could not copy Grub configuration to '$target_config_path'" done else # Not Using Secure Boot: # Populate the EFI file system with a newly created Grub boot loader image and the Grub configuration file. local efi_boot_directory="$RAWDISK_BOOT_EFI_STAGING_ROOT/BOOT" mkdir $v -p "$efi_boot_directory" || Error "Could not create $efi_boot_directory" echo "$new_grub_configuration" > "$efi_boot_directory/grub.cfg" # Create a Grub 2 EFI core image and install it as boot loader. (NOTE: This version will not be signed.) # Use the UEFI default boot loader name, so that firmware will find it without an existing boot entry. local boot_loader="$efi_boot_directory/BOOTX64.EFI" local grub_modules=( part_gpt fat normal configfile linux video all_video ) [[ -f "$efi_modules_directory/linuxefi.mod" ]] && grub_modules+=("$efi_modules_directory/linuxefi.mod") $grub2_name-mkimage -O x86_64-efi -o "$boot_loader" -p "/EFI/BOOT" "${grub_modules[@]}" StopIfError "Error occurred during $grub2_name-mkimage of $boot_loader" fi