From a9c15e5e653735f2f1bf85710cc6e30236cd2ee6 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 21 Dec 2020 14:17:11 +0000 Subject: Add option to configure rEFInd to not use EFI NVRAM (mga#27838) The combination of this and installing in \EFI\BOOT provides a workaround for machines where the NVRAM is broken or worn out. --- perl-install/bootloader.pm | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'perl-install/bootloader.pm') diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index a9f3077a8..85278c547 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -705,9 +705,19 @@ sub read_refind() { } } $bootloader{method} = 'refind'; + #- Try both possible locations for the main config file. The default is to use NVRAM if the + #- config file isn't found. + $bootloader{use_nvram} = get_refind_use_nvram("$::prefix/boot/EFI/EFI/refind/refind.conf") + && get_refind_use_nvram("$::prefix/boot/EFI/EFI/BOOT/refind.conf"); \%bootloader; } +sub get_refind_use_nvram { + my ($path) = @_; + #- The default is to use NVRAM, so test if it is explicitly disabled. + -r $path && (grep { /^\s*use_nvram\s+(false|off|0)/ } cat_utf8($path)) ? 0 : 1; +} + # FIXME: actually read back previous conf sub read_cromwell() { +{ method => 'cromwell' }; @@ -2426,7 +2436,12 @@ sub write_refind { my $default_kernel = readlink("$::prefix/boot/vmlinuz"); if ($default_kernel) { - write_refind_previous_boot_var($default_kernel); + if ($bootloader->{use_nvram}) { + write_refind_previous_boot_var($default_kernel); + } else { + write_refind_previous_boot_file($default_kernel, "$::prefix/boot/EFI/EFI/refind"); + write_refind_previous_boot_file($default_kernel, "$::prefix/boot/EFI/EFI/BOOT"); + } } } @@ -2450,6 +2465,20 @@ sub write_refind_previous_boot_var { run_program::run('umount', $efivars) if !$already_mounted; } +sub write_refind_previous_boot_file { + my ($kernel, $base_path) = @_; + return if ! -e "$base_path/refind.conf" || ! mkdir_p("$base_path/vars"); + if (open(my $f, '>:raw', "$base_path/vars/PreviousBoot")) { + require Encode; + log::l("writing rEFInd $base_path/vars/PreviousBoot file"); + print $f Encode::encode('UTF16-LE', "Boot boot\\$kernel"); + print $f "\x00\x00"; + close($f); + } else { + log::l("failed to write rEFInd $base_path/vars/PreviousBoot file"); + } +} + sub install_refind { my ($bootloader, $all_hds) = @_; @@ -2469,9 +2498,19 @@ sub install_refind { run_program::rooted($::prefix, '/sbin/refind-install', '2>', \$error, @options) or die "refind-install failed: $error"; } + #- Try both possible locations for the main config file. + set_refind_use_nvram($bootloader->{use_nvram}, "$::prefix/boot/EFI/EFI/refind/refind.conf"); + set_refind_use_nvram($bootloader->{use_nvram}, "$::prefix/boot/EFI/EFI/BOOT/refind.conf"); write_refind($bootloader, $all_hds); } +sub set_refind_use_nvram { + my ($use_nvram, $path) = @_; + return if ! -w $path; + my $script = 's/^#?\s*use_nvram\s+.*/use_nvram ' . ($use_nvram ? 'true' : 'false') . '/'; + run_program::run('sed', '-i', '-E', $script, $path) or die "failed to update $path"; +} + sub when_config_changed_refind { my ($_bootloader) = @_; #- do not do anything -- cgit v1.2.1