grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4] Support to disable reed-solomon codes
@ 2013-12-09 19:54 Jon McCune
  2013-12-09 23:23 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 2+ messages in thread
From: Jon McCune @ 2013-12-09 19:54 UTC (permalink / raw)
  To: grub-devel; +Cc: Jon McCune

 [v0] new grub-*-setup flag to disable insertion of reed solomon codes
 [v0] grub-install support for option --no-rs-codes
 [v1] bugfix: also change the maxsec value in util/setup.c
 [v2] Modified to support new C-language install utilities, added documentation
 [v3] Incorporate feedback from ML. Most significant changes:
      Clarify Reed Solomon code behavior in documentation
      Use positive logic within code
      Move core.img version check outside add_rs_codes conditional
 [v4] Use enum and start from 0x100 for no-short-form option
      Zero extra memory returned by realloc() prior to use

Signed-off-by: Jon McCune <jonmccune@google.com>
---
 docs/grub.texi              | 14 +++++++++++++-
 include/grub/util/install.h |  6 ++++--
 util/grub-install.c         | 19 +++++++++++++++----
 util/grub-setup.c           | 19 +++++++++++++++++--
 util/setup.c                | 39 ++++++++++++++++++++++++++-------------
 5 files changed, 75 insertions(+), 22 deletions(-)

diff --git a/docs/grub.texi b/docs/grub.texi
index 54b02fd..91fa1de 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5994,8 +5994,20 @@ mounted on
 Recheck the device map, even if @file{/boot/grub/device.map} already
 exists. You should use this option whenever you add/remove a disk
 into/from your computer.
-@end table
 
+@item --no-rs-codes
+By default on x86 BIOS systems, @command{grub-install} will use some
+extra space in the bootloader embedding area for Reed-Solomon
+error-correcting codes. This enables GRUB to still boot successfully
+if some blocks are corrupted.  The exact amount of protection offered
+is dependent on available space in the embedding area.  R sectors of
+redundancy can tolerate up to R/2 corrupted sectors. This
+redundancy may be cumbersome if attempting to cryptographically
+validate the contents of the bootloader embedding area, or in more
+modern systems with GPT-style partition tables (@pxref{BIOS
+installation}) where GRUB does not reside in any unpartitioned space
+outside of the MBR.  Disable the Reed-Solomon codes with this option.
+@end table
 
 @node Invoking grub-mkconfig
 @chapter Invoking grub-mkconfig
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index beca2d2..20626d4 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -183,12 +183,14 @@ void
 grub_util_bios_setup (const char *dir,
 		      const char *boot_file, const char *core_file,
 		      const char *dest, int force,
-		      int fs_probe, int allow_floppy);
+		      int fs_probe, int allow_floppy,
+		      int add_rs_codes);
 void
 grub_util_sparc_setup (const char *dir,
 		       const char *boot_file, const char *core_file,
 		       const char *dest, int force,
-		       int fs_probe, int allow_floppy);
+		       int fs_probe, int allow_floppy,
+		       int add_rs_codes);
 
 char *
 grub_install_get_image_targets_string (void);
diff --git a/util/grub-install.c b/util/grub-install.c
index 0aa7f48..5d22f90 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -68,6 +68,7 @@ static int have_load_cfg = 0;
 static FILE * load_cfg_f = NULL;
 static char *load_cfg;
 static int install_bootsector = 1;
+static int add_rs_codes = 1;
 
 enum
   {
@@ -93,7 +94,8 @@ enum
     OPTION_DEBUG_IMAGE,
     OPTION_NO_FLOPPY,
     OPTION_DISK_MODULE,
-    OPTION_NO_BOOTSECTOR
+    OPTION_NO_BOOTSECTOR,
+    OPTION_NO_RS_CODES,
   };
 
 static int fs_probe = 1;
@@ -180,6 +182,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
       install_bootsector = 0;
       return 0;
 
