[2005] 2009-02-27 Robert Millan <[email protected]>

Robert Millan <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2005
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2005
Author:   robertmh
Date:     2009-02-27 21:19:00 +0000 (Fri, 27 Feb 2009)
Log Message:
-----------
2009-02-27  Robert Millan  <[email protected]>

        * loader/i386/pc/multiboot.c: Move from here ...
        * loader/i386/multiboot.c: ... to here.  Update all users.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/DISTLIST
    trunk/grub2/conf/i386-coreboot.mk
    trunk/grub2/conf/i386-coreboot.rmk
    trunk/grub2/conf/i386-pc.mk
    trunk/grub2/conf/i386-pc.rmk

Added Paths:
-----------
    trunk/grub2/loader/i386/multiboot.c

Removed Paths:
-------------
    trunk/grub2/loader/i386/pc/multiboot.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/ChangeLog	2009-02-27 21:19:00 UTC (rev 2005)
@@ -1,5 +1,10 @@
 2009-02-27  Robert Millan  <[email protected]>
 
+	* loader/i386/pc/multiboot.c: Move from here ...
+	* loader/i386/multiboot.c: ... to here.  Update all users.
+
+2009-02-27  Robert Millan  <[email protected]>
+
 	Patch from Alexandre Bique <[email protected]>
 	* util/i386/pc/grub-setup.c (setup): Fix directory path.
 

Modified: trunk/grub2/DISTLIST
===================================================================
--- trunk/grub2/DISTLIST	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/DISTLIST	2009-02-27 21:19:00 UTC (rev 2005)
@@ -385,13 +385,15 @@
 loader/i386/bsd.c
 loader/i386/bsd_normal.c
 loader/i386/linux.c
+loader/i386/multiboot.c
 loader/i386/efi/linux.c
 loader/i386/ieee1275/linux.c
 loader/i386/pc/chainloader.c
 loader/i386/pc/chainloader_normal.c
 loader/i386/pc/linux.c
-loader/i386/pc/multiboot.c
 loader/i386/pc/multiboot2.c
+loader/i386/pc/multiboot_elf32.c
+loader/i386/pc/multiboot_elf64.c
 loader/i386/pc/multiboot_normal.c
 loader/ieee1275/multiboot2.c
 loader/powerpc/ieee1275/linux.c

Modified: trunk/grub2/conf/i386-coreboot.mk
===================================================================
--- trunk/grub2/conf/i386-coreboot.mk	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/conf/i386-coreboot.mk	2009-02-27 21:19:00 UTC (rev 2005)
@@ -1296,16 +1296,16 @@
 serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For _multiboot.mod.
-_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \
+_multiboot_mod_SOURCES = loader/i386/multiboot.c \
                          loader/i386/pc/multiboot2.c \
                          loader/multiboot2.c \
                          loader/multiboot_loader.c
-CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst
+CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst
 ifneq ($(_multiboot_mod_EXPORTS),no)
 CLEANFILES += def-_multiboot.lst
 DEFSYMFILES += def-_multiboot.lst
 endif
-MOSTLYCLEANFILES += _multiboot_mod-loader_i386_pc_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d
+MOSTLYCLEANFILES += _multiboot_mod-loader_i386_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d
 UNDSYMFILES += und-_multiboot.lst
 
 _multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF)
@@ -1314,9 +1314,9 @@
 	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
 	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
 
-pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
+pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
 	-rm -f $@
-	$(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
+	$(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
 
 mod-_multiboot.o: mod-_multiboot.c
 	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $<
@@ -1333,23 +1333,23 @@
 	echo '_multiboot' > $@
 	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
 
-_multiboot_mod-loader_i386_pc_multiboot.o: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES)
-	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $<
--include _multiboot_mod-loader_i386_pc_multiboot.d
+_multiboot_mod-loader_i386_multiboot.o: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include _multiboot_mod-loader_i386_multiboot.d
 
-CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst fs-_multiboot_mod-loader_i386_pc_multiboot.lst partmap-_multiboot_mod-loader_i386_pc_multiboot.lst
-COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst
-FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot.lst
-PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot.lst
+CLEANFILES += cmd-_multiboot_mod-loader_i386_multiboot.lst fs-_multiboot_mod-loader_i386_multiboot.lst partmap-_multiboot_mod-loader_i386_multiboot.lst
+COMMANDFILES += cmd-_multiboot_mod-loader_i386_multiboot.lst
+FSFILES += fs-_multiboot_mod-loader_i386_multiboot.lst
+PARTMAPFILES += partmap-_multiboot_mod-loader_i386_multiboot.lst
 
-cmd-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) gencmdlist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1)
+cmd-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
-fs-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genfslist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1)
+fs-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
-partmap-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genpartmaplist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1)
+partmap-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
 
 _multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES)

