All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] add grub-mbchk utility to grub
@ 2010-08-10 15:56 Scott Moser
  2010-08-12 16:38 ` Robert Millan
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Scott Moser @ 2010-08-10 15:56 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 380 bytes --]

Hi all,
   I've been playing around with multiboot images, and found grub 0.97's
'mbchk' to be very useful.  Its really nice from a shell script or other
to easily answer "is this file a multiboot image?".

   The attached patch basically copies mbchk.c from grub-0.97 to current
bzr with minimal changes.
   Is that something that could be carried in grub2 ?

   Thanks,
   Scott

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: add grub-mbchk util --]
[-- Type: TEXT/x-diff; name=grub-mbchk.patch, Size: 7434 bytes --]

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-07-06 18:27:55 +0000
+++ conf/common.rmk	2010-08-10 14:06:23 +0000
@@ -165,6 +165,11 @@
 grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c
 CLEANFILES += grub-editenv
 
+# for grub-mbchk
+bin_UTILITIES += grub-mbchk
+grub_mbchk_SOURCES = gnulib/progname.c util/grub-mbchk.c kern/emu/misc.c util/misc.c
+CLEANFILES += grub-mbchk
+
 # Needed for genmk.rb to work
 ifeq (0,1)
 bin_UTILITIES += grub-macho2img grub-pe2elf

=== added file 'docs/man/grub-mbchk.h2m'
--- docs/man/grub-mbchk.h2m	1970-01-01 00:00:00 +0000
+++ docs/man/grub-mbchk.h2m	2010-08-10 13:31:55 +0000
@@ -0,0 +1,2 @@
+[NAME]
+grub-mbchk \- check the format of a Multiboot kernel

=== added file 'util/grub-mbchk.c'
--- util/grub-mbchk.c	1970-01-01 00:00:00 +0000
+++ util/grub-mbchk.c	2010-08-10 15:49:40 +0000
@@ -0,0 +1,260 @@
+/* grub-mbchk.c - a simple checker for the format of a Multiboot kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2001,2002,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/i18n.h>
+#include <multiboot.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "progname.h"
+
+static int quiet = 0;
+static char *optstring = "hvq";
+static struct option options[] =
+{
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"quiet", no_argument, 0, 'q'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``%s --help'' for more information.\n", program_name);
+  else
+    printf ("\
+Usage: %s [OPTION]... [FILENAME]...\n\
+Check if the format of FILENAME complies with the Multiboot Specification.\n\
+\n\
+\nOptions:\n\
+  -q, --quiet                suppress all normal output\n\
+  -h, --help                 display this help and exit\n\
+  -V, --version              output version information and exit.\n\
+\n\
+If not given explicitly, FILENAME defaults to standard input.\n\
+\n\
+Report bugs to <%s>.\n",
+program_name, PACKAGE_BUGREPORT);
+  exit (status);
+}
+
+static int
+check_multiboot (const char *filename, FILE *fp)
+{
+  struct multiboot_header *mbh = 0;
+  unsigned int i;
+  char buf[8192];
+
+  memset(buf, 0, 8192);
+
+  if (fread (buf, 1, 8192, fp) == 0)
+    {
+      fprintf (stderr, "%s: Read error.\n", filename);
+      return 0;
+    }
+
+  for (i = 0; i < 8192 - sizeof (struct multiboot_header); i++)
+    {
+      multiboot_uint32_t magic = *((multiboot_uint32_t *) (buf + i));
+
+      if (magic == MULTIBOOT_HEADER_MAGIC)
+	{
+	  mbh = (struct multiboot_header *) (buf + i);
+	  break;
+	}
+    }
+
+  if (! mbh)
+    {
+      fprintf (stderr, "%s: No Multiboot header.\n", filename);
+      return 0;
+    }
+
+  if (! quiet)
+    printf ("%s: The Multiboot header is found at the offset %d.\n",
+	    filename, i);
+
+  /* Check for the checksum.  */
+  if (mbh->magic + mbh->flags + mbh->checksum != 0)
+    {
+      fprintf (stderr,
+	       "%s: Bad checksum (0x%x).\n",
+	       filename, mbh->checksum);
+      return 0;
+    }
+
+  /* Reserved flags must be zero.  */
+  if (mbh->flags & ~0x00010003)
+    {
+      fprintf (stderr,
+	       "%s: Non-zero is found in reserved flags (0x%x).\n",
+	       filename, mbh->flags);
+      return 0;
+    }
+
+  if (! quiet)
+    {
+      printf ("%s: Page alignment is turned %s.\n",
+	      filename, (mbh->flags & 0x1)? "on" : "off");
+      printf ("%s: Memory information is turned %s.\n",
+	      filename, (mbh->flags & 0x2)? "on" : "off");
+      printf ("%s: Address fields is turned %s.\n",
+	      filename, (mbh->flags & 0x10000)? "on" : "off");
+    }
+
+  /* Check for the address fields.  */
+  if (mbh->flags & 0x10000)
+    {
+      if (mbh->header_addr < mbh->load_addr)
+	{
+	  fprintf (stderr,
+		   "%s: header_addr is less than "
+		   "load_addr (0x%x > 0x%x).\n",
+		   filename, mbh->header_addr, mbh->load_addr);
+	  return 0;
+	}
+
+      if (mbh->load_end_addr && mbh->load_addr >= mbh->load_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is not less than load_end_addr"
+		   " (0x%x >= 0x%x).\n",
+		   filename, mbh->load_addr, mbh->load_end_addr);
+	  return 0;
+	}
+
+      if (mbh->bss_end_addr && mbh->load_end_addr > mbh->bss_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is greater than bss_end_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->bss_end_addr);
+	  return 0;
+	}
+
+      if (mbh->load_addr > mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is greater than entry_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* FIXME: It is better to check if the entry address is within the
+	 file, especially when the load end address is zero.  */
+      if (mbh->load_end_addr && mbh->load_end_addr <= mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is not greater than entry_addr"
+		   " (0x%x <= 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* This is a GRUB-specific limitation.  */
+      if (mbh->load_addr < 0x100000)
+	{
+	  fprintf (stderr,
+		   "%s: Cannot be loaded at less than 1MB by GRUB"
+		   " (0x%x).\n",
+		   filename, mbh->load_addr);
+	  return 0;
+	}
+    }
+
+  if (! quiet)
+    printf ("%s: All checks passed.\n", filename);
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int c;
+
+  set_program_name (argv[0]);
+
+  grub_util_init_nls ();
+
+  do
+    {
+      c = getopt_long (argc, argv, optstring, options, 0);
+      switch (c)
+	{
+	case EOF:
+	  break;
+
+	case 'h':
+	  usage (0);
+	  break;
+
+	case 'V':
+	  printf ("%s (GNU GRUB " VERSION ")\n", program_name);
+	  exit (0);
+	  break;
+
+	case 'q':
+	  quiet = 1;
+	  break;
+
+	default:
+	  usage (1);
+	  break;
+	}
+    }
+  while (c != EOF);
+
+  if (optind < argc)
+    {
+      while (optind < argc)
+	{
+	  FILE *fp;
+
+	  fp = fopen (argv[optind], "r");
+	  if (! fp)
+	    {
+	      fprintf (stderr, "%s: No such file.\n", argv[optind]);
+	      exit (1);
+	    }
+
+	  if (! check_multiboot (argv[optind], fp))
+	    exit (1);
+
+	  fclose (fp);
+	  optind++;
+	}
+    }
+  else
+    {
+      if (! check_multiboot ("<stdin>", stdin))
+	exit (1);
+    }
+  return 0;
+}


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

* Re: [PATCH] add grub-mbchk utility to grub
  2010-08-10 15:56 [PATCH] add grub-mbchk utility to grub Scott Moser
@ 2010-08-12 16:38 ` Robert Millan
  2010-08-16 15:29   ` Scott Moser
  2010-08-12 16:40 ` Robert Millan
  2010-09-03 15:17 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 1 reply; 6+ messages in thread
