]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Reimport mbchk.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Sep 2010 15:15:37 +0000 (17:15 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Sep 2010 15:15:37 +0000 (17:15 +0200)
* util/Makefile.am: New file.
* util/mbchk.c: Likewise.
* Makefile.am (SUBDIRS): Add util.
* configure.ac: New options --enable-mbchk. Check for HELP2MAN.
(CFLAGS): Don't alter.
(COND_MAN_PAGES): New conditional.
(AC_CONFIG_FILES): Add util/Makefile.
* doc/Makefile.am (kernel_CFLAGS): Add -m32 and -nostdlib.
* doc/multiboot.texi (Invoking mbchk): New chapter.

ChangeLog
Makefile.am
configure.ac
doc/Makefile.am
doc/multiboot.texi
util/Makefile.am [new file with mode: 0644]
util/mbchk.c [new file with mode: 0644]

index 09068870f56f2b0500fa724ec5aec27b2cbd429b..1cb200f9bfcbc4dd9e3245f95031bb578c3e6d24 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-09-03  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Reimport mbchk.
+
+       * util/Makefile.am: New file.
+       * util/mbchk.c: Likewise.
+       * Makefile.am (SUBDIRS): Add util.
+       * configure.ac: New options --enable-mbchk. Check for HELP2MAN.
+       (CFLAGS): Don't alter.
+       (COND_MAN_PAGES): New conditional.
+       (AC_CONFIG_FILES): Add util/Makefile.
+       * doc/Makefile.am (kernel_CFLAGS): Add -m32 and -nostdlib.
+       * doc/multiboot.texi (Invoking mbchk): New chapter.
+
 2010-03-14  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * doc/kernel.c (cmain): Use padding to properly display 64-bit
index 70eec9cd0f4ede6f3c26694423fe75a4ba98cdc3..6d6f55ba3006326582c296f235b525ceca515618 100644 (file)
@@ -1,6 +1,6 @@
 # Do not change this order if you don't know what you are doing.
 AUTOMAKE_OPTIONS = 1.7 gnu
-SUBDIRS = doc
+SUBDIRS = doc util
 
 .PHONY: web-manual
 web-manual: all
index bf1511eba1b86e79df54c413dfaf6aadf0e37516..5482aeff83a4cee7d99eb3b0354e4e691d7150bf 100644 (file)
@@ -42,8 +42,17 @@ dnl Because recent automake complains about CCASFLAGS, set it here.
 CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
 AC_SUBST(CCASFLAGS)
 
-CFLAGS="-m32 -nostdlib $CFLAGS"
+AC_ARG_ENABLE(mbchk,
+  [  --enable-mbchk
+                          build the mbchk (multiboot checker)])
+AM_CONDITIONAL(BUILD_MBCHK, test "x$enable_mbchk" = xyes)
+
+if test "x$enable_mbchk" = xyes; then
+  AC_PATH_PROG(HELP2MAN, help2man)
+fi
+
+AM_CONDITIONAL([COND_MAN_PAGES], [test x$enable_mbchk = xyes -a x$HELP2MAN != x])
 
 dnl Output.
-AC_CONFIG_FILES([Makefile doc/Makefile])
+AC_CONFIG_FILES([Makefile doc/Makefile util/Makefile])
 AC_OUTPUT
index 787a99eca08667907705928b4ab3b2876b4da3e3..dd65301de7a8c0750b4a847965aca1aca9d662e0 100644 (file)
@@ -10,7 +10,7 @@ pkginclude_HEADERS = multiboot.h
 if BUILD_EXAMPLE_KERNEL
 noinst_PROGRAMS = kernel
 kernel_SOURCES = $(EXAMPLES)
-kernel_CFLAGS = -fno-builtin -nostdinc -O -g -Wall \
+kernel_CFLAGS = -m32 -nostdlib -fno-builtin -nostdinc -O -g -Wall \
        -imacros $(top_builddir)/config.h
 kernel_LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000 -Wl,--build-id=none
 
index 631897a15180352f271fefc07cba362922c428ba..11e8b8c5dd265029531c340f393aa67217c79464 100644 (file)
@@ -77,8 +77,9 @@ sequence standard. This edition documents version @value{VERSION}.
 * Terminology::                 
 * Specification::               
 * Examples::                    
-* History::                     
-* Index::                       
+* History::
+* Invoking mbchk::              How to use the Multiboot checker
+* Index::                  
 @end menu
 
 
@@ -1279,6 +1280,26 @@ Major changes plus HTMLification.
 @end itemize
 @end table
 
+@node Invoking mbchk
+@chapter Invoking mbchk
+
+The program @command{mbchk} checks for the format of a Multiboot
+kernel. We recommend using this program before booting your own kernel.
+
+@command{mbchk} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --quiet
+Suppress all normal output.
+@end table
+
+
 
 @node Index
 @unnumbered Index
diff --git a/util/Makefile.am b/util/Makefile.am
new file mode 100644 (file)
index 0000000..812f118
--- /dev/null
@@ -0,0 +1,17 @@
+
+HELP2MAN = @HELP2MAN@
+if COND_MAN_PAGES
+man_MANS = mbchk.1
+endif
+
+if BUILD_MBCHK
+bin_PROGRAMS = mbchk
+endif
+
+mbchk_SOURCES = mbchk.c
+mbchk_CPPFLAGS = -I$(top_srcdir)/doc 
+
+$(srcdir)/mbchk.1: ./mbchk
+       $(HELP2MAN)  \
+               --name="check the format of a Multiboot kernel" \
+               --section=1 --output=$@ ./$<
diff --git a/util/mbchk.c b/util/mbchk.c
new file mode 100644 (file)
index 0000000..766e2c4
--- /dev/null
@@ -0,0 +1,230 @@
+/* mbchk - a simple checker for the format of a Multiboot kernel */
+/*
+ *  Copyright (C) 1999,2001,2002  Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <multiboot.h>
+
+static int quiet = 0;
+static char *optstring = "hvq";
+static struct option longopts[] =
+{
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'v'},
+  {"quiet", no_argument, 0, 'q'},
+  {0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``mbchk --help'' for more information.\n");
+  else
+    printf ("Usage: mbchk [OPTION]... [FILE]...\n"
+           "Check if the format of FILE complies with the Multiboot Specification.\n"
+           "\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"
+           "Report bugs to <bug-grub@gnu.org>.\n");
+
+  exit (status);
+}
+
+static int
+check_multiboot (const char *filename, FILE *fp)
+{
+  struct multiboot_header *mbh = 0;
+  int i;
+  char buf[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++)
+    {
+      mbh = (struct multiboot_header *) (buf + i);
+      if (mbh->magic == MULTIBOOT_HEADER_MAGIC)
+       break;
+    }
+
+  if (i == 8192 - sizeof (struct multiboot_header))
+    {
+      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%lx).\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%lx).\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%lx > 0x%lx).\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%lx >= 0x%lx).\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%lx > 0x%lx).\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%lx > 0x%lx).\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%lx <= 0x%lx).\n",
+                  filename, mbh->load_end_addr, mbh->entry_addr);
+         return 0;
+       }
+    }
+
+  if (! quiet)
+    printf ("%s: All checks passed.\n", filename);
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int c;
+
+  do
+    {
+      c = getopt_long (argc, argv, optstring, longopts, 0);
+      switch (c)
+       {
+       case EOF:
+         break;
+
+       case 'h':
+         usage (0);
+         break;
+
+       case 'v':
+         printf ("mbchk (GNU GRUB " VERSION ")\n");
+         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;
+}
+