Modified: trunk/grub2/conf/i386-coreboot.rmk
===================================================================
--- trunk/grub2/conf/i386-coreboot.rmk	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/conf/i386-coreboot.rmk	2009-02-27 21:19:00 UTC (rev 2005)
@@ -149,7 +149,7 @@
 serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For _multiboot.mod.
-_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \
+_multiboot_mod_SOURCES = loader/i386/multiboot.c \
                          loader/i386/pc/multiboot2.c \
                          loader/multiboot2.c \
                          loader/multiboot_loader.c

Modified: trunk/grub2/conf/i386-pc.mk
===================================================================
--- trunk/grub2/conf/i386-pc.mk	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/conf/i386-pc.mk	2009-02-27 21:19:00 UTC (rev 2005)
@@ -1816,16 +1816,16 @@
 serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For _multiboot.mod.
-_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \
+_multiboot_mod_SOURCES = loader/i386/multiboot.c \
                          loader/i386/pc/multiboot2.c \
                          loader/multiboot2.c \
                          loader/multiboot_loader.c
-CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst
+CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst
 ifneq ($(_multiboot_mod_EXPORTS),no)
 CLEANFILES += def-_multiboot.lst
 DEFSYMFILES += def-_multiboot.lst
 endif
-MOSTLYCLEANFILES += _multiboot_mod-loader_i386_pc_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d
+MOSTLYCLEANFILES += _multiboot_mod-loader_i386_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d
 UNDSYMFILES += und-_multiboot.lst
 
 _multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF)
@@ -1834,9 +1834,9 @@
 	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
 	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
 
-pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
+pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
 	-rm -f $@
-	$(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
+	$(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o
 
 mod-_multiboot.o: mod-_multiboot.c
 	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $<
@@ -1853,23 +1853,23 @@
 	echo '_multiboot' > $@
 	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
 
-_multiboot_mod-loader_i386_pc_multiboot.o: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES)
-	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $<
--include _multiboot_mod-loader_i386_pc_multiboot.d
+_multiboot_mod-loader_i386_multiboot.o: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include _multiboot_mod-loader_i386_multiboot.d
 
-CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst fs-_multiboot_mod-loader_i386_pc_multiboot.lst partmap-_multiboot_mod-loader_i386_pc_multiboot.lst
-COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst
-FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot.lst
-PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot.lst
+CLEANFILES += cmd-_multiboot_mod-loader_i386_multiboot.lst fs-_multiboot_mod-loader_i386_multiboot.lst partmap-_multiboot_mod-loader_i386_multiboot.lst
+COMMANDFILES += cmd-_multiboot_mod-loader_i386_multiboot.lst
+FSFILES += fs-_multiboot_mod-loader_i386_multiboot.lst
+PARTMAPFILES += partmap-_multiboot_mod-loader_i386_multiboot.lst
 
-cmd-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) gencmdlist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1)
+cmd-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
-fs-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genfslist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1)
+fs-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
-partmap-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genpartmaplist.sh
-	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1)
+partmap-_multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1)
 
 
 _multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES)

Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/conf/i386-pc.rmk	2009-02-27 21:19:00 UTC (rev 2005)
@@ -237,7 +237,7 @@
 serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For _multiboot.mod.
-_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \
+_multiboot_mod_SOURCES = loader/i386/multiboot.c \
                          loader/i386/pc/multiboot2.c \
                          loader/multiboot2.c \
                          loader/multiboot_loader.c