From: Robert Millan @ 2010-08-12 16:38 UTC (permalink / raw)
  To: The development of GNU GRUB

2010/8/10, Scott Moser <scott.moser@canonical.com>:
> Hi all,
>    I've been playing around with multiboot images, and found grub 0.97's
> 'mbchk' to be very useful.  Its really nice from a shell script or other
> to easily answer "is this file a multiboot image?".
>
>    The attached patch basically copies mbchk.c from grub-0.97 to current
> bzr with minimal changes.
>    Is that something that could be carried in grub2 ?

I think it would make more sense in multiboot itself (multiboot package
doesn't just include documentation, there's also sample C code and
such).


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

* Re: [PATCH] add grub-mbchk utility to grub
  2010-08-10 15:56 [PATCH] add grub-mbchk utility to grub Scott Moser
  2010-08-12 16:38 ` Robert Millan
@ 2010-08-12 16:40 ` Robert Millan
  2010-09-03 15:17 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 0 replies; 6+ messages in thread
From: Robert Millan @ 2010-08-12 16:40 UTC (permalink / raw)
  To: The development of GNU GRUB

Btw I think this is not true anymore:

+      /* This is a GRUB-specific limitation.  */
+      if (mbh->load_addr < 0x100000)
+	{
+	  fprintf (stderr,
+		   "%s: Cannot be loaded at less than 1MB by GRUB"
+		   " (0x%x).\n",
+		   filename, mbh->load_addr);
+	  return 0;
+	}

