203 lines
6.2 KiB
Diff
203 lines
6.2 KiB
Diff
From a0bfbdf9139bc127d28c4102b941ee504f7f0041 Mon Sep 17 00:00:00 2001
|
|
From: Steve McIntyre <93sam@debian.org>
|
|
Date: Wed, 3 Dec 2014 01:25:12 +0000
|
|
Subject: Add support for forcing EFI installation to the removable media path
|
|
|
|
Add an extra option to grub-install "--force-extra-removable". On EFI
|
|
platforms, this will cause an extra copy of the grub-efi image to be
|
|
written to the appropriate removable media patch
|
|
/boot/efi/EFI/BOOT/BOOT$ARCH.EFI as well. This will help with broken
|
|
UEFI implementations where the firmware does not work when configured
|
|
with new boot paths.
|
|
|
|
Signed-off-by: Steve McIntyre <93sam@debian.org>
|
|
|
|
Bug-Debian: https://bugs.debian.org/767037 https://bugs.debian.org/773092
|
|
Forwarded: Not yet
|
|
Last-Update: 2021-09-24
|
|
|
|
Patch-Name: grub-install-extra-removable.patch
|
|
---
|
|
util/grub-install.c | 110 +++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 108 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/util/grub-install.c b/util/grub-install.c
|
|
index 2304cc5c4..b51fe4710 100644
|
|
--- a/util/grub-install.c
|
|
+++ b/util/grub-install.c
|
|
@@ -56,6 +56,7 @@
|
|
|
|
static char *target;
|
|
static int removable = 0;
|
|
+static int force_extra_removable = 0;
|
|
static int recheck = 0;
|
|
static int update_nvram = 1;
|
|
static char *install_device = NULL;
|
|
@@ -113,7 +114,8 @@ enum
|
|
OPTION_LABEL_BGCOLOR,
|
|
OPTION_PRODUCT_VERSION,
|
|
OPTION_UEFI_SECURE_BOOT,
|
|
- OPTION_NO_UEFI_SECURE_BOOT
|
|
+ OPTION_NO_UEFI_SECURE_BOOT,
|
|
+ OPTION_FORCE_EXTRA_REMOVABLE
|
|
};
|
|
|
|
static int fs_probe = 1;
|
|
@@ -216,6 +218,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
|
removable = 1;
|
|
return 0;
|
|
|
|
+ case OPTION_FORCE_EXTRA_REMOVABLE:
|
|
+ force_extra_removable = 1;
|
|
+ return 0;
|
|
+
|
|
case OPTION_ALLOW_FLOPPY:
|
|
allow_floppy = 1;
|
|
return 0;
|
|
@@ -322,6 +328,9 @@ static struct argp_option options[] = {
|
|
N_("do not install an image usable with UEFI Secure Boot, even if the "
|
|
"system was currently started using it. "
|
|
"This option is only available on EFI."), 2},
|
|
+ {"force-extra-removable", OPTION_FORCE_EXTRA_REMOVABLE, 0, 0,
|
|
+ N_("force installation to the removable media path also. "
|
|
+ "This option is only available on EFI."), 2},
|
|
{0, 0, 0, 0, 0, 0}
|
|
};
|
|
|
|
@@ -847,6 +856,91 @@ fill_core_services (const char *core_services)
|
|
free (sysv_plist);
|
|
}
|
|
|
|
+/* Helper routine for also_install_removable() below. Walk through the
|
|
+ specified dir, looking to see if there is a file/dir that matches
|
|
+ the search string exactly, but in a case-insensitive manner. If so,
|
|
+ return a copy of the exact file/dir that *does* exist. If not,
|
|
+ return NULL */
|
|
+static char *
|
|
+check_component_exists(const char *dir,
|
|
+ const char *search)
|
|
+{
|
|
+ grub_util_fd_dir_t d;
|
|
+ grub_util_fd_dirent_t de;
|
|
+ char *found = NULL;
|
|
+
|
|
+ d = grub_util_fd_opendir (dir);
|
|
+ if (!d)
|
|
+ grub_util_error (_("cannot open directory `%s': %s"),
|
|
+ dir, grub_util_fd_strerror ());
|
|
+
|
|
+ while ((de = grub_util_fd_readdir (d)))
|
|
+ {
|
|
+ if (strcasecmp (de->d_name, search) == 0)
|
|
+ {
|
|
+ found = xstrdup (de->d_name);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ grub_util_fd_closedir (d);
|
|
+ return found;
|
|
+}
|
|
+
|
|
+/* Some complex directory-handling stuff in here, to cope with
|
|
+ * case-insensitive FAT/VFAT filesystem semantics. Ugh. */
|
|
+static void
|
|
+also_install_removable(const char *src,
|
|
+ const char *base_efidir,
|
|
+ const char *efi_suffix_upper)
|
|
+{
|
|
+ char *efi_file = NULL;
|
|
+ char *dst = NULL;
|
|
+ char *cur = NULL;
|
|
+ char *found = NULL;
|
|
+
|
|
+ if (!efi_suffix_upper)
|
|
+ grub_util_error ("%s", _("efi_suffix_upper not set"));
|
|
+ efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper);
|
|
+
|
|
+ /* We need to install in $base_efidir/EFI/BOOT/$efi_file, but we
|
|
+ * need to cope with case-insensitive stuff here. Build the path one
|
|
+ * component at a time, checking for existing matches each time. */
|
|
+
|
|
+ /* Look for "EFI" in base_efidir. Make it if it does not exist in
|
|
+ * some form. */
|
|
+ found = check_component_exists(base_efidir, "EFI");
|
|
+ if (found == NULL)
|
|
+ found = xstrdup("EFI");
|
|
+ dst = grub_util_path_concat (2, base_efidir, found);
|
|
+ cur = xstrdup (dst);
|
|
+ free (dst);
|
|
+ free (found);
|
|
+ grub_install_mkdir_p (cur);
|
|
+
|
|
+ /* Now BOOT */
|
|
+ found = check_component_exists(cur, "BOOT");
|
|
+ if (found == NULL)
|
|
+ found = xstrdup("BOOT");
|
|
+ dst = grub_util_path_concat (2, cur, found);
|
|
+ cur = xstrdup (dst);
|
|
+ free (dst);
|
|
+ free (found);
|
|
+ grub_install_mkdir_p (cur);
|
|
+
|
|
+ /* Now $efi_file */
|
|
+ found = check_component_exists(cur, efi_file);
|
|
+ if (found == NULL)
|
|
+ found = xstrdup(efi_file);
|
|
+ dst = grub_util_path_concat (2, cur, found);
|
|
+ cur = xstrdup (dst);
|
|
+ free (dst);
|
|
+ free (found);
|
|
+ grub_install_copy_file (src, cur, 1);
|
|
+
|
|
+ free (cur);
|
|
+ free (efi_file);
|
|
+}
|
|
+
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
@@ -864,6 +958,7 @@ main (int argc, char *argv[])
|
|
char *relative_grubdir;
|
|
char **efidir_device_names = NULL;
|
|
grub_device_t efidir_grub_dev = NULL;
|
|
+ char *base_efidir = NULL;
|
|
char *efidir_grub_devname;
|
|
int efidir_is_mac = 0;
|
|
int is_prep = 0;
|
|
@@ -896,6 +991,9 @@ main (int argc, char *argv[])
|
|
bootloader_id = xstrdup ("grub");
|
|
}
|
|
|
|
+ if (removable && force_extra_removable)
|
|
+ grub_util_error (_("Invalid to use both --removable and --force_extra_removable"));
|
|
+
|
|
if (!grub_install_source_directory)
|
|
{
|
|
if (!target)
|
|
@@ -1115,6 +1213,8 @@ main (int argc, char *argv[])
|
|
if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
|
|
grub_util_error (_("%s doesn't look like an EFI partition"), efidir);
|
|
|
|
+ base_efidir = xstrdup(efidir);
|
|
+
|
|
/* The EFI specification requires that an EFI System Partition must
|
|
contain an "EFI" subdirectory, and that OS loaders are stored in
|
|
subdirectories below EFI. Vendors are expected to pick names that do
|
|
@@ -2048,9 +2148,15 @@ main (int argc, char *argv[])
|
|
fprintf (config_dst_f, "configfile $prefix/grub.cfg\n");
|
|
fclose (config_dst_f);
|
|
free (config_dst);
|
|
+ if (force_extra_removable)
|
|
+ also_install_removable(efi_signed, base_efidir, efi_suffix_upper);
|
|
}
|
|
else
|
|
- grub_install_copy_file (imgfile, dst, 1);
|
|
+ {
|
|
+ grub_install_copy_file (imgfile, dst, 1);
|
|
+ if (force_extra_removable)
|
|
+ also_install_removable(imgfile, base_efidir, efi_suffix_upper);
|
|
+ }
|
|
|
|
grub_set_install_backup_ponr ();
|
|
|