From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Vq6v9-0005lT-0r for mharc-grub-devel@gnu.org; Mon, 09 Dec 2013 14:55:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37702) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vq6v4-0005h9-5P for grub-devel@gnu.org; Mon, 09 Dec 2013 14:55:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vq6v0-00033f-Ih for grub-devel@gnu.org; Mon, 09 Dec 2013 14:55:06 -0500 Received: from mail-oa0-x249.google.com ([2607:f8b0:4003:c02::249]:43025) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vq6v0-00031c-84 for grub-devel@gnu.org; Mon, 09 Dec 2013 14:55:02 -0500 Received: by mail-oa0-f73.google.com with SMTP id i4so786707oah.4 for ; Mon, 09 Dec 2013 11:55:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=2weZQm0XVu60UU3BMLKa6JPR9z1uFdKHoRxII8IMtNU=; b=e1YZnvzWpwHtXBpj0jr3I7xYxv3P5jaOu+a9AUi3+gj5UA264ue3fLbnw1HpsRSVQr N4vMJbauWDvk3nq89y2HElHwldlQcRzqtcixh4TRdBuqpqLw2DokAyP+q4uMvWnBSanY iMMRhbJ9KxBYt4vpaoOXf9qJ2kF6G2qfuhXeZZHEp/JPxpZM9qHjlgaqabbEHaTU5Bsu IP9EygtoA8xKeXZtbtfO/f3+JyROao1T9EyowmEfjk+L557hbNNyOhIhtEe5emvWdh8f vviPQ79EaELLI9X7x6j5TsUFyRR9k0U17Q0LTBgoxsf6LlJKoZ22EiDJFx8UqFhoH6CX emwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=2weZQm0XVu60UU3BMLKa6JPR9z1uFdKHoRxII8IMtNU=; b=bE7UfZR9LTL+nTRRj9aQ9hPCX8lxtgdsvkZbiZ6r28wc88ZmDRLr1QbSB1+ft4LBfy Ui61As0mHSRf19mHWS7k5kfl9PBMA4OdTC3SHiEuzeQfq9ZnP5clG7sfN231HCafR4nT DykL2uhRDJvooO/J6iSWfInOtynRRmEKERVfU5J4Sguik8BRGxCBYk/EWCP990R6MomC CTOLIpQsH+DTIYuw48ZiPjFVDJJHADrAzCoyQMS92DpmzqaD5E9a7/Xr+UwLEv6C992S y7MHsbdedc56mw3zB9gjTMOcrqmwA0wjDj6/EkksDjOMZ6h3qSckUi1nFLzYkZ53A84M o+Cg== X-Gm-Message-State: ALoCoQnukRSWbdGor8hsSUOkKO5GMthl01hMCDxtYG9a0J1IAsf9sxO7DEIXcUva19pZtnRRdUCBYaf0ZVzYiKxsCw/3f+wcpqZFu65Vvzf8y04KLgfw/gqebYruU1G1Hc4gsX6iUj951w1CwHX8c9mYyltd5yIdZ5E3SpYP2PgrByTSaGtjEKstaOb2ZnnaQ4kVMTfnP2nXiLfArpjUgguaOSD8vnJi09n19wxE1oRlehP6M06qGuc= X-Received: by 10.182.108.136 with SMTP id hk8mr7237063obb.11.1386618901042; Mon, 09 Dec 2013 11:55:01 -0800 (PST) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id l41si13797126yhi.5.2013.12.09.11.55.01 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Dec 2013 11:55:01 -0800 (PST) Received: from yinz.mtv.corp.google.com (yinz.mtv.corp.google.com [172.17.81.122]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id CBE865A41B3; Mon, 9 Dec 2013 11:55:00 -0800 (PST) Received: by yinz.mtv.corp.google.com (Postfix, from userid 184367) id 67589C2593; Mon, 9 Dec 2013 11:55:00 -0800 (PST) From: Jon McCune To: grub-devel@gnu.org Subject: [PATCH v4] Support to disable reed-solomon codes Date: Mon, 9 Dec 2013 11:54:57 -0800 Message-Id: <1386618897-17163-1-git-send-email-jonmccune@google.com> X-Mailer: git-send-email 1.8.5.1 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c02::249 Cc: Jon McCune X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Dec 2013 19:55:08 -0000 [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 --- 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