-- 
Robert Millan


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

* Re: [PATCH] add grub-mbchk utility to grub
  2010-08-12 16:38 ` Robert Millan
@ 2010-08-16 15:29   ` Scott Moser
  0 siblings, 0 replies; 6+ messages in thread
From: Scott Moser @ 2010-08-16 15:29 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1249 bytes --]

On Thu, 12 Aug 2010, Robert Millan wrote:

> 2010/8/10, Scott Moser <scott.moser@canonical.com>:
> > Hi all,
> >    I've been playing around with multiboot images, and found grub 0.97's
> > 'mbchk' to be very useful.  Its really nice from a shell script or other
> > to easily answer "is this file a multiboot image?".
> >
> >    The attached patch basically copies mbchk.c from grub-0.97 to current
> > bzr with minimal changes.
> >    Is that something that could be carried in grub2 ?
>
> I think it would make more sense in multiboot itself (multiboot package
> doesn't just include documentation, there's also sample C code and
> such).

Well, I would prefer it in grub, but admittedly, that is for reasons other
than "its the best place for it".  Being part of the grub package means it
would be likely installed on systems and easy to use.  I won't disagree
that 'multiboot' is probably a better place, but will suggest that it is
less discoverable.

Attached is a patch against multiboot-0.6.96 to add a 'tools/' subdir and
'mbchk.c' to that.   The reason for the tools/ dir rather than putting it
into examples was to allow to examples/ dir to continue using '-m32' on
all c files.  I couldn't see an easy way to work around that otherwise.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: add mbchk.c too multiboot --]
[-- Type: TEXT/x-diff; name=multiboot-mbchk.patch, Size: 8822 bytes --]

Index: multiboot-0.6.96/Makefile
===================================================================
--- multiboot-0.6.96.orig/Makefile	2010-08-16 11:23:31.577581150 -0400
+++ multiboot-0.6.96/Makefile	2010-08-16 11:23:50.000000000 -0400
@@ -188,7 +188,7 @@
 
 # Do not change this order if you don't know what you are doing.
 AUTOMAKE_OPTIONS = 1.7 gnu
-SUBDIRS = docs
+SUBDIRS = docs tools
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
Index: multiboot-0.6.96/Makefile.am
===================================================================
--- multiboot-0.6.96.orig/Makefile.am	2010-08-16 11:20:26.017581151 -0400
+++ multiboot-0.6.96/Makefile.am	2010-08-16 11:23:43.247581150 -0400
@@ -1,3 +1,3 @@
 # Do not change this order if you don't know what you are doing.
 AUTOMAKE_OPTIONS = 1.7 gnu
-SUBDIRS = docs
+SUBDIRS = docs tools
Index: multiboot-0.6.96/configure.ac
===================================================================
--- multiboot-0.6.96.orig/configure.ac	2010-08-16 11:20:25.957581151 -0400
+++ multiboot-0.6.96/configure.ac	2010-08-16 11:22:24.807581151 -0400
@@ -18,7 +18,7 @@
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE
 