Copied: trunk/grub2/loader/i386/multiboot.c (from rev 2001, trunk/grub2/loader/i386/pc/multiboot.c)
===================================================================
--- trunk/grub2/loader/i386/multiboot.c	                        (rev 0)
+++ trunk/grub2/loader/i386/multiboot.c	2009-02-27 21:19:00 UTC (rev 2005)
@@ -0,0 +1,629 @@
+/* multiboot.c - boot a multiboot OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  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/>.
+ */
+
+/*
+ *  FIXME: The following features from the Multiboot specification still
+ *         need to be implemented:
+ *  - VBE support
+ *  - symbol table
+ *  - drives table
+ *  - ROM configuration table
+ *  - APM table
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/multiboot.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/elf.h>
+#include <grub/aout.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/env.h>
+
+extern grub_dl_t my_mod;
+static struct grub_multiboot_info *mbi;
+static grub_addr_t entry;
+
+static char *playground = NULL;
+
+static grub_err_t
+grub_multiboot_boot (void)
+{
+  grub_multiboot_real_boot (entry, mbi);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_multiboot_unload (void)
+{
+  if (mbi)
+    {
+      unsigned int i;
+      for (i = 0; i < mbi->mods_count; i++)
+	{
+	  grub_free ((void *)
+		     ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start);
+	  grub_free ((void *)
+		     ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline);
+	}
+      grub_free ((void *) mbi->mods_addr);
+      grub_free ((void *) mbi->cmdline);
+      grub_free (mbi);
+    }
+  
+  mbi = 0;
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Return the length of the Multiboot mmap that will be needed to allocate
+   our platform's map.  */
+static grub_uint32_t
+grub_get_multiboot_mmap_len (void)
+{
+  grub_size_t count = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+			     grub_uint64_t size __attribute__ ((unused)),
+			     grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+  
+  grub_machine_mmap_iterate (hook);
+  
+  return count * sizeof (struct grub_multiboot_mmap_entry);
+}
+
+/* Fill previously allocated Multiboot mmap.  */
+static void
+grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
+{
+  struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      mmap_entry->addr = addr;
+      mmap_entry->len = size;
+      mmap_entry->type = type;
+      mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size);
+      mmap_entry++;
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (hook);
+}
+
+/* Check if BUFFER contains ELF32.  */
+static int
+grub_multiboot_is_elf32 (void *buffer)
+{
+  Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer;
+
+  return ehdr->e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+static grub_err_t
+grub_multiboot_load_elf32 (grub_file_t file, void *buffer)
+{
+  Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer;
+  char *phdr_base;
+  int lowest_segment = 0, highest_segment = 0;
+  int i;
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+  if (grub_dl_check_header (ehdr, sizeof(Elf32_Ehdr)))
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+  if (ehdr->e_type != ET_EXEC)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
+    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+  phdr_base = (char *) buffer + ehdr->e_phoff;
+#define phdr(i)			((Elf32_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+    if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+      {
+	if (phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
+	  lowest_segment = i;
+	if (phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
+	  highest_segment = i;
+      }
+  grub_multiboot_payload_size += (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
+  grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
+
+  playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+  if (! playground)
+    return grub_errno;
+
+  grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+        {
+	  char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
+
+	  grub_dprintf ("multiboot_loader", "segment %d: paddr=%p, memsz=0x%x\n",
+			i, (void *) phdr(i)->p_paddr, phdr(i)->p_memsz);
+
+	  if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
+	      == (grub_off_t) -1)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "invalid offset in program header");
+
+          if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
+              != (grub_ssize_t) phdr(i)->p_filesz)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "couldn't read segment from file");
+
+          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
+            grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
+			 phdr(i)->p_memsz - phdr(i)->p_filesz);
+        }
+    }
+
+  grub_multiboot_payload_entry_offset = ehdr->e_entry - phdr(lowest_segment)->p_vaddr;
+
+#undef phdr
+
+  return grub_errno;
+}
+
+/* Check if BUFFER contains ELF64.  */
+static int
+grub_multiboot_is_elf64 (void *buffer)
+{
+  Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
+
+  return ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+static grub_err_t
+grub_multiboot_load_elf64 (grub_file_t file, void *buffer)
+{
+  Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
+  char *phdr_base;
+  grub_addr_t physical_entry_addr = 0;
+  int i;
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+      || ehdr->e_ident[EI_MAG1] != ELFMAG1
+      || ehdr->e_ident[EI_MAG2] != ELFMAG2
+      || ehdr->e_ident[EI_MAG3] != ELFMAG3
+      || ehdr->e_version != EV_CURRENT
+      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+      || ehdr->e_machine != EM_X86_64)
+    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+  if (ehdr->e_type != ET_EXEC)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
+    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+  /* We still in 32-bit mode */
+  if (ehdr->e_entry > 0xffffffff)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
+
+  entry = ehdr->e_entry;
+
+  phdr_base = (char *) buffer + ehdr->e_phoff;
+#define phdr(i)			((Elf64_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      if (phdr(i)->p_type == PT_LOAD)
+        {
+          /* The segment should fit in the area reserved for the OS.  */
+          if (phdr(i)->p_paddr < (grub_uint64_t) grub_os_area_addr)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "segment doesn't fit in memory reserved for the OS (0x%lx < 0x%lx)",
+			       phdr(i)->p_paddr, (grub_uint64_t) grub_os_area_addr);
+          if (phdr(i)->p_paddr + phdr(i)->p_memsz
+		  > (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "segment doesn't fit in memory reserved for the OS (0x%lx > 0x%lx)",
+			       phdr(i)->p_paddr + phdr(i)->p_memsz,
+			       (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size);
+
+	  if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
+	      == (grub_off_t) -1)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "invalid offset in program header");
+
+	  if (grub_file_read (file, (void *) ((grub_uint32_t) phdr(i)->p_paddr),
+			      phdr(i)->p_filesz)
+              != (grub_ssize_t) phdr(i)->p_filesz)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "couldn't read segment from file");
+
+          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
+	    grub_memset (((char *) ((grub_uint32_t) phdr(i)->p_paddr)
+			  + phdr(i)->p_filesz),
+			 0,
+			 phdr(i)->p_memsz - phdr(i)->p_filesz);
+
+	  if ((entry >= phdr(i)->p_vaddr) &&
+	      (entry < phdr(i)->p_vaddr + phdr(i)->p_memsz))
+	    physical_entry_addr = entry + phdr(i)->p_paddr - phdr(i)->p_vaddr;
+        }
+    }
+#undef phdr
+
+  if (physical_entry_addr)
+    entry = physical_entry_addr;
+
+  return grub_errno;
+}
+
+/* Load ELF32 or ELF64.  */
+static grub_err_t
+grub_multiboot_load_elf (grub_file_t file, void *buffer)
+{
+  if (grub_multiboot_is_elf32 (buffer))
+    return grub_multiboot_load_elf32 (file, buffer);
+  else if (grub_multiboot_is_elf64 (buffer))
+    return grub_multiboot_load_elf64 (file, buffer);
+
+  return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
+}
+
+static int
+grub_multiboot_get_bootdev (grub_uint32_t *bootdev)
+{
+  char *p;
+
+  p = grub_env_get ("root");
+  if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') &&
+      (p[2] >= '0') && (p[2] <= '9'))
+    {
+      grub_uint32_t bd;
+
+      bd = (p[0] == 'h') ? 0x80 : 0;
+      bd += grub_strtoul (p + 2, &p, 0);
+      bd <<= 24;
+
+      if ((p) && (p[0] == ','))
+	{
+	  if ((p[1] >= '0') && (p[1] <= '9'))
+	    {
+
+	      bd += ((grub_strtoul (p + 1, &p, 0) - 1) & 0xFF) << 16;
+
+	      if ((p) && (p[0] == ','))
+		p++;
+	    }
+          else
+            bd += 0xFF0000;
+
+	  if ((p[0] >= 'a') && (p[0] <= 'z'))
+            bd += (p[0] - 'a') << 8;
+          else
+            bd += 0xFF00;
+	}
+      else
+        bd += 0xFFFF00;
+
+      bd += 0xFF;
+
+      *bootdev = bd;
+      return 1;
+    }
+
+  return 0;
+}
+
+void
+grub_multiboot (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
+  struct grub_multiboot_header *header;
+  grub_ssize_t len;
+  grub_uint32_t mmap_length;
+  int i;
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "File too small");
+      goto fail;
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct grub_multiboot_header *) buffer;
+       ((char *) header <= buffer + len - 12) || (header = 0);
+       header = (struct grub_multiboot_header *) ((char *) header + 4))
+    {
+      if (header->magic == MULTIBOOT_MAGIC
+	  && !(header->magic + header->flags + header->checksum))
+	break;
+    }
+
+  if (header == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found");
+      goto fail;
+    }
+
+  if (header->flags & MULTIBOOT_UNSUPPORTED)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+		  "Unsupported flag: 0x%x", header->flags);
+      goto fail;
+    }
+
+  if (playground)
+    {
+      grub_free (playground);
+      playground = NULL;
+    }
+
+  mmap_length = grub_get_multiboot_mmap_len ();
+
+  grub_multiboot_payload_size = sizeof (struct grub_multiboot_info) + mmap_length + MULTIBOOT_INFO_ALIGN;
+
+  if (header->flags & MULTIBOOT_AOUT_KLUDGE)
+    {
+      int offset = ((char *) header - buffer -
+		    (header->header_addr - header->load_addr));
+      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
+		       header->load_end_addr - header->load_addr);
+
+      if (header->bss_end_addr)
+	grub_multiboot_payload_size += (header->bss_end_addr - header->load_addr);
+      else
+	grub_multiboot_payload_size += load_size;
+      grub_multiboot_payload_dest = header->load_addr;
+
+      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+      if (! playground)
+	goto fail;
+
+      grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
+
+      if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
+	goto fail;
+
+      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
+      if (grub_errno)
+	goto fail;
+      
+      if (header->bss_end_addr)
+	grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
+		     header->bss_end_addr - header->load_addr - load_size);
+      
+      grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr;
+
+    }
+  else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
+    goto fail;
+
+  grub_multiboot_payload_size = ALIGN_UP (grub_multiboot_payload_size, MULTIBOOT_INFO_ALIGN);
+
+  mbi = grub_multiboot_payload_orig + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info);
+  grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
+  mbi->mmap_length = mmap_length;
+      
+  grub_fill_multiboot_mmap ((struct grub_multiboot_mmap_entry *) (grub_multiboot_payload_orig
+								  + grub_multiboot_payload_size
+								  - mbi->mmap_length));
+
+  /* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
+     by the spec.  Is there something we can do about it?  */
+  mbi->mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mbi->mmap_length;
+  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
+
+  if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
+    {
+      grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward));
+      entry = (grub_addr_t) playground;
+    }
+  else
+    {
+      grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size),
+		    &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward));
+      entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size;
+    }
+  
+  grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
+		(void *) grub_multiboot_payload_dest,
+		grub_multiboot_payload_size,
+		grub_multiboot_payload_entry_offset);
+
+  /* Convert from bytes to kilobytes.  */
+  mbi->mem_lower = grub_lower_mem / 1024;
+  mbi->mem_upper = grub_upper_mem / 1024;
+  mbi->flags |= MULTIBOOT_INFO_MEMORY;
+
+  for (i = 0, len = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  cmdline = p = grub_malloc (len);
+  if (! cmdline)
+    goto fail;
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  *(--p) = '\0';
+
+  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
+  mbi->cmdline = (grub_uint32_t) cmdline;
+
+  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
+  mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING);
+
+  if (grub_multiboot_get_bootdev (&mbi->boot_device))
+    mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
+
+  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (cmdline);
+      grub_free (mbi);
+      grub_dl_unref (my_mod);
+    }
+}
+
+
+void
+grub_module  (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size, len = 0;
+  char *module = 0, *cmdline = 0, *p;
+  int i;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (!mbi)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+		  "You need to load the multiboot kernel first");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
+  if (! module)
+    goto fail;
+
+  if (grub_file_read (file, module, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  cmdline = p = grub_malloc (len);
+  if (! cmdline)
+    goto fail;
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  *(--p) = '\0';
+
+  if (mbi->flags & MULTIBOOT_INFO_MODS)
+    {
+      struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr;
+
+      modlist = grub_realloc (modlist, (mbi->mods_count + 1)
+			               * sizeof (struct grub_mod_list));
+      if (! modlist)
+	goto fail;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      modlist += mbi->mods_count;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      modlist->pad = 0;
+      mbi->mods_count++;
+    }
+  else
+    {
+      struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list));
+      if (! modlist)
+	goto fail;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      modlist->pad = 0;
+      mbi->mods_count = 1;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      mbi->flags |= MULTIBOOT_INFO_MODS;
+    }
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (module);
+      grub_free (cmdline);
+    }
+}


