195 lines
9.4 KiB
Diff
195 lines
9.4 KiB
Diff
diff --git a/usr/share/rear/lib/uefi-functions.sh b/usr/share/rear/lib/uefi-functions.sh
|
|
index 95e6292d..c583e044 100644
|
|
--- a/usr/share/rear/lib/uefi-functions.sh
|
|
+++ b/usr/share/rear/lib/uefi-functions.sh
|
|
@@ -37,20 +37,76 @@ function trim {
|
|
}
|
|
|
|
function build_bootx86_efi {
|
|
- local gmkimage
|
|
- if has_binary grub-mkimage; then
|
|
- gmkimage=grub-mkimage
|
|
- elif has_binary grub2-mkimage; then
|
|
- gmkimage=grub2-mkimage
|
|
+ local outfile="$1"
|
|
+ local embedded_config=""
|
|
+ local gmkstandalone=""
|
|
+ local gprobe=""
|
|
+ local dirs=()
|
|
+ # modules is the list of modules to load
|
|
+ local modules=()
|
|
+
|
|
+ # Configuration file is optional for image creation.
|
|
+ shift
|
|
+ if [[ -n "$1" ]] ; then
|
|
+ # graft point syntax. $1 will appear as /boot/grub/grub.cfg in the image
|
|
+ embedded_config="/boot/grub/grub.cfg=$1"
|
|
+ shift
|
|
+ # directories that should be accessible by GRUB2 (e.g. because they contain the kernel)
|
|
+ dirs=( ${@:+"$@"} )
|
|
+ fi
|
|
+
|
|
+ if has_binary grub-mkstandalone ; then
|
|
+ gmkstandalone=grub-mkstandalone
|
|
+ elif has_binary grub2-mkstandalone ; then
|
|
+ # At least SUSE systems use 'grub2' prefixed names for GRUB2 programs:
|
|
+ gmkstandalone=grub2-mkstandalone
|
|
else
|
|
- Log "Did not find grub-mkimage (cannot build bootx86.efi)"
|
|
- return
|
|
+ # This build_bootx86_efi function is only called in output/ISO/Linux-i386/250_populate_efibootimg.sh
|
|
+ # which runs only if UEFI is used so that we simply error out here if we cannot make a bootable EFI image of GRUB2
|
|
+ # (normally a function should not exit out but return to its caller with a non-zero return code):
|
|
+ Error "Cannot make bootable EFI image of GRUB2 (neither grub-mkstandalone nor grub2-mkstandalone found)"
|
|
+ fi
|
|
+
|
|
+ # Determine what modules need to be loaded in order to access given directories
|
|
+ # (if the list of modules is not overriden by GRUB2_MODULES_LOAD)
|
|
+ if (( ${#dirs[@]} )) && ! (( ${#modules[@]} )) ; then
|
|
+ if has_binary grub-probe ; then
|
|
+ gprobe=grub-probe
|
|
+ elif has_binary grub2-probe ; then
|
|
+ # At least SUSE systems use 'grub2' prefixed names for GRUB2 programs:
|
|
+ gprobe=grub2-probe
|
|
+ else
|
|
+ LogWarn "Neither grub-probe nor grub2-probe found"
|
|
+ if test /usr/lib/grub*/x86_64-efi/partmap.lst ; then
|
|
+ LogWarn "including all partition modules"
|
|
+ modules=( $(cat /usr/lib/grub*/x86_64-efi/partmap.lst) )
|
|
+ else
|
|
+ Error "Can not determine partition modules, ${dirs[*]} would be likely inaccessible in GRUB2"
|
|
+ fi
|
|
+ fi
|
|
+
|
|
+ if [ -n "$gprobe" ]; then
|
|
+ # this is unfortunately only a crude approximation of the Grub internal probe_mods() function
|
|
+ modules=( $( for p in "${dirs[@]}" ; do
|
|
+ $gprobe --target=fs "$p"
|
|
+ $gprobe --target=partmap "$p" | sed -e 's/^/part_/'
|
|
+ $gprobe --target=abstraction "$p"
|
|
+ done | sort -u ) )
|
|
+ fi
|
|
+ fi
|
|
+
|
|
+ # grub-mkimage needs /usr/lib/grub/x86_64-efi/moddep.lst (cf. https://github.com/rear/rear/issues/1193)
|
|
+ # and at least on SUSE systems grub2-mkimage needs /usr/lib/grub2/x86_64-efi/moddep.lst (in 'grub2' directory)
|
|
+ # so that we error out if grub-mkimage or grub2-mkimage would fail when its moddep.lst is missing.
|
|
+ # Careful: usr/sbin/rear sets nullglob so that /usr/lib/grub*/x86_64-efi/moddep.lst gets empty if nothing matches
|
|
+ # and 'test -f' succeeds with empty argument so that we cannot use 'test -f /usr/lib/grub*/x86_64-efi/moddep.lst'
|
|
+ # also 'test -n' succeeds with empty argument but (fortunately/intentionally?) plain 'test' fails with empty argument:
|
|
+ test /usr/lib/grub*/x86_64-efi/moddep.lst || Error "$gmkstandalone would not make bootable EFI image of GRUB2 (no /usr/lib/grub*/x86_64-efi/moddep.lst file)"
|
|
+
|
|
+ (( ${#modules[@]} )) && LogPrint "GRUB2 modules to load: ${modules[*]}"
|
|
+
|
|
+ if ! $gmkstandalone $v ${modules:+"--modules=${modules[*]}"} -O x86_64-efi -o $outfile $embedded_config ; then
|
|
+ Error "Failed to make bootable EFI image of GRUB2 (error during $gmkstandalone of $outfile)"
|
|
fi
|
|
- # as not all Linux distro's have the same grub modules present we verify what we have (see also https://github.com/rear/rear/pull/2001)
|
|
- grub_modules=""
|
|
- for grub_module in part_gpt part_msdos fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs ; do
|
|
- test "$( find /boot -type f -name "$grub_module.mod" 2>/dev/null )" && grub_modules="$grub_modules $grub_module"
|
|
- done
|
|
- $gmkimage $v -O x86_64-efi -c $TMP_DIR/mnt/EFI/BOOT/embedded_grub.cfg -o $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi -p "/EFI/BOOT" $grub_modules
|
|
- StopIfError "Error occurred during $gmkimage of BOOTX64.efi"
|
|
}
|
|
+
|
|
diff --git a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
|
|
index fdf66039..e9325012 100644
|
|
--- a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
|
|
+++ b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
|
|
@@ -2,6 +2,9 @@
|
|
|
|
is_true $USING_UEFI_BOOTLOADER || return 0 # empty or 0 means NO UEFI
|
|
|
|
+local boot_dir="/boot"
|
|
+local efi_boot_tmp_dir="$TMP_DIR/mnt/EFI/BOOT"
|
|
+
|
|
mkdir $v -p $TMP_DIR/mnt/EFI/BOOT >&2
|
|
StopIfError "Could not create $TMP_DIR/mnt/EFI/BOOT"
|
|
|
|
@@ -56,14 +59,8 @@ title Relax-and-Recover (no Secure Boot)
|
|
|
|
EOF
|
|
else
|
|
-# create small embedded grub.cfg file for grub-mkimage
|
|
-cat > $TMP_DIR/mnt/EFI/BOOT/embedded_grub.cfg <<EOF
|
|
-set prefix=(cd0)/EFI/BOOT
|
|
-configfile /EFI/BOOT/grub.cfg
|
|
-EOF
|
|
-
|
|
-# create a grub.cfg
|
|
- create_grub2_cfg > $TMP_DIR/mnt/EFI/BOOT/grub.cfg
|
|
+ # create a grub.cfg
|
|
+ create_grub2_cfg > $efi_boot_tmp_dir/grub.cfg
|
|
fi
|
|
|
|
# Create BOOTX86.efi but only if we are NOT secure booting.
|
|
@@ -72,15 +69,15 @@ fi
|
|
# See issue #1374
|
|
# build_bootx86_efi () can be safely used for other scenarios.
|
|
if ! test -f "$SECURE_BOOT_BOOTLOADER" ; then
|
|
- build_bootx86_efi
|
|
+ build_bootx86_efi $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi $efi_boot_tmp_dir/grub.cfg "$boot_dir" "$UEFI_BOOTLOADER"
|
|
fi
|
|
|
|
# We will be using grub-efi or grub2 (with efi capabilities) to boot from ISO.
|
|
# Because usr/sbin/rear sets 'shopt -s nullglob' the 'echo -n' command
|
|
# outputs nothing if nothing matches the bash globbing pattern '/boot/grub*'
|
|
-local grubdir="$( echo -n /boot/grub* )"
|
|
+local grubdir="$( echo -n ${boot_dir}/grub* )"
|
|
# Use '/boot/grub' as fallback if nothing matches '/boot/grub*'
|
|
-test -d "$grubdir" || grubdir='/boot/grub'
|
|
+test -d "$grubdir" || grubdir="${boot_dir}/grub"
|
|
|
|
if [ -d $(dirname ${UEFI_BOOTLOADER})/fonts ]; then
|
|
cp $v $(dirname ${UEFI_BOOTLOADER})/fonts/* $TMP_DIR/mnt/EFI/BOOT/fonts/ >&2
|
|
diff --git a/usr/share/rear/output/default/940_grub2_rescue.sh b/usr/share/rear/output/default/940_grub2_rescue.sh
|
|
index a94957de..fbbd7074 100644
|
|
--- a/usr/share/rear/output/default/940_grub2_rescue.sh
|
|
+++ b/usr/share/rear/output/default/940_grub2_rescue.sh
|
|
@@ -144,13 +144,18 @@ if is_true $USING_UEFI_BOOTLOADER ; then
|
|
# probably a bug, as I was able to boot with value set to root=anything
|
|
root_uuid=$(mount | grep -w 'on /' | awk '{print $1}' | xargs blkid -s UUID -o value)
|
|
|
|
- # Grub2 modules that will be used for booting "Relax-and-Recover"
|
|
- # It might be useful to make this variable global in the future
|
|
- grub2_modules="linux echo all_video part_gpt ext2 btrfs search configfile"
|
|
-
|
|
# Create configuration file for "Relax-and-Recover" UEFI boot entry.
|
|
# This file will not interact with existing Grub2 configuration in any way.
|
|
- ( echo "menuentry '$grub_rear_menu_entry_name' --class os {"
|
|
+ ( echo "set btrfs_relative_path=y"
|
|
+ echo "insmod efi_gop"
|
|
+ echo "insmod efi_uga"
|
|
+ echo "insmod video_bochs"
|
|
+ echo "insmod video_cirrus"
|
|
+ echo "insmod all_video"
|
|
+ echo ""
|
|
+ echo "set gfxpayload=keep"
|
|
+ echo ""
|
|
+ echo "menuentry '$grub_rear_menu_entry_name' --class os {"
|
|
echo " search --no-floppy --fs-uuid --set=root $grub_boot_uuid"
|
|
echo " echo 'Loading kernel $boot_kernel_file ...'"
|
|
echo " linux $grub_boot_dir/$boot_kernel_name root=UUID=$root_uuid $KERNEL_CMDLINE"
|
|
@@ -159,19 +164,8 @@ if is_true $USING_UEFI_BOOTLOADER ; then
|
|
echo "}"
|
|
) > $grub_config_dir/rear.cfg
|
|
|
|
- # Tell rear.efi which configuration file to load
|
|
- ( echo "search --no-floppy --fs-uuid --set=root $grub_boot_uuid"
|
|
- echo ""
|
|
- echo "set btrfs_relative_path=y"
|
|
- echo "set prefix=(\$root)${grub_boot_dir}/grub${grub_num}"
|
|
- echo ""
|
|
- echo "configfile (\$root)${grub_boot_dir}/grub${grub_num}/rear.cfg"
|
|
- ) > $grub_config_dir/rear_embed.cfg
|
|
-
|
|
# Create rear.efi at UEFI default boot directory location.
|
|
- if ! grub${grub_num}-mkimage -o $boot_dir/efi/EFI/BOOT/rear.efi -O x86_64-efi -c $grub_config_dir/rear_embed.cfg -p /EFI/BOOT $grub2_modules ; then
|
|
- Error "Could not create UEFI boot image"
|
|
- fi
|
|
+ build_bootx86_efi $boot_dir/efi/EFI/BOOT/rear.efi $grub_config_dir/rear.cfg "$boot_dir" "$UEFI_BOOTLOADER"
|
|
|
|
# If UEFI boot entry for "Relax-and-Recover" does not exist, create it.
|
|
# This will also add "Relax-and-Recover" to boot order because if UEFI entry is not listed in BootOrder,
|