+    case OPTION_NO_RS_CODES:
+      add_rs_codes = 0;
+      return 0;
+
     case OPTION_DEBUG:
       verbosity++;
       return 0;
@@ -238,6 +244,9 @@ static struct argp_option options[] = {
    N_("do not probe for filesystems in DEVICE"), 0},
   {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
    N_("do not install bootsector"), 0},
+  {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0,
+   N_("Do not apply any reed-solomon codes when embedding core.img. "
+      "This option is only available on x86 BIOS targets."), 0},
 
   {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
   {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
@@ -1435,12 +1444,13 @@ main (int argc, char *argv[])
 					      "boot.img");
 	grub_install_copy_file (boot_img_src, boot_img, 1);
 
-	grub_util_info ("%sgrub-bios-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
+	grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'",
 			install_bootsector ? "" : "NOT RUNNING: ",
 			allow_floppy ? "--allow-floppy " : "",
 			verbosity ? "--verbose " : "",
 			force ? "--force " : "",
 			!fs_probe ? "--skip-fs-probe" : "",
+			!add_rs_codes ? "--no-rs-codes" : "",
 			platdir,
 			device_map,
 			install_device);
@@ -1449,7 +1459,7 @@ main (int argc, char *argv[])
 	if (install_bootsector)
 	  grub_util_bios_setup (platdir, "boot.img", "core.img",
 				install_drive, force,
-				fs_probe, allow_floppy);
+				fs_probe, allow_floppy, add_rs_codes);
 	break;
       }
     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
@@ -1475,7 +1485,8 @@ main (int argc, char *argv[])
 	if (install_bootsector)
 	  grub_util_sparc_setup (platdir, "boot.img", "core.img",
 				 install_device, force,
-				 fs_probe, allow_floppy);
+				 fs_probe, allow_floppy,
+				 0 /* unused */ );
 	break;
       }
 
diff --git a/util/grub-setup.c b/util/grub-setup.c
index 90b9de0..7a6ca78 100644
--- a/util/grub-setup.c
+++ b/util/grub-setup.c
@@ -64,6 +64,12 @@
 #define DEFAULT_BOOT_FILE	"boot.img"
 #define DEFAULT_CORE_FILE	"core.img"
 
+/* Non-printable "keys" for arguments with no short form.
+ * See grub-core/gnulib/argp.h for details. */
+enum {
+  NO_RS_CODES_KEY = 0x100,
+};
+
 static struct argp_option options[] = {
   {"boot-image",  'b', N_("FILE"), 0,
    N_("use FILE as the boot image [default=%s]"), 0},
@@ -82,7 +88,9 @@ static struct argp_option options[] = {
    /* TRANSLATORS: The potential breakage isn't limited to floppies but it's
       likely to make the install unbootable from HDD.  */
    N_("make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0},
-
+  {"no-rs-codes", NO_RS_CODES_KEY, 0,      0,
+   N_("Do not apply any reed-solomon codes when embedding core.img. "
+      "This option is only available on x86 BIOS targets."), 0},
   { 0, 0, 0, 0, 0, 0 }
 };
 
@@ -118,6 +126,7 @@ struct arguments
   int  fs_probe;
   int allow_floppy;
   char *device;
+  int add_rs_codes;
 };
 
 static error_t
@@ -173,6 +182,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
         verbosity++;
         break;
 
+      case NO_RS_CODES_KEY:
+        arguments->add_rs_codes = 0;
+        break;
+
       case ARGP_KEY_ARG:
         if (state->arg_num == 0)
           arguments->device = xstrdup(arg);
@@ -233,6 +246,7 @@ main (int argc, char *argv[])
   /* Default option values. */
   memset (&arguments, 0, sizeof (struct arguments));
   arguments.fs_probe  = 1;
+  arguments.add_rs_codes = 1;
 
   /* Parse our arguments */
   if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
@@ -292,7 +306,8 @@ main (int argc, char *argv[])
 		   arguments.boot_file ? : DEFAULT_BOOT_FILE,
 		   arguments.core_file ? : DEFAULT_CORE_FILE,
 		   dest_dev, arguments.force,
-		   arguments.fs_probe, arguments.allow_floppy);
+		   arguments.fs_probe, arguments.allow_floppy,
+		   arguments.add_rs_codes);
 
   /* Free resources.  */
   grub_fini_all ();