-CFLAGS="-m32 $CFLAGS"
+CFLAGS="$CFLAGS"
 
 #
 # Programs
@@ -46,5 +46,5 @@
 
 
 dnl Output.
-AC_CONFIG_FILES([Makefile docs/Makefile])
+AC_CONFIG_FILES([Makefile docs/Makefile tools/Makefile])
 AC_OUTPUT
Index: multiboot-0.6.96/docs/Makefile.am
===================================================================
--- multiboot-0.6.96.orig/docs/Makefile.am	2010-08-16 11:20:26.027581151 -0400
+++ multiboot-0.6.96/docs/Makefile.am	2010-08-16 11:21:48.057581151 -0400
@@ -1,3 +1,5 @@
+AM_CFLAGS = -m32
+
 info_TEXINFOS = multiboot.texi
 EXAMPLES = boot.S kernel.c multiboot.h
 multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
Index: multiboot-0.6.96/tools/Makefile.am
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ multiboot-0.6.96/tools/Makefile.am	2010-08-16 11:21:28.000000000 -0400
@@ -0,0 +1,5 @@
+bin_PROGRAMS = mbchk
+
+AM_CPPFLAGS = -I$(top_builddir)/docs
+
+mbchk_SOURCES = mbchk.c multiboot.h
Index: multiboot-0.6.96/tools/mbchk.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ multiboot-0.6.96/tools/mbchk.c	2010-08-16 11:21:28.000000000 -0400
@@ -0,0 +1,257 @@
+/* mbchk.c - a simple checker for the format of a Multiboot kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2001,2002,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <multiboot.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+const char *program_name = NULL;
+
+static int quiet = 0;
+static char *optstring = "hvq";
+static struct option options[] =
+{
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"quiet", no_argument, 0, 'q'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``%s --help'' for more information.\n", program_name);
+  else
+    printf ("\
+Usage: %s [OPTION]... [FILENAME]...\n\
+Check if the format of FILENAME complies with the Multiboot Specification.\n\
+\n\
+\nOptions:\n\
+  -q, --quiet                suppress all normal output\n\
+  -h, --help                 display this help and exit\n\
+  -V, --version              output version information and exit.\n\
+\n\
+If not given explicitly, FILENAME defaults to standard input.\n\
+\n\
+Report bugs to <%s>.\n",
+program_name, PACKAGE_BUGREPORT);
+  exit (status);
+}
+
+static int
+check_multiboot (const char *filename, FILE *fp)
+{
+  struct multiboot_header *mbh = 0;
+  unsigned int i;
+  char buf[8192];
+
+  memset(buf, 0, 8192);
+
+  if (fread (buf, 1, 8192, fp) == 0)
+    {
+      fprintf (stderr, "%s: Read error.\n", filename);
+      return 0;
+    }
+
+  for (i = 0; i < 8192 - sizeof (struct multiboot_header); i++)
+    {
+      multiboot_uint32_t magic = *((multiboot_uint32_t *) (buf + i));
+
+      if (magic == MULTIBOOT_HEADER_MAGIC)
+	{
+	  mbh = (struct multiboot_header *) (buf + i);
+	  break;
+	}
+    }
+
+  if (! mbh)
+    {
+      fprintf (stderr, "%s: No Multiboot header.\n", filename);
+      return 0;
+    }
+
+  if (! quiet)
+    printf ("%s: The Multiboot header is found at the offset %d.\n",
+	    filename, i);
+
+  /* Check for the checksum.  */
+  if (mbh->magic + mbh->flags + mbh->checksum != 0)
+    {
+      fprintf (stderr,
+	       "%s: Bad checksum (0x%x).\n",
+	       filename, mbh->checksum);
+      return 0;
+    }
+
+  /* Reserved flags must be zero.  */
+  if (mbh->flags & ~0x00010003)
+    {
+      fprintf (stderr,
+	       "%s: Non-zero is found in reserved flags (0x%x).\n",
+	       filename, mbh->flags);
+      return 0;
+    }
+
+  if (! quiet)
+    {
+      printf ("%s: Page alignment is turned %s.\n",
+	      filename, (mbh->flags & 0x1)? "on" : "off");
+      printf ("%s: Memory information is turned %s.\n",
+	      filename, (mbh->flags & 0x2)? "on" : "off");
+      printf ("%s: Address fields is turned %s.\n",
+	      filename, (mbh->flags & 0x10000)? "on" : "off");
+    }
+
+  /* Check for the address fields.  */
+  if (mbh->flags & 0x10000)
+    {
+      if (mbh->header_addr < mbh->load_addr)
+	{
+	  fprintf (stderr,
+		   "%s: header_addr is less than "
+		   "load_addr (0x%x > 0x%x).\n",
+		   filename, mbh->header_addr, mbh->load_addr);
+	  return 0;
+	}
+
+      if (mbh->load_end_addr && mbh->load_addr >= mbh->load_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is not less than load_end_addr"
+		   " (0x%x >= 0x%x).\n",
+		   filename, mbh->load_addr, mbh->load_end_addr);
+	  return 0;
+	}
+
+      if (mbh->bss_end_addr && mbh->load_end_addr > mbh->bss_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is greater than bss_end_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->bss_end_addr);
+	  return 0;
+	}
+
+      if (mbh->load_addr > mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is greater than entry_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* FIXME: It is better to check if the entry address is within the
+	 file, especially when the load end address is zero.  */
+      if (mbh->load_end_addr && mbh->load_end_addr <= mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is not greater than entry_addr"
+		   " (0x%x <= 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* This is a GRUB-specific limitation.  */
+      if (mbh->load_addr < 0x100000)
+	{
+	  fprintf (stderr,
+		   "%s: Cannot be loaded at less than 1MB by GRUB"
+		   " (0x%x).\n",
+		   filename, mbh->load_addr);
+	  return 0;
+	}
+    }
+
+  if (! quiet)
+    printf ("%s: All checks passed.\n", filename);
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int c;
+
+  program_name = "mbchk";
+
+  do
+    {
+      c = getopt_long (argc, argv, optstring, options, 0);
+      switch (c)
+	{
+	case EOF:
+	  break;
+
+	case 'h':
+	  usage (0);
+	  break;
+
+	case 'V':
+	  printf ("%s (GNU GRUB " VERSION ")\n", program_name);
+	  exit (0);
+	  break;
+
+	case 'q':
+	  quiet = 1;
+	  break;
+
+	default:
+	  usage (1);
+	  break;
+	}
+    }
+  while (c != EOF);
+
+  if (optind < argc)
+    {
+      while (optind < argc)
+	{
+	  FILE *fp;
+
+	  fp = fopen (argv[optind], "r");
+	  if (! fp)
+	    {
+	      fprintf (stderr, "%s: No such file.\n", argv[optind]);
+	      exit (1);
+	    }
+
+	  if (! check_multiboot (argv[optind], fp))
+	    exit (1);
+
+	  fclose (fp);
+	  optind++;
+	}
+    }
+  else
+    {
+      if (! check_multiboot ("<stdin>", stdin))
+	exit (1);
+    }
+  return 0;
+}
+
+

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