Property changes on: trunk/grub2/loader/i386/multiboot.c
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.19
Added: svn:mime-type
   + text/x-csrc
Added: svn:keywords
   + Author Date Id Revision
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Deleted: trunk/grub2/loader/i386/pc/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/pc/multiboot.c	2009-02-27 21:01:25 UTC (rev 2004)
+++ trunk/grub2/loader/i386/pc/multiboot.c	2009-02-27 21:19:00 UTC (rev 2005)
@@ -1,629 +0,0 @@
-/* multiboot.c - boot a multiboot OS image. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  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/>.
- */
-
-/*
- *  FIXME: The following features from the Multiboot specification still
- *         need to be implemented:
- *  - VBE support
- *  - symbol table
- *  - drives table
- *  - ROM configuration table
- *  - APM table
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/multiboot.h>
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/elf.h>
-#include <grub/aout.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/rescue.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/env.h>
-
-extern grub_dl_t my_mod;
-static struct grub_multiboot_info *mbi;
-static grub_addr_t entry;
-
-static char *playground = NULL;
-
-static grub_err_t
-grub_multiboot_boot (void)
-{
-  grub_multiboot_real_boot (entry, mbi);
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_multiboot_unload (void)
-{
-  if (mbi)
-    {
-      unsigned int i;
-      for (i = 0; i < mbi->mods_count; i++)
-	{
-	  grub_free ((void *)
-		     ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start);
-	  grub_free ((void *)
-		     ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline);
-	}
-      grub_free ((void *) mbi->mods_addr);
-      grub_free ((void *) mbi->cmdline);
-      grub_free (mbi);
-    }
-  
-  mbi = 0;
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Return the length of the Multiboot mmap that will be needed to allocate
-   our platform's map.  */
-static grub_uint32_t
-grub_get_multiboot_mmap_len (void)
-{
-  grub_size_t count = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
-			     grub_uint64_t size __attribute__ ((unused)),
-			     grub_uint32_t type __attribute__ ((unused)))
-    {
-      count++;
-      return 0;
-    }
-  
-  grub_machine_mmap_iterate (hook);
-  
-  return count * sizeof (struct grub_multiboot_mmap_entry);
-}
-
-/* Fill previously allocated Multiboot mmap.  */
-static void
-grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
-{
-  struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      mmap_entry->addr = addr;
-      mmap_entry->len = size;
-      mmap_entry->type = type;
-      mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size);
-      mmap_entry++;
-
-      return 0;
-    }
-
-  grub_machine_mmap_iterate (hook);
-}
-
-/* Check if BUFFER contains ELF32.  */
-static int
-grub_multiboot_is_elf32 (void *buffer)
-{
-  Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer;
-
-  return ehdr->e_ident[EI_CLASS] == ELFCLASS32;
-}
-
-static grub_err_t
-grub_multiboot_load_elf32 (grub_file_t file, void *buffer)
-{
-  Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer;
-  char *phdr_base;
-  int lowest_segment = 0, highest_segment = 0;
-  int i;
-
-  if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
-
-  if (grub_dl_check_header (ehdr, sizeof(Elf32_Ehdr)))
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
-
-  if (ehdr->e_type != ET_EXEC)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
-
-  /* FIXME: Should we support program headers at strange locations?  */
-  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
-    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
-
-  phdr_base = (char *) buffer + ehdr->e_phoff;
-#define phdr(i)			((Elf32_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
-
-  for (i = 0; i < ehdr->e_phnum; i++)
-    if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
-      {
-	if (phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
-	  lowest_segment = i;
-	if (phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
-	  highest_segment = i;
-      }
-  grub_multiboot_payload_size += (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
-  grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
-
-  playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
-  if (! playground)
-    return grub_errno;
-
-  grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
-
-  /* Load every loadable segment in memory.  */
-  for (i = 0; i < ehdr->e_phnum; i++)
-    {
-      if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
-        {
-	  char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
-
-	  grub_dprintf ("multiboot_loader", "segment %d: paddr=%p, memsz=0x%x\n",
-			i, (void *) phdr(i)->p_paddr, phdr(i)->p_memsz);
-
-	  if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
-	      == (grub_off_t) -1)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "invalid offset in program header");
-
-          if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
-              != (grub_ssize_t) phdr(i)->p_filesz)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "couldn't read segment from file");
-
-          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
-            grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
-			 phdr(i)->p_memsz - phdr(i)->p_filesz);
-        }
-    }
-
-  grub_multiboot_payload_entry_offset = ehdr->e_entry - phdr(lowest_segment)->p_vaddr;
-
-#undef phdr
-
-  return grub_errno;
-}
-
-/* Check if BUFFER contains ELF64.  */
-static int
-grub_multiboot_is_elf64 (void *buffer)
-{
-  Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
-
-  return ehdr->e_ident[EI_CLASS] == ELFCLASS64;
-}
-
-static grub_err_t
-grub_multiboot_load_elf64 (grub_file_t file, void *buffer)
-{
-  Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
-  char *phdr_base;
-  grub_addr_t physical_entry_addr = 0;
-  int i;
-
-  if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
-
-  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
-      || ehdr->e_ident[EI_MAG1] != ELFMAG1
-      || ehdr->e_ident[EI_MAG2] != ELFMAG2
-      || ehdr->e_ident[EI_MAG3] != ELFMAG3
-      || ehdr->e_version != EV_CURRENT
-      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
-      || ehdr->e_machine != EM_X86_64)
-    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
-
-  if (ehdr->e_type != ET_EXEC)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
-
-  /* FIXME: Should we support program headers at strange locations?  */
-  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
-    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
-
-  /* We still in 32-bit mode */
-  if (ehdr->e_entry > 0xffffffff)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
-
-  entry = ehdr->e_entry;
-
-  phdr_base = (char *) buffer + ehdr->e_phoff;
-#define phdr(i)			((Elf64_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
-
-  /* Load every loadable segment in memory.  */
-  for (i = 0; i < ehdr->e_phnum; i++)
-    {
-      if (phdr(i)->p_type == PT_LOAD)
-        {
-          /* The segment should fit in the area reserved for the OS.  */
-          if (phdr(i)->p_paddr < (grub_uint64_t) grub_os_area_addr)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "segment doesn't fit in memory reserved for the OS (0x%lx < 0x%lx)",
-			       phdr(i)->p_paddr, (grub_uint64_t) grub_os_area_addr);
-          if (phdr(i)->p_paddr + phdr(i)->p_memsz
-		  > (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "segment doesn't fit in memory reserved for the OS (0x%lx > 0x%lx)",
-			       phdr(i)->p_paddr + phdr(i)->p_memsz,
-			       (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size);
-
-	  if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
-	      == (grub_off_t) -1)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "invalid offset in program header");
-
-	  if (grub_file_read (file, (void *) ((grub_uint32_t) phdr(i)->p_paddr),
-			      phdr(i)->p_filesz)
-              != (grub_ssize_t) phdr(i)->p_filesz)
-	    return grub_error (GRUB_ERR_BAD_OS,
-			       "couldn't read segment from file");
-
-          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
-	    grub_memset (((char *) ((grub_uint32_t) phdr(i)->p_paddr)
-			  + phdr(i)->p_filesz),
-			 0,
-			 phdr(i)->p_memsz - phdr(i)->p_filesz);
-
-	  if ((entry >= phdr(i)->p_vaddr) &&
-	      (entry < phdr(i)->p_vaddr + phdr(i)->p_memsz))
-	    physical_entry_addr = entry + phdr(i)->p_paddr - phdr(i)->p_vaddr;
-        }
-    }
-#undef phdr
-
-  if (physical_entry_addr)
-    entry = physical_entry_addr;
-
-  return grub_errno;
-}
-
-/* Load ELF32 or ELF64.  */
-static grub_err_t
-grub_multiboot_load_elf (grub_file_t file, void *buffer)
-{
-  if (grub_multiboot_is_elf32 (buffer))
-    return grub_multiboot_load_elf32 (file, buffer);
-  else if (grub_multiboot_is_elf64 (buffer))
-    return grub_multiboot_load_elf64 (file, buffer);
-
-  return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
-}
-
-static int
-grub_multiboot_get_bootdev (grub_uint32_t *bootdev)
-{
-  char *p;
-
-  p = grub_env_get ("root");
-  if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') &&
-      (p[2] >= '0') && (p[2] <= '9'))
-    {
-      grub_uint32_t bd;
-
-      bd = (p[0] == 'h') ? 0x80 : 0;
-      bd += grub_strtoul (p + 2, &p, 0);
-      bd <<= 24;
-
-      if ((p) && (p[0] == ','))
-	{
-	  if ((p[1] >= '0') && (p[1] <= '9'))
-	    {
-
-	      bd += ((grub_strtoul (p + 1, &p, 0) - 1) & 0xFF) << 16;
-
-	      if ((p) && (p[0] == ','))
-		p++;
-	    }
-          else
-            bd += 0xFF0000;
-
-	  if ((p[0] >= 'a') && (p[0] <= 'z'))
-            bd += (p[0] - 'a') << 8;
-          else
-            bd += 0xFF00;
-	}
-      else
-        bd += 0xFFFF00;
-
-      bd += 0xFF;
-
-      *bootdev = bd;
-      return 1;
-    }
-
-  return 0;
-}
-
-void
-grub_multiboot (int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
-  struct grub_multiboot_header *header;
-  grub_ssize_t len;
-  grub_uint32_t mmap_length;
-  int i;
-
-  grub_loader_unset ();
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
-      goto fail;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (! file)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
-      goto fail;
-    }
-
-  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
-  if (len < 32)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "File too small");
-      goto fail;
-    }
-
-  /* Look for the multiboot header in the buffer.  The header should
-     be at least 12 bytes and aligned on a 4-byte boundary.  */
-  for (header = (struct grub_multiboot_header *) buffer;
-       ((char *) header <= buffer + len - 12) || (header = 0);
-       header = (struct grub_multiboot_header *) ((char *) header + 4))
-    {
-      if (header->magic == MULTIBOOT_MAGIC
-	  && !(header->magic + header->flags + header->checksum))
-	break;
-    }
-
-  if (header == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found");
-      goto fail;
-    }
-
-  if (header->flags & MULTIBOOT_UNSUPPORTED)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-		  "Unsupported flag: 0x%x", header->flags);
-      goto fail;
-    }
-
-  if (playground)
-    {
-      grub_free (playground);
-      playground = NULL;
-    }
-
-  mmap_length = grub_get_multiboot_mmap_len ();
-
-  grub_multiboot_payload_size = sizeof (struct grub_multiboot_info) + mmap_length + MULTIBOOT_INFO_ALIGN;
-
-  if (header->flags & MULTIBOOT_AOUT_KLUDGE)
-    {
-      int offset = ((char *) header - buffer -
-		    (header->header_addr - header->load_addr));
-      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
-		       header->load_end_addr - header->load_addr);
-
-      if (header->bss_end_addr)
-	grub_multiboot_payload_size += (header->bss_end_addr - header->load_addr);
-      else
-	grub_multiboot_payload_size += load_size;
-      grub_multiboot_payload_dest = header->load_addr;
-
-      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
-      if (! playground)
-	goto fail;
-
-      grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
-
-      if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
-	goto fail;
-
-      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
-      if (grub_errno)
-	goto fail;
-      
-      if (header->bss_end_addr)
-	grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
-		     header->bss_end_addr - header->load_addr - load_size);
-      
-      grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr;
-
-    }
-  else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
-    goto fail;
-
-  grub_multiboot_payload_size = ALIGN_UP (grub_multiboot_payload_size, MULTIBOOT_INFO_ALIGN);
-
-  mbi = grub_multiboot_payload_orig + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info);
-  grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
-  mbi->mmap_length = mmap_length;
-      
-  grub_fill_multiboot_mmap ((struct grub_multiboot_mmap_entry *) (grub_multiboot_payload_orig
-								  + grub_multiboot_payload_size
-								  - mbi->mmap_length));
-
-  /* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
-     by the spec.  Is there something we can do about it?  */
-  mbi->mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mbi->mmap_length;
-  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
-
-  if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
-    {
-      grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward));
-      entry = (grub_addr_t) playground;
-    }
-  else
-    {
-      grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size),
-		    &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward));
-      entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size;
-    }
-  
-  grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
-		(void *) grub_multiboot_payload_dest,
-		grub_multiboot_payload_size,
-		grub_multiboot_payload_entry_offset);
-
-  /* Convert from bytes to kilobytes.  */
-  mbi->mem_lower = grub_lower_mem / 1024;
-  mbi->mem_upper = grub_upper_mem / 1024;
-  mbi->flags |= MULTIBOOT_INFO_MEMORY;
-
-  for (i = 0, len = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-
-  cmdline = p = grub_malloc (len);
-  if (! cmdline)
-    goto fail;
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  *(--p) = '\0';
-
-  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
-  mbi->cmdline = (grub_uint32_t) cmdline;
-
-  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
-  mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING);
-
-  if (grub_multiboot_get_bootdev (&mbi->boot_device))
-    mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
-
-  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_free (cmdline);
-      grub_free (mbi);
-      grub_dl_unref (my_mod);
-    }
-}
-
-
-void
-grub_module  (int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size, len = 0;
-  char *module = 0, *cmdline = 0, *p;
-  int i;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
-      goto fail;
-    }
-
-  if (!mbi)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT,
-		  "You need to load the multiboot kernel first");
-      goto fail;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (! file)
-    goto fail;
-
-  size = grub_file_size (file);
-  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
-  if (! module)
-    goto fail;
-
-  if (grub_file_read (file, module, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
-      goto fail;
-    }
-
-  for (i = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-
-  cmdline = p = grub_malloc (len);
-  if (! cmdline)
-    goto fail;
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  *(--p) = '\0';
-
-  if (mbi->flags & MULTIBOOT_INFO_MODS)
-    {
-      struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr;
-
-      modlist = grub_realloc (modlist, (mbi->mods_count + 1)
-			               * sizeof (struct grub_mod_list));
-      if (! modlist)
-	goto fail;
-      mbi->mods_addr = (grub_uint32_t) modlist;
-      modlist += mbi->mods_count;
-      modlist->mod_start = (grub_uint32_t) module;
-      modlist->mod_end = (grub_uint32_t) module + size;
-      modlist->cmdline = (grub_uint32_t) cmdline;
-      modlist->pad = 0;
-      mbi->mods_count++;
-    }
-  else
-    {
-      struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list));
-      if (! modlist)
-	goto fail;
-      modlist->mod_start = (grub_uint32_t) module;
-      modlist->mod_end = (grub_uint32_t) module + size;
-      modlist->cmdline = (grub_uint32_t) cmdline;
-      modlist->pad = 0;
-      mbi->mods_count = 1;
-      mbi->mods_addr = (grub_uint32_t) modlist;
-      mbi->flags |= MULTIBOOT_INFO_MODS;
-    }
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_free (module);
-      grub_free (cmdline);
-    }
-}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.