diff --git a/util/setup.c b/util/setup.c
index 337c304..682b320 100644
--- a/util/setup.c
+++ b/util/setup.c
@@ -248,7 +248,8 @@ void
 SETUP (const char *dir,
        const char *boot_file, const char *core_file,
        const char *dest, int force,
-       int fs_probe, int allow_floppy)
+       int fs_probe, int allow_floppy,
+       int add_rs_codes __attribute__ ((unused))) /* unused on sparc64 */
 {
   char *core_path;
   char *boot_img, *core_img, *boot_path;
@@ -486,7 +487,11 @@ SETUP (const char *dir,
 
     nsec = core_sectors;
 
-    maxsec = 2 * core_sectors;
+    if (add_rs_codes)
+      maxsec = 2 * core_sectors;
+    else
+      maxsec = core_sectors;
+
     if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 		>> GRUB_DISK_SECTOR_BITS))
       maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
@@ -543,15 +548,16 @@ SETUP (const char *dir,
 
     write_rootdev (root_dev, boot_img, bl.first_sector);
 
+    /* Round up to the nearest sector boundary, and zero the extra memory */
     core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
+    assert (core_img && (nsec * GRUB_DISK_SECTOR_SIZE >= core_size));
+    memset (core_img + core_size, 0, nsec * GRUB_DISK_SECTOR_SIZE - core_size);
+
     bl.first_block = (struct grub_boot_blocklist *) (core_img
 						     + GRUB_DISK_SECTOR_SIZE
 						     - sizeof (*bl.block));
 
     grub_size_t no_rs_length;
-    grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE
-			   + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY),
-			  grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size));
     no_rs_length = grub_target_to_host16 
       (grub_get_unaligned16 (core_img
 			     + GRUB_DISK_SECTOR_SIZE
@@ -560,14 +566,21 @@ SETUP (const char *dir,
     if (no_rs_length == 0xffff)
       grub_util_error ("%s", _("core.img version mismatch"));
 
-    void *tmp = xmalloc (core_size);
-    grub_memcpy (tmp, core_img, core_size);
-    grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE,
-				      core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE,
-				      nsec * GRUB_DISK_SECTOR_SIZE
-				      - core_size);
-    assert (grub_memcmp (tmp, core_img, core_size) == 0);
-    free (tmp);
+    if (add_rs_codes)
+      {
+	grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE
+			       + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY),
+			      grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size));
+
+	void *tmp = xmalloc (core_size);
+	grub_memcpy (tmp, core_img, core_size);
+	grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE,
+					  core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE,
+					  nsec * GRUB_DISK_SECTOR_SIZE
+					  - core_size);
+	assert (grub_memcmp (tmp, core_img, core_size) == 0);
+	free (tmp);
+      }
 
     /* Write the core image onto the disk.  */
     for (i = 0; i < nsec; i++)
-- 
1.8.5.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v4] Support to disable reed-solomon codes
  2013-12-09 19:54 [PATCH v4] Support to disable reed-solomon codes Jon McCune
@ 2013-12-09 23:23 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-12-09 23:23 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 300 bytes --]

> +    /* Round up to the nearest sector boundary, and zero the extra memory */
>      core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
> +    assert (core_img && (nsec * GRUB_DISK_SECTOR_SIZE >= core_size));
Can you change that to xrealloc while on it?
Other than this, go ahead.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-12-09 23:23 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-09 19:54 [PATCH v4] Support to disable reed-solomon codes Jon McCune
2013-12-09 23:23 ` Vladimir 'φ-coder/phcoder' Serbinenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).