* Re: [PATCH] add grub-mbchk utility to grub
  2010-08-10 15:56 [PATCH] add grub-mbchk utility to grub Scott Moser
  2010-08-12 16:38 ` Robert Millan
  2010-08-12 16:40 ` Robert Millan
@ 2010-09-03 15:17 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 0 replies; 6+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-09-03 15:17 UTC (permalink / raw)
  To: grub-devel

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

On 08/10/2010 05:56 PM, Scott Moser wrote:
> Hi all,
>    I've been playing around with multiboot images, and found grub 0.97's
> 'mbchk' to be very useful.  Its really nice from a shell script or other
> to easily answer "is this file a multiboot image?".
>
>   
I remerged mbchk into multiboot using the files from legacy (not using
your patch)
>    The attached patch basically copies mbchk.c from grub-0.97 to current
> bzr with minimal changes.
>    Is that something that could be carried in grub2 ?
>
>    Thanks,
>    Scott
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

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

* [PATCH] add grub-mbchk utility to grub
@ 2010-08-11 15:06 Scott Moser
  0 siblings, 0 replies; 6+ messages in thread
From: Scott Moser @ 2010-08-11 15:06 UTC (permalink / raw)
  To: Grub-devel list

[-- Attachment #1: Type: TEXT/PLAIN, Size: 452 bytes --]

To: grub-devel@gnu.org
Subject: [PATCH] add grub-mbchk utility to grub

Hi all,
   I've been playing around with multiboot images, and found grub 0.97's
'mbchk' to be very useful.  Its really nice from a shell script or other
to easily answer "is this file a multiboot image?".

   The attached patch basically copies mbchk.c from grub-0.97 to current
bzr with minimal changes.
   Is that something that could be carried in grub2 ?

   Thanks,
   Scott

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: add grub-mbchk.patch --]
[-- Type: TEXT/x-diff; name=grub-mbchk.patch, Size: 7434 bytes --]

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-07-06 18:27:55 +0000
+++ conf/common.rmk	2010-08-10 14:06:23 +0000
@@ -165,6 +165,11 @@
 grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c
 CLEANFILES += grub-editenv
 
