diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c index d76c34c14..b39e97f48 100644 --- a/grub-core/osdep/basic/no_platform.c +++ b/grub-core/osdep/basic/no_platform.c @@ -25,7 +25,7 @@ void grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) + int partno, const char *relpath, int detect_nvram) { grub_util_error ("%s", _("no IEEE1275 routines are available for your platform")); } @@ -33,7 +33,8 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device, void grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, - const char *efi_distributor) + const char *efi_distributor, + int detect_nvram) { grub_util_error ("%s", _("no EFI routines are available for your platform")); } diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c index ca448bc11..4eb2c11c9 100644 --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -134,7 +134,8 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) int grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, - const char *efi_distributor) + const char *efi_distributor, + int detect_nvram) { const char * efidir_disk; int efidir_part; @@ -153,6 +154,21 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, #ifdef __linux__ grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL }); #endif + + /* If requested, we try to detect if NVRAM access is available and if not, + warn the user and resume normal operation. */ + if (detect_nvram) + { + error = grub_util_exec_redirect_null ((const char * []){ "efibootmgr", NULL }); + if (error == 2) + { + grub_util_warn ("%s", _("Auto-NVRAM selected and no EFI variable support detected on the system.")); + return 0; + } + else if (error) + return error; + } + /* Delete old entries from the same distributor. */ ret = grub_install_remove_efi_entries_by_distributor (efi_distributor); if (ret) @@ -178,7 +194,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, void grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) + int partno, const char *relpath, int detect_nvram) { char *boot_device; @@ -189,6 +205,14 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device, grub_util_error (_("%s: not found"), "ofpathname"); } + /* If requested, we try to detect if NVRAM access is available and if not, + warn the user and resume normal operation. */ + if (detect_nvram && grub_util_exec_redirect_null ((const char * []){ "nvram", NULL })) + { + grub_util_warn ("%s", _("Auto-NVRAM selected and no IEEE1275 variable support detected on the system.")); + return; + } + /* Get the Open Firmware device tree path translation. */ if (!is_prep) { diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c index 912269191..f4c5bd47b 100644 --- a/grub-core/osdep/windows/platform.c +++ b/grub-core/osdep/windows/platform.c @@ -204,7 +204,8 @@ set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len) void grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, - const char *efi_distributor) + const char *efi_distributor, + int detect_nvram) { grub_uint16_t *boot_order, *new_boot_order; grub_uint16_t *distributor16; @@ -411,7 +412,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, void grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) + int partno, const char *relpath, int detect_nvram) { grub_util_error ("%s", _("no IEEE1275 routines are available for your platform")); } diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 0dba8b67f..ba5140b5a 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -213,11 +213,12 @@ grub_install_get_default_x86_platform (void); int grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, - const char *efi_distributor); + const char *efi_distributor, + int detect_nvram); void grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath); + int partno, const char *relpath, int detect_nvram); void grub_install_sgi_setup (const char *install_device, diff --git a/util/grub-install.c b/util/grub-install.c index 690f180c5..f963e72cb 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -57,6 +57,7 @@ static char *target; static int removable = 0; static int recheck = 0; static int update_nvram = 1; +static int auto_nvram = 0; static char *install_device = NULL; static char *debug_image = NULL; static char *rootdir = NULL; @@ -109,7 +110,8 @@ enum OPTION_LABEL_FONT, OPTION_LABEL_COLOR, OPTION_LABEL_BGCOLOR, - OPTION_PRODUCT_VERSION + OPTION_PRODUCT_VERSION, + OPTION_AUTO_NVRAM }; static int fs_probe = 1; @@ -200,6 +202,10 @@ argp_parser (int key, char *arg, struct argp_state *state) update_nvram = 0; return 0; + case OPTION_AUTO_NVRAM: + auto_nvram = 1; + return 0; + case OPTION_FORCE: force = 1; return 0; @@ -278,6 +284,9 @@ static struct argp_option options[] = { {"no-nvram", OPTION_NO_NVRAM, 0, 0, N_("don't update the `boot-device'/`Boot*' NVRAM variables. " "This option is only available on EFI and IEEE1275 targets."), 2}, + {"auto-nvram", OPTION_AUTO_NVRAM, 0, 0, + N_("only update NVRAM variables if possible. " + "This option is only available on EFI and IEEE1275 targets."), 2}, {"skip-fs-probe",'s',0, 0, N_("do not probe for filesystems in DEVICE"), 0}, {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0, @@ -1755,7 +1764,7 @@ main (int argc, char *argv[]) ? ins_dev->disk->partition->number + 1 : 0; dev = grub_util_get_os_disk (install_device); grub_install_register_ieee1275 (0, dev, partno, - "\\\\BootX"); + "\\\\BootX", auto_nvram); } grub_device_close (ins_dev); free (grub_elf); @@ -1787,7 +1796,7 @@ main (int argc, char *argv[]) grub_device_close (ins_dev); if (update_nvram) grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), - 0, NULL); + 0, NULL, auto_nvram); break; } /* fallthrough. */ @@ -1802,7 +1811,7 @@ main (int argc, char *argv[]) ? grub_dev->disk->partition->number + 1 : 0; dev = grub_util_get_os_disk (grub_devices[0]); grub_install_register_ieee1275 (0, dev, - partno, relpath); + partno, relpath, auto_nvram); } break; case GRUB_INSTALL_PLATFORM_MIPS_ARC: @@ -1851,7 +1860,7 @@ main (int argc, char *argv[]) int ret; ret = grub_install_register_efi (efidir_grub_dev, "\\System\\Library\\CoreServices", - efi_distributor); + efi_distributor, auto_nvram); if (ret) grub_util_error (_("efibootmgr failed to register the boot entry: %s"), strerror (ret)); @@ -1893,7 +1902,7 @@ main (int argc, char *argv[]) (part ? ",": ""), (part ? : "")); grub_free (part); ret = grub_install_register_efi (efidir_grub_dev, - efifile_path, efi_distributor); + efifile_path, efi_distributor, auto_nvram); if (ret) grub_util_error (_("efibootmgr failed to register the boot entry: %s"), strerror (ret));