+# for grub-mbchk
+bin_UTILITIES += grub-mbchk
+grub_mbchk_SOURCES = gnulib/progname.c util/grub-mbchk.c kern/emu/misc.c util/misc.c
+CLEANFILES += grub-mbchk
+
 # Needed for genmk.rb to work
 ifeq (0,1)
 bin_UTILITIES += grub-macho2img grub-pe2elf

=== added file 'docs/man/grub-mbchk.h2m'
--- docs/man/grub-mbchk.h2m	1970-01-01 00:00:00 +0000
+++ docs/man/grub-mbchk.h2m	2010-08-10 13:31:55 +0000
@@ -0,0 +1,2 @@
+[NAME]
+grub-mbchk \- check the format of a Multiboot kernel

=== added file 'util/grub-mbchk.c'
--- util/grub-mbchk.c	1970-01-01 00:00:00 +0000
+++ util/grub-mbchk.c	2010-08-10 15:49:40 +0000
@@ -0,0 +1,260 @@
+/* grub-mbchk.c - a simple checker for the format of a Multiboot kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2001,2002,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/i18n.h>
+#include <multiboot.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "progname.h"
+
+static int quiet = 0;
+static char *optstring = "hvq";
+static struct option options[] =
+{
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"quiet", no_argument, 0, 'q'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``%s --help'' for more information.\n", program_name);
+  else
+    printf ("\
+Usage: %s [OPTION]... [FILENAME]...\n\
+Check if the format of FILENAME complies with the Multiboot Specification.\n\
+\n\
+\nOptions:\n\
+  -q, --quiet                suppress all normal output\n\
+  -h, --help                 display this help and exit\n\
+  -V, --version              output version information and exit.\n\
+\n\
+If not given explicitly, FILENAME defaults to standard input.\n\
+\n\
+Report bugs to <%s>.\n",
+program_name, PACKAGE_BUGREPORT);
+  exit (status);
+}
+
+static int
+check_multiboot (const char *filename, FILE *fp)
+{
+  struct multiboot_header *mbh = 0;
+  unsigned int i;
+  char buf[8192];
+
+  memset(buf, 0, 8192);
+
+  if (fread (buf, 1, 8192, fp) == 0)
+    {
+      fprintf (stderr, "%s: Read error.\n", filename);
+      return 0;
+    }
+
+  for (i = 0; i < 8192 - sizeof (struct multiboot_header); i++)
+    {
+      multiboot_uint32_t magic = *((multiboot_uint32_t *) (buf + i));
+
+      if (magic == MULTIBOOT_HEADER_MAGIC)
+	{
+	  mbh = (struct multiboot_header *) (buf + i);
+	  break;
+	}
+    }
+
+  if (! mbh)
+    {
+      fprintf (stderr, "%s: No Multiboot header.\n", filename);
+      return 0;
+    }
+
+  if (! quiet)
+    printf ("%s: The Multiboot header is found at the offset %d.\n",
+	    filename, i);
+
+  /* Check for the checksum.  */
+  if (mbh->magic + mbh->flags + mbh->checksum != 0)
+    {
+      fprintf (stderr,
+	       "%s: Bad checksum (0x%x).\n",
+	       filename, mbh->checksum);
+      return 0;
+    }
+
+  /* Reserved flags must be zero.  */
+  if (mbh->flags & ~0x00010003)
+    {
+      fprintf (stderr,
+	       "%s: Non-zero is found in reserved flags (0x%x).\n",
+	       filename, mbh->flags);
+      return 0;
+    }
+
+  if (! quiet)
+    {
+      printf ("%s: Page alignment is turned %s.\n",
+	      filename, (mbh->flags & 0x1)? "on" : "off");
+      printf ("%s: Memory information is turned %s.\n",
+	      filename, (mbh->flags & 0x2)? "on" : "off");
+      printf ("%s: Address fields is turned %s.\n",
+	      filename, (mbh->flags & 0x10000)? "on" : "off");
+    }
+
+  /* Check for the address fields.  */
+  if (mbh->flags & 0x10000)
+    {
+      if (mbh->header_addr < mbh->load_addr)
+	{
+	  fprintf (stderr,
+		   "%s: header_addr is less than "
+		   "load_addr (0x%x > 0x%x).\n",
+		   filename, mbh->header_addr, mbh->load_addr);
+	  return 0;
+	}
+
+      if (mbh->load_end_addr && mbh->load_addr >= mbh->load_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is not less than load_end_addr"
+		   " (0x%x >= 0x%x).\n",
+		   filename, mbh->load_addr, mbh->load_end_addr);
+	  return 0;
+	}
+
+      if (mbh->bss_end_addr && mbh->load_end_addr > mbh->bss_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is greater than bss_end_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->bss_end_addr);
+	  return 0;
+	}
+
+      if (mbh->load_addr > mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is greater than entry_addr"
+		   " (0x%x > 0x%x).\n",
+		   filename, mbh->load_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* FIXME: It is better to check if the entry address is within the
+	 file, especially when the load end address is zero.  */
+      if (mbh->load_end_addr && mbh->load_end_addr <= mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is not greater than entry_addr"
+		   " (0x%x <= 0x%x).\n",
+		   filename, mbh->load_end_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* This is a GRUB-specific limitation.  */
+      if (mbh->load_addr < 0x100000)
+	{
+	  fprintf (stderr,
+		   "%s: Cannot be loaded at less than 1MB by GRUB"
+		   " (0x%x).\n",
+		   filename, mbh->load_addr);
+	  return 0;
+	}
+    }
+
+  if (! quiet)
+    printf ("%s: All checks passed.\n", filename);
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int c;
+
+  set_program_name (argv[0]);
+
+  grub_util_init_nls ();
+
+  do
+    {
+      c = getopt_long (argc, argv, optstring, options, 0);
+      switch (c)
+	{
+	case EOF:
+	  break;
+
+	case 'h':
+	  usage (0);
+	  break;
+
+	case 'V':
+	  printf ("%s (GNU GRUB " VERSION ")\n", program_name);
+	  exit (0);
+	  break;
+
+	case 'q':
+	  quiet = 1;
+	  break;
+
+	default:
+	  usage (1);
+	  break;
+	}
+    }
+  while (c != EOF);
+
+  if (optind < argc)
+    {
+      while (optind < argc)
+	{
+	  FILE *fp;
+
+	  fp = fopen (argv[optind], "r");
+	  if (! fp)
+	    {
+	      fprintf (stderr, "%s: No such file.\n", argv[optind]);
+	      exit (1);
+	    }
+
+	  if (! check_multiboot (argv[optind], fp))
+	    exit (1);
+
+	  fclose (fp);
+	  optind++;
+	}
+    }
+  else
+    {
+      if (! check_multiboot ("<stdin>", stdin))
+	exit (1);
+    }
+  return 0;
+}


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

end of thread, other threads:[~2010-09-03 15:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-10 15:56 [PATCH] add grub-mbchk utility to grub Scott Moser
2010-08-12 16:38 ` Robert Millan
2010-08-16 15:29   ` Scott Moser
2010-08-12 16:40 ` Robert Millan
2010-09-03 15:17 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-11 15:06 Scott Moser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.