All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] [PATCH] Add multiboot 2 capabilities
@ 2007-07-07 15:53 Jerone Young
  2007-07-07 18:12 ` Otavio Salvador
  0 siblings, 1 reply; 10+ messages in thread
From: Jerone Young @ 2007-07-07 15:53 UTC (permalink / raw)
  To: The development of GRUB 2

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

This patch is to introduce multiboot 2 loading capabilities to grub2
for powerpc & i386-pc. This patch was more so started by Hollis
Blanchard getting multiboot 2 working for power pc and I added to it
and cleaned it up.

One of the ideas with this patch is to keep everything under one
command for the user. So instead of having a "multiboot2" & "module2"
command, I created a proxy like mechanism so that you have only one
command for both multiboot 1 & 2 ... "multiboot". This is where
"loader/multiboot_loader.c" comes from. I could have integrated things
more but I figure the current approach will less likely break
anything.

The other thing that this patch does is it begins to make the
multiboot 1 code a bit more architecture agnostic so IF someone wanted
to implement it on another architecture they can.

A bit of file moving around and definition renaming is also apart of
this patch. I have also taken the time to make sure that it does not
break multiboot 1 loading on i386-pc.

If you have any comments please try to make them by next Saturday
(July 14). If I don't hear any complaints or suggestions, I will check
the code into the repository as is. Sorry the patch is a little big.

Also I have don't have the change log entry in this patch :-).

Signed-off-by: Jerone Young <jerone@gmail.com>

[-- Attachment #2: multiboot_2_patch.diff --]
[-- Type: text/x-diff, Size: 62306 bytes --]

diff -r b85dfdfcce16 conf/i386-pc.rmk
--- a/conf/i386-pc.rmk	Wed Jul 04 15:53:23 2007 -0500
+++ b/conf/i386-pc.rmk	Thu Jul 05 01:08:06 2007 -0500
@@ -180,12 +180,15 @@ serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For _multiboot.mod.
-_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c
+_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \
+                         loader/i386/pc/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
 _multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
 _multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For multiboot.mod.
-multiboot_mod_SOURCES = loader/i386/pc/multiboot_normal.c
+multiboot_mod_SOURCES = loader/multiboot_loader_normal.c 
 multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
 multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
diff -r b85dfdfcce16 conf/powerpc-ieee1275.rmk
--- a/conf/powerpc-ieee1275.rmk	Wed Jul 04 15:53:23 2007 -0500
+++ b/conf/powerpc-ieee1275.rmk	Thu Jul 05 08:04:34 2007 -0500
@@ -102,7 +102,9 @@ pkgdata_MODULES = halt.mod \
 	linux.mod \
 	normal.mod \
 	reboot.mod \
-	suspend.mod
+	suspend.mod \
+        _multiboot.mod \
+        multiboot.mod
 
 # For _linux.mod.
 _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -140,5 +142,18 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS)
 halt_mod_CFLAGS = $(COMMON_CFLAGS)
 halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For _multiboot.mod
+_multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
+_multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod
+multiboot_mod_SOURCES = loader/multiboot_loader_normal.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) 
+
+
 include $(srcdir)/conf/common.mk
 
diff -r b85dfdfcce16 include/grub/i386/pc/loader.h
--- a/include/grub/i386/pc/loader.h	Wed Jul 04 15:53:23 2007 -0500
+++ b/include/grub/i386/pc/loader.h	Thu Jul 05 01:17:47 2007 -0500
@@ -22,11 +22,13 @@
 
 #include <grub/types.h>
 #include <grub/symbol.h>
-#include <grub/machine/multiboot.h>
+#include <grub/multiboot.h>
 
 extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
 extern char *EXPORT_VAR(grub_linux_tmp_addr);
 extern char *EXPORT_VAR(grub_linux_real_addr);
+extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
+extern grub_size_t EXPORT_VAR(grub_os_area_size);
 
 void EXPORT_FUNC(grub_linux_boot_zimage) (void) __attribute__ ((noreturn));
 void EXPORT_FUNC(grub_linux_boot_bzimage) (void) __attribute__ ((noreturn));
@@ -34,16 +36,18 @@ void EXPORT_FUNC(grub_linux_boot_bzimage
 /* This is an asm part of the chainloader.  */
 void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn));
 
+
 /* The asm part of the multiboot loader.  */
 void EXPORT_FUNC(grub_multiboot_real_boot) (grub_addr_t entry, 
 					    struct grub_multiboot_info *mbi) 
+     __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_multiboot2_real_boot) (grub_addr_t entry,
+                                             struct grub_multiboot_info *mbi)
      __attribute__ ((noreturn));
 
 /* It is necessary to export these functions, because normal mode commands
    reuse rescue mode commands.  */
 void grub_rescue_cmd_linux (int argc, char *argv[]);
 void grub_rescue_cmd_initrd (int argc, char *argv[]);
-void grub_rescue_cmd_multiboot (int argc, char *argv[]);
-void grub_rescue_cmd_module (int argc, char *argv[]);
 
 #endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff -r b85dfdfcce16 include/grub/i386/pc/multiboot.h
--- a/include/grub/i386/pc/multiboot.h	Wed Jul 04 15:53:23 2007 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/* multiboot.h - multiboot header file. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003  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.
- */
-
-#ifndef GRUB_MULTIBOOT_MACHINE_HEADER
-#define GRUB_MULTIBOOT_MACHINE_HEADER 1
-
-/* How many bytes from the start of the file we search for the header.  */
-#define GRUB_MB_SEARCH                 8192
-
-/* The magic field should contain this.  */
-#define GRUB_MB_MAGIC                  0x1BADB002
-
-/* This should be in %eax.  */
-#define GRUB_MB_MAGIC2                 0x2BADB002
-
-/* The bits in the required part of flags field we don't support.  */
-#define GRUB_MB_UNSUPPORTED            0x0000fffc
-
-/* Alignment of multiboot modules.  */
-#define GRUB_MB_MOD_ALIGN              0x00001000
-
-/* 
- * Flags set in the 'flags' member of the multiboot header.
- */
-
-/* Align all boot modules on i386 page (4KB) boundaries.  */
-#define GRUB_MB_PAGE_ALIGN		0x00000001
-
-/* Must pass memory information to OS.  */
-#define GRUB_MB_MEMORY_INFO		0x00000002
-
-/* Must pass video information to OS.  */
-#define GRUB_MB_VIDEO_MODE		0x00000004
-
-/* This flag indicates the use of the address fields in the header.  */
-#define GRUB_MB_AOUT_KLUDGE		0x00010000
-
-/*
- *  Flags to be set in the 'flags' member of the multiboot info structure.
- */
-
-/* is there basic lower/upper memory information? */
-#define GRUB_MB_INFO_MEMORY		0x00000001
-/* is there a boot device set? */
-#define GRUB_MB_INFO_BOOTDEV		0x00000002
-/* is the command-line defined? */
-#define GRUB_MB_INFO_CMDLINE		0x00000004
-/* are there modules to do something with? */
-#define GRUB_MB_INFO_MODS		0x00000008
-
-/* These next two are mutually exclusive */
-
-/* is there a symbol table loaded? */
-#define GRUB_MB_INFO_AOUT_SYMS		0x00000010
-/* is there an ELF section header table? */
-#define GRUB_MB_INFO_ELF_SHDR		0x00000020
-
-/* is there a full memory map? */
-#define GRUB_MB_INFO_MEM_MAP		0x00000040
-
-/* Is there drive info?  */
-#define GRUB_MB_INFO_DRIVE_INFO		0x00000080
-
-/* Is there a config table?  */
-#define GRUB_MB_INFO_CONFIG_TABLE	0x00000100
-
-/* Is there a boot loader name?  */
-#define GRUB_MB_INFO_BOOT_LOADER_NAME	0x00000200
-
-/* Is there a APM table?  */
-#define GRUB_MB_INFO_APM_TABLE		0x00000400
-
-/* Is there video information?  */
-#define GRUB_MB_INFO_VIDEO_INFO		0x00000800
-
-#ifndef ASM_FILE
-
-#include <grub/types.h>
-
-struct grub_multiboot_header
-{ 
-  /* Must be GRUB_MB_MAGIC - see above.  */
-  grub_uint32_t magic;
-
-  /* Feature flags.  */
-  grub_uint32_t flags;
-
-  /* The above fields plus this one must equal 0 mod 2^32. */
-  grub_uint32_t checksum;
-  
-  /* These are only valid if GRUB_MB_AOUT_KLUDGE is set.  */
-  grub_uint32_t header_addr;
-  grub_uint32_t load_addr;
-  grub_uint32_t load_end_addr;
-  grub_uint32_t bss_end_addr;
-  grub_uint32_t entry_addr;
-
-  /* These are only valid if GRUB_MB_VIDEO_MODE is set.  */
-  grub_uint32_t mode_type;
-  grub_uint32_t width;
-  grub_uint32_t height;
-  grub_uint32_t depth;
-};
-
-struct grub_multiboot_info
-{
-  /* Multiboot info version number */
-  grub_uint32_t flags;
-  
-  /* Available memory from BIOS */
-  grub_uint32_t mem_lower;
-  grub_uint32_t mem_upper;
-  
-  /* "root" partition */
-  grub_uint32_t boot_device;
-  
-  /* Kernel command line */
-  grub_uint32_t cmdline;
-  
-  /* Boot-Module list */
-  grub_uint32_t mods_count;
-  grub_uint32_t mods_addr;
-  
-  grub_uint32_t syms[4];
-  
-  /* Memory Mapping buffer */
-  grub_uint32_t mmap_length;
-  grub_uint32_t mmap_addr;
-  
-  /* Drive Info buffer */
-  grub_uint32_t drives_length;
-  grub_uint32_t drives_addr;
-  
-  /* ROM configuration table */
-  grub_uint32_t config_table;
-  
-  /* Boot Loader Name */
-  grub_uint32_t boot_loader_name;
-
-  /* APM table */
-  grub_uint32_t apm_table;
-
-  /* Video */
-  grub_uint32_t vbe_control_info;
-  grub_uint32_t vbe_mode_info;
-  grub_uint16_t vbe_mode;
-  grub_uint16_t vbe_interface_seg;
-  grub_uint16_t vbe_interface_off;
-  grub_uint16_t vbe_interface_len;
-};
-
-struct grub_mod_list
-{
-  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
-  grub_uint32_t mod_start;
-  grub_uint32_t mod_end;
-  
-  /* Module command line */
-  grub_uint32_t cmdline;
-  
-  /* padding to take it to 16 bytes (must be zero) */
-  grub_uint32_t pad;
-};
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_MULTIBOOT_MACHINE_HEADER */
diff -r b85dfdfcce16 include/grub/multiboot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/grub/multiboot.h	Thu Jul 05 01:18:19 2007 -0500
@@ -0,0 +1,120 @@
+/* multiboot.h - multiboot header file with grub definitions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003  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.
+ */
+
+#ifndef GRUB_MULTIBOOT_HEADER
+#define GRUB_MULTIBOOT_HEADER 1
+
+#include <multiboot.h>
+
+void grub_multiboot (int argc, char *argv[]);
+void grub_module (int argc, char *argv[]);
+
+#ifndef ASM_FILE
+
+#include <grub/types.h>
+
+struct grub_multiboot_header
+{ 
+  /* Must be MULTIBOOT_MAGIC - see above.  */
+  grub_uint32_t magic;
+
+  /* Feature flags.  */
+  grub_uint32_t flags;
+
+  /* The above fields plus this one must equal 0 mod 2^32. */
+  grub_uint32_t checksum;
+  
+  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+  grub_uint32_t header_addr;
+  grub_uint32_t load_addr;
+  grub_uint32_t load_end_addr;
+  grub_uint32_t bss_end_addr;
+  grub_uint32_t entry_addr;
+
+  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+  grub_uint32_t mode_type;
+  grub_uint32_t width;
+  grub_uint32_t height;
+  grub_uint32_t depth;
+};
+
+struct grub_multiboot_info
+{
+  /* Multiboot info version number */
+  grub_uint32_t flags;
+  
+  /* Available memory from BIOS */
+  grub_uint32_t mem_lower;
+  grub_uint32_t mem_upper;
+  
+  /* "root" partition */
+  grub_uint32_t boot_device;
+  
+  /* Kernel command line */
+  grub_uint32_t cmdline;
+  
+  /* Boot-Module list */
+  grub_uint32_t mods_count;
+  grub_uint32_t mods_addr;
+  
+  grub_uint32_t syms[4];
+  
+  /* Memory Mapping buffer */
+  grub_uint32_t mmap_length;
+  grub_uint32_t mmap_addr;
+  
+  /* Drive Info buffer */
+  grub_uint32_t drives_length;
+  grub_uint32_t drives_addr;
+  
+  /* ROM configuration table */
+  grub_uint32_t config_table;
+  
+  /* Boot Loader Name */
+  grub_uint32_t boot_loader_name;
+
+  /* APM table */
+  grub_uint32_t apm_table;
+
+  /* Video */
+  grub_uint32_t vbe_control_info;
+  grub_uint32_t vbe_mode_info;
+  grub_uint16_t vbe_mode;
+  grub_uint16_t vbe_interface_seg;
+  grub_uint16_t vbe_interface_off;
+  grub_uint16_t vbe_interface_len;
+};
+
+struct grub_mod_list
+{
+  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+  grub_uint32_t mod_start;
+  grub_uint32_t mod_end;
+  
+  /* Module command line */
+  grub_uint32_t cmdline;
+  
+  /* padding to take it to 16 bytes (must be zero) */
+  grub_uint32_t pad;
+};
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_MULTIBOOT_HEADER */
diff -r b85dfdfcce16 include/grub/multiboot2.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/grub/multiboot2.h	Thu Jul 05 01:13:50 2007 -0500
@@ -0,0 +1,50 @@
+/* multiboot2.h - multiboot2 header file with grub definitions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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.
+ */
+
+#ifndef GRUB_MULTIBOOT2_HEADER
+#define GRUB_MULTIBOOT2_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/elf.h>
+
+struct multiboot_tag_header;
+
+grub_err_t grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len);
+
+grub_err_t grub_mb2_tags_arch_create (void);
+void grub_mb2_arch_boot (grub_addr_t entry, void *tags);
+void grub_mb2_arch_unload (struct multiboot_tag_header *tags);
+
+grub_err_t grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr);
+grub_err_t grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr);
+
+grub_err_t grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr);
+grub_err_t grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size);
+
+void grub_multiboot2 (int argc, char *argv[]);
+void grub_module2 (int argc, char *argv[]);
+
+#define for_each_tag(tag, tags) \
+  for (tag = tags; \
+       tag && tag->key != MULTIBOOT2_TAG_END; \
+       tag = (struct multiboot_tag_header *)((char *)tag + tag->len))
+
+#endif /* ! GRUB_MULTIBOOT2_HEADER */
diff -r b85dfdfcce16 include/grub/multiboot_loader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/grub/multiboot_loader.h	Wed Jul 04 17:40:45 2007 -0500
@@ -0,0 +1,29 @@
+/* multiboot_loader.h - multiboot loader header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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.
+ */
+
+
+#ifndef GRUB_MULTIBOOT_LOADER_HEADER
+#define GRUB_MULTIBOOT_LOADER_HEADER 1
+
+/* Provided by the core ("rescue mode").  */
+void grub_rescue_cmd_multiboot_loader (int argc, char *argv[]);
+void grub_rescue_cmd_module_loader (int argc, char *argv[]);
+
+#endif /* ! GRUB_MULTIBOOT_LOADER_HEADER */
diff -r b85dfdfcce16 include/grub/powerpc/ieee1275/multiboot.h
--- a/include/grub/powerpc/ieee1275/multiboot.h	Wed Jul 04 15:53:23 2007 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/* multiboot.h - multiboot header file. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003, 2004  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.
- */
-
-#ifndef GRUB_MULTIBOOT_MACHINE_HEADER
-#define GRUB_MULTIBOOT_MACHINE_HEADER 1
-
-/* How many bytes from the start of the file we search for the header.  */
-#define GRUB_MB_SEARCH                 8192
-
-/* The magic field should contain this.  */
-#define GRUB_MB_MAGIC                  0x1BADB002
-
-/* This should be in %eax.  */
-#define GRUB_MB_MAGIC2                 0x2BADB002
-
-/* The bits in the required part of flags field we don't support.  */
-#define GRUB_MB_UNSUPPORTED            0x0000fffc
-
-/* Alignment of multiboot modules.  */
-#define GRUB_MB_MOD_ALIGN              0x00001000
-
-/* 
- * Flags set in the 'flags' member of the multiboot header.
- */
-
-/* Align all boot modules on i386 page (4KB) boundaries.  */
-#define GRUB_MB_PAGE_ALIGN		0x00000001
-
-/* Must pass memory information to OS.  */
-#define GRUB_MB_MEMORY_INFO		0x00000002
-
-/* Must pass video information to OS.  */
-#define GRUB_MB_VIDEO_MODE		0x00000004
-
-/* This flag indicates the use of the address fields in the header.  */
-#define GRUB_MB_AOUT_KLUDGE		0x00010000
-
-/*
- *  Flags to be set in the 'flags' member of the multiboot info structure.
- */
-
-/* is there basic lower/upper memory information? */
-#define GRUB_MB_INFO_MEMORY		0x00000001
-/* is there a boot device set? */
-#define GRUB_MB_INFO_BOOTDEV		0x00000002
-/* is the command-line defined? */
-#define GRUB_MB_INFO_CMDLINE		0x00000004
-/* are there modules to do something with? */
-#define GRUB_MB_INFO_MODS		0x00000008
-
-/* These next two are mutually exclusive */
-
-/* is there a symbol table loaded? */
-#define GRUB_MB_INFO_AOUT_SYMS		0x00000010
-/* is there an ELF section header table? */
-#define GRUB_MB_INFO_ELF_SHDR		0x00000020
-
-/* is there a full memory map? */
-#define GRUB_MB_INFO_MEM_MAP		0x00000040
-
-/* Is there drive info?  */
-#define GRUB_MB_INFO_DRIVE_INFO		0x00000080
-
-/* Is there a config table?  */
-#define GRUB_MB_INFO_CONFIG_TABLE	0x00000100
-
-/* Is there a boot loader name?  */
-#define GRUB_MB_INFO_BOOT_LOADER_NAME	0x00000200
-
-/* Is there a APM table?  */
-#define GRUB_MB_INFO_APM_TABLE		0x00000400
-
-/* Is there video information?  */
-#define GRUB_MB_INFO_VIDEO_INFO		0x00000800
-
-#ifndef ASM_FILE
-
-#include <grub/types.h>
-
-struct grub_multiboot_header
-{ 
-  /* Must be GRUB_MB_MAGIC - see above.  */
-  grub_uint32_t magic;
-
-  /* Feature flags.  */
-  grub_uint32_t flags;
-
-  /* The above fields plus this one must equal 0 mod 2^32. */
-  grub_uint32_t checksum;
-  
-  /* These are only valid if GRUB_MB_AOUT_KLUDGE is set.  */
-  grub_uint32_t header_addr;
-  grub_uint32_t load_addr;
-  grub_uint32_t load_end_addr;
-  grub_uint32_t bss_end_addr;
-  grub_uint32_t entry_addr;
-
-  /* These are only valid if GRUB_MB_VIDEO_MODE is set.  */
-  grub_uint32_t mode_type;
-  grub_uint32_t width;
-  grub_uint32_t height;
-  grub_uint32_t depth;
-};
-
-struct grub_multiboot_info
-{
-  /* MultiBoot info version number */
-  grub_uint32_t flags;
-  
-  /* Available memory from BIOS */
-  grub_uint32_t mem_lower;
-  grub_uint32_t mem_upper;
-  
-  /* "root" partition */
-  grub_uint32_t boot_device;
-  
-  /* Kernel command line */
-  grub_uint32_t cmdline;
-  
-  /* Boot-Module list */
-  grub_uint32_t mods_count;
-  grub_uint32_t mods_addr;
-  
-  grub_uint32_t syms[4];
-  
-  /* Memory Mapping buffer */
-  grub_uint32_t mmap_length;
-  grub_uint32_t mmap_addr;
-  
-  /* Drive Info buffer */
-  grub_uint32_t drives_length;
-  grub_uint32_t drives_addr;
-  
-  /* ROM configuration table */
-  grub_uint32_t config_table;
-  
-  /* Boot Loader Name */
-  grub_uint32_t boot_loader_name;
-
-  /* APM table */
-  grub_uint32_t apm_table;
-
-  /* Video */
-  grub_uint32_t vbe_control_info;
-  grub_uint32_t vbe_mode_info;
-  grub_uint16_t vbe_mode;
-  grub_uint16_t vbe_interface_seg;
-  grub_uint16_t vbe_interface_off;
-  grub_uint16_t vbe_interface_len;
-};
-
-struct grub_mod_list
-{
-  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
-  grub_uint32_t mod_start;
-  grub_uint32_t mod_end;
-  
-  /* Module command line */
-  grub_uint32_t cmdline;
-  
-  /* padding to take it to 16 bytes (must be zero) */
-  grub_uint32_t pad;
-};
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_MULTIBOOT_MACHINE_HEADER */
diff -r b85dfdfcce16 include/multiboot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/multiboot.h	Thu Jul 05 00:36:23 2007 -0500
@@ -0,0 +1,93 @@
+/* multiboot.h - multiboot header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003  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.
+ */
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT_SEARCH                 8192
+
+/* The magic field should contain this.  */
+#define MULTIBOOT_MAGIC                  0x1BADB002
+
+/* This should be in %eax.  */
+#define MULTIBOOT_MAGIC2                 0x2BADB002
+
+/* The bits in the required part of flags field we don't support.  */
+#define MULTIBOOT_UNSUPPORTED            0x0000fffc
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT_MOD_ALIGN              0x00001000
+
+/* 
+ * Flags set in the 'flags' member of the multiboot header.
+ */
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN		0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO		0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE		0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE		0x00010000
+
+/*
+ *  Flags to be set in the 'flags' member of the multiboot info structure.
+ */
+
+/* is there basic lower/upper memory information? */
+#define MULTIBOOT_INFO_MEMORY		0x00000001
+/* is there a boot device set? */
+#define MULTIBOOT_INFO_BOOTDEV		0x00000002
+/* is the command-line defined? */
+#define MULTIBOOT_INFO_CMDLINE		0x00000004
+/* are there modules to do something with? */
+#define MULTIBOOT_INFO_MODS		0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MULTIBOOT_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MULTIBOOT_INFO_ELF_SHDR		0x00000020
+
+/* is there a full memory map? */
+#define MULTIBOOT_INFO_MEM_MAP		0x00000040
+
+/* Is there drive info?  */
+#define MULTIBOOT_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MULTIBOOT_INFO_CONFIG_TABLE	0x00000100
+
+/* Is there a boot loader name?  */
+#define MULTIBOOT_INFO_BOOT_LOADER_NAME	0x00000200
+
+/* Is there a APM table?  */
+#define MULTIBOOT_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MULTIBOOT_INFO_VIDEO_INFO		0x00000800
+
+#endif /* ! MULTIBOOT_HEADER */
diff -r b85dfdfcce16 include/multiboot2.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/multiboot2.h	Thu Jul 05 00:51:54 2007 -0500
@@ -0,0 +1,108 @@
+/* multiboot2.h - multiboot 2 header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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.
+ */
+
+#ifndef MULTIBOOT2_HEADER
+#define MULTIBOOT2_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT2_HEADER_SEARCH           8192
+
+/* The magic field should contain this.  */
+#define MULTIBOOT2_HEADER_MAGIC            0xe85250d6
+
+/* Passed from the bootloader to the kernel.  */
+#define MULTIBOOT2_BOOTLOADER_MAGIC        0x36d76289
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT2_MOD_ALIGN               0x00001000
+
+#ifndef ASM_FILE
+
+#include "stdint.h"
+
+/* XXX not portable? */
+#if __WORDSIZE == 64
+typedef uint64_t multiboot_word;
+#else
+typedef uint32_t multiboot_word;
+#endif
+
+struct multiboot_header
+{
+  uint32_t magic;
+};
+
+struct multiboot_tag_header
+{
+  uint32_t key;
+  uint32_t len;
+};
+
+#define MULTIBOOT2_TAG_RESERVED1 0
+#define MULTIBOOT2_TAG_RESERVED2 (~0)
+
+#define MULTIBOOT2_TAG_START     1
+struct multiboot_tag_start
+{
+  struct multiboot_tag_header header;
+  multiboot_word size; /* Total size of all multiboot tags. */
+};
+
+#define MULTIBOOT2_TAG_NAME      2
+struct multiboot_tag_name
+{
+  struct multiboot_tag_header header;
+  char name[1];
+};
+
+#define MULTIBOOT2_TAG_MODULE    3
+struct multiboot_tag_module
+{
+  struct multiboot_tag_header header;
+  multiboot_word addr;
+  multiboot_word size;
+  unsigned char type[36];
+  unsigned char cmdline[1];
+};
+
+#define MULTIBOOT2_TAG_MEMORY    4
+struct multiboot_tag_memory
+{
+  struct multiboot_tag_header header;
+  multiboot_word addr;
+  multiboot_word size;
+  multiboot_word type;
+};
+
+#define MULTIBOOT2_TAG_UNUSED    5
+struct multiboot_tag_unused
+{
+  struct multiboot_tag_header header;
+};
+
+#define MULTIBOOT2_TAG_END       0xffff
+struct multiboot_tag_end
+{
+  struct multiboot_tag_header header;
+};
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT2_HEADER */
diff -r b85dfdfcce16 kern/i386/pc/startup.S
--- a/kern/i386/pc/startup.S	Wed Jul 04 15:53:23 2007 -0500
+++ b/kern/i386/pc/startup.S	Thu Jul 05 01:01:25 2007 -0500
@@ -50,7 +50,8 @@
 #include <grub/machine/console.h>
 #include <grub/cpu/linux.h>
 #include <grub/machine/kernel.h>
-#include <grub/machine/multiboot.h>
+#include <multiboot.h>
+#include <multiboot2.h>
 		
 #define ABS(x)	((x) - EXT_C(start) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
 	
@@ -814,10 +815,31 @@ FUNCTION(grub_multiboot_real_boot)
 	cli
 	
 	/* Move the magic value into eax and jump to the kernel.  */
-	movl	$GRUB_MB_MAGIC2,%eax
+	movl	$MULTIBOOT_MAGIC2,%eax
 	popl	%ecx
 	jmp 	*%ecx
-	
+
+/*
+ * This starts the multiboot 2 kernel.
+ */
+
+FUNCTION(grub_multiboot2_real_boot)
+        /* Push the entry address on the stack.  */
+        pushl   %eax
+        /* Move the address of the multiboot information structure to ebx.  */
+        movl    %edx,%ebx
+
+        /* Unload all modules and stop the floppy driver.  */
+        call    EXT_C(grub_dl_unload_all)
+        call    EXT_C(grub_stop_floppy)
+
+        /* Interrupts should be disabled.  */
+        cli
+
+        /* Move the magic value into eax and jump to the kernel.  */
+        movl    $MULTIBOOT2_BOOTLOADER_MAGIC,%eax 
+        popl    %ecx
+        jmp     *%ecx
 	
 /*
  *   int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
diff -r b85dfdfcce16 loader/i386/pc/multiboot.c
--- a/loader/i386/pc/multiboot.c	Wed Jul 04 15:53:23 2007 -0500
+++ b/loader/i386/pc/multiboot.c	Thu Jul 05 01:16:01 2007 -0500
@@ -33,7 +33,7 @@
 
 #include <grub/loader.h>
 #include <grub/machine/loader.h>
-#include <grub/machine/multiboot.h>
+#include <grub/multiboot.h>
 #include <grub/machine/init.h>
 #include <grub/elf.h>
 #include <grub/file.h>
@@ -44,7 +44,7 @@
 #include <grub/misc.h>
 #include <grub/gzio.h>
 
-static grub_dl_t my_mod;
+extern grub_dl_t my_mod;
 static struct grub_multiboot_info *mbi;
 static grub_addr_t entry;
 
@@ -108,7 +108,7 @@ grub_multiboot_load_elf32 (grub_file_t f
     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 > GRUB_MB_SEARCH)
+  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");
   
   entry = ehdr->e_entry;
@@ -178,7 +178,7 @@ grub_multiboot_load_elf64 (grub_file_t f
     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 > GRUB_MB_SEARCH)
+  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 */
@@ -237,16 +237,14 @@ grub_multiboot_load_elf (grub_file_t fil
 }
 
 void
-grub_rescue_cmd_multiboot (int argc, char *argv[])
+grub_multiboot (int argc, char *argv[])
 {
   grub_file_t file = 0;
-  char buffer[GRUB_MB_SEARCH], *cmdline = 0, *p;
+  char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
   struct grub_multiboot_header *header;
   grub_ssize_t len;
   int i;
 
-  grub_dl_ref (my_mod);
-
   grub_loader_unset ();
     
   if (argc == 0)
@@ -262,7 +260,7 @@ grub_rescue_cmd_multiboot (int argc, cha
       goto fail;
     }
 
-  len = grub_file_read (file, buffer, GRUB_MB_SEARCH);
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
   if (len < 32)
     {
       grub_error (GRUB_ERR_BAD_OS, "File too small");
@@ -275,7 +273,7 @@ grub_rescue_cmd_multiboot (int argc, cha
        ((char *) header <= buffer + len - 12) || (header = 0);
        header = (struct grub_multiboot_header *) ((char *) header + 4))
     {
-      if (header->magic == GRUB_MB_MAGIC 
+      if (header->magic == MULTIBOOT_MAGIC 
 	  && !(header->magic + header->flags + header->checksum))
 	break;
     }
@@ -286,7 +284,7 @@ grub_rescue_cmd_multiboot (int argc, cha
       goto fail;
     }
 
-  if (header->flags & GRUB_MB_UNSUPPORTED)
+  if (header->flags & MULTIBOOT_UNSUPPORTED)
     {
       grub_error (GRUB_ERR_UNKNOWN_OS,
 		  "Unsupported flag: 0x%x", header->flags);
@@ -300,7 +298,7 @@ grub_rescue_cmd_multiboot (int argc, cha
   if (! mbi)
     goto fail;
 
-  mbi->flags = GRUB_MB_INFO_MEMORY;
+  mbi->flags = MULTIBOOT_INFO_MEMORY;
 
   /* Convert from bytes to kilobytes.  */
   mbi->mem_lower = grub_lower_mem / 1024;
@@ -322,10 +320,10 @@ grub_rescue_cmd_multiboot (int argc, cha
   /* Remove the space after the last word.  */
   *(--p) = '\0';
   
-  mbi->flags |= GRUB_MB_INFO_CMDLINE;
+  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
   mbi->cmdline = (grub_uint32_t) cmdline;
 
-  mbi->flags |= GRUB_MB_INFO_BOOT_LOADER_NAME;
+  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
   mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING);
 
   grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
@@ -344,7 +342,7 @@ grub_rescue_cmd_multiboot (int argc, cha
 
 
 void
-grub_rescue_cmd_module  (int argc, char *argv[])
+grub_module  (int argc, char *argv[])
 {
   grub_file_t file = 0;
   grub_ssize_t size, len = 0;
@@ -369,7 +367,7 @@ grub_rescue_cmd_module  (int argc, char 
     goto fail;
 
   size = grub_file_size (file);
-  module = grub_memalign (GRUB_MB_MOD_ALIGN, size);
+  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
   if (! module)
     goto fail;
 
@@ -395,7 +393,7 @@ grub_rescue_cmd_module  (int argc, char 
   /* Remove the space after the last word.  */
   *(--p) = '\0';
 
-  if (mbi->flags & GRUB_MB_INFO_MODS)
+  if (mbi->flags & MULTIBOOT_INFO_MODS)
     {
       struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr;
 
@@ -422,7 +420,7 @@ grub_rescue_cmd_module  (int argc, char 
       modlist->pad = 0;
       mbi->mods_count = 1;
       mbi->mods_addr = (grub_uint32_t) modlist;
-      mbi->flags |= GRUB_MB_INFO_MODS;
+      mbi->flags |= MULTIBOOT_INFO_MODS;
     }
 
  fail:
@@ -435,19 +433,3 @@ grub_rescue_cmd_module  (int argc, char 
       grub_free (cmdline);
     }
 }
-
-
-GRUB_MOD_INIT(multiboot)
-{
-  grub_rescue_register_command ("multiboot", grub_rescue_cmd_multiboot,
-				"load a multiboot kernel");
-  grub_rescue_register_command ("module", grub_rescue_cmd_module,
-				"load a multiboot module");
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(multiboot)
-{
-  grub_rescue_unregister_command ("multiboot");
-  grub_rescue_unregister_command ("module");
-}
diff -r b85dfdfcce16 loader/i386/pc/multiboot2.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/i386/pc/multiboot2.c	Thu Jul 05 01:20:12 2007 -0500
@@ -0,0 +1,101 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  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 <multiboot2.h>
+#include <grub/multiboot2.h>
+#include <grub/elf.h>
+#include <grub/err.h>
+#include <grub/machine/loader.h>
+#include <grub/mm.h>
+
+grub_err_t
+grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  Elf32_Addr paddr = phdr->p_paddr;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range", 
+                      paddr);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  Elf64_Addr paddr = phdr->p_paddr;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return (GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range",
+            paddr);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+  grub_addr_t modaddr;
+
+  modaddr = grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
+  if (! modaddr)
+    return grub_errno;
+
+  *addr = modaddr;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
+{
+  grub_free((void *) addr);
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry, void *tags)
+{
+  grub_multiboot2_real_boot (entry, tags);
+}
+
+void grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+   struct multiboot_tag_header *tag;
+   
+   /* Free all module memory in the tag list.  */
+   for_each_tag (tag, tags)
+     {
+       if (tag->key == MULTIBOOT2_TAG_MODULE)
+         {
+           struct multiboot_tag_module *module =
+              (struct multiboot_tag_module *) tag;
+           grub_free((void *) module->addr);
+         }
+     }
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+  /* XXX Create boot device et al. */
+  return GRUB_ERR_NONE;
+}
diff -r b85dfdfcce16 loader/i386/pc/multiboot_normal.c
--- a/loader/i386/pc/multiboot_normal.c	Wed Jul 04 15:53:23 2007 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* multiboot_normal.c - boot another boot loader */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005  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 <grub/machine/loader.h>
-#include <grub/err.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-
-static grub_err_t
-grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ ((unused)),
-			   int argc, char **args)
-{
-  grub_rescue_cmd_multiboot (argc, args);
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)),
-			int argc, char **args)
-{
-  grub_rescue_cmd_module (argc, args);
-  return grub_errno;
-}
-
-GRUB_MOD_INIT(multiboot_normal)
-{
-  (void) mod; /* To stop warning.  */
-  grub_register_command ("multiboot", grub_normal_cmd_multiboot,
-			 GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
-			 "multiboot FILE [ARGS...]",
-			 "Load a Multiboot kernel.", 0);
-  
-  grub_register_command ("module", grub_normal_cmd_module,
-			 GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
-			 "module FILE [ARGS...]",
-			 "Load a Multiboot module.", 0);
-}
-
-GRUB_MOD_FINI(multiboot_normal)
-{
-  grub_unregister_command ("multiboot");
-  grub_unregister_command ("module");
-}
diff -r b85dfdfcce16 loader/multiboot2.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/multiboot2.c	Thu Jul 05 17:48:07 2007 -0500
@@ -0,0 +1,464 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  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 <multiboot2.h>
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/multiboot2.h>
+#include <grub/elfload.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>
+
+static grub_addr_t entry;
+extern grub_dl_t my_mod;
+
+static char *grub_mb2_tags;
+static char *grub_mb2_tags_pos;
+static grub_size_t grub_mb2_tags_len;
+static int grub_mb2_tags_count;
+
+static void
+grub_mb2_tags_free (void)
+{
+  grub_dprintf ("loader", "Freeing all tags...\n");
+  grub_free (grub_mb2_tags);
+  grub_mb2_tags = 0;
+  grub_mb2_tags_pos = 0;
+  grub_mb2_tags_len = 0;
+  grub_mb2_tags_count = 0;
+}
+
+grub_err_t
+grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len)
+{
+  struct multiboot_tag_header *tag;
+  grub_size_t used;
+  grub_size_t needed;
+
+  grub_dprintf ("loader", "Allocating tag: key 0x%x, size 0x%lx.\n",
+		key, (unsigned long) len);
+
+  used = grub_mb2_tags_pos - grub_mb2_tags;
+  len = ALIGN_UP (len, sizeof (multiboot_word));
+
+  needed = used + len;
+
+  if (needed > grub_mb2_tags_len)
+    {
+      /* Allocate new buffer.  */
+      grub_size_t newsize = needed * 2;
+      char *newarea;
+
+      grub_dprintf ("loader", "Reallocating tag buffer (new size 0x%lx).\n",
+		    (unsigned long) newsize);
+
+      newarea = grub_malloc (newsize);
+      if (! newarea)
+	return grub_errno;
+      grub_memcpy (newarea, grub_mb2_tags, grub_mb2_tags_len);
+      grub_free (grub_mb2_tags);
+
+      grub_mb2_tags_len = newsize;
+      grub_mb2_tags = newarea;
+      grub_mb2_tags_pos = newarea + used;
+    }
+
+  tag = (struct multiboot_tag_header *) grub_mb2_tags_pos;
+  grub_mb2_tags_pos += len;
+
+  tag->key = key;
+  tag->len = len;
+
+  if (addr)
+    *addr = (grub_addr_t) tag;
+
+  grub_mb2_tags_count++;
+
+  grub_dprintf ("loader", "Allocated tag %u at %p.\n", grub_mb2_tags_count, tag);
+
+  return 0;
+}
+
+static grub_err_t
+grub_mb2_tag_start_create (void)
+{
+  return grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_START,
+			    sizeof (struct multiboot_tag_start));
+}
+
+static grub_err_t
+grub_mb2_tag_name_create (void)
+{
+  struct multiboot_tag_name *name;
+  grub_addr_t name_addr;
+  grub_err_t err;
+  const char *grub_version = PACKAGE_STRING;
+
+  err = grub_mb2_tag_alloc (&name_addr, MULTIBOOT2_TAG_NAME,
+			   sizeof (struct multiboot_tag_name) +
+			   sizeof (grub_version) + 1);
+  if (err)
+    return err;
+
+  name = (struct multiboot_tag_name *) name_addr;
+  grub_strcpy (name->name, grub_version);
+
+  return GRUB_ERR_NONE;
+}
+
+typedef grub_err_t (*tag_create_t) (void);
+static tag_create_t grub_mb2_tag_creators[] = {
+  grub_mb2_tag_start_create,
+  grub_mb2_tag_name_create,
+  grub_mb2_tags_arch_create,
+  0,
+};
+
+static grub_err_t
+grub_mb2_tags_create (void)
+{
+  tag_create_t *creator;
+  grub_err_t err;
+
+  for (creator = grub_mb2_tag_creators; *creator != 0; creator++)
+    {
+      err = (*creator) ();
+      if (err)
+	goto error;
+    }
+
+  return GRUB_ERR_NONE;
+
+error:
+  grub_error_push ();
+  grub_mb2_tags_free ();
+  grub_error_pop ();
+  return err;
+}
+
+static grub_err_t
+grub_mb2_tags_finish (void)
+{
+  struct multiboot_tag_start *start;
+  grub_err_t err;
+
+  /* Create the `end' tag.  */
+  err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END,
+			   sizeof (struct multiboot_tag_end));
+  if (err)
+    goto error;
+
+  /* We created the `start' tag first.  Update it now.  */
+  start = (struct multiboot_tag_start *) grub_mb2_tags;
+  start->size = grub_mb2_tags_pos - grub_mb2_tags;
+  return GRUB_ERR_NONE;
+
+error:
+  grub_error_push ();
+  grub_mb2_tags_free ();
+  grub_error_pop ();
+  return err;
+}
+
+static grub_err_t
+grub_mb2_boot (void)
+{
+  grub_mb2_tags_finish ();
+
+  grub_dprintf ("loader", "Tags at %p\n", grub_mb2_tags);
+  grub_mb2_arch_boot (entry, grub_mb2_tags);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_mb2_unload (void)
+{
+  struct multiboot_tag_header *tag;
+  struct multiboot_tag_header *tags =
+    (struct multiboot_tag_header *) grub_mb2_tags;
+
+  /* Free all module memory in the tag list.  */
+  for_each_tag (tag, tags)
+    {
+      if (tag->key == MULTIBOOT2_TAG_MODULE)
+	{
+	  struct multiboot_tag_module *module =
+	      (struct multiboot_tag_module *) tag;
+	  grub_free ((void *) module->addr);
+	}
+    }
+
+  /* Allow architecture to un-reserve memory.  */
+  grub_mb2_arch_unload (tags);
+
+  /* Free the tags themselves.  */
+  grub_mb2_tags_free ();
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer)
+{
+  /* XXX Create module tag here.  */
+  return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported");
+}
+
+/* Create the tag containing the cmdline and the address of the module data.  */
+static grub_err_t
+grub_mb2_tag_module_create (grub_addr_t modaddr, grub_size_t modsize,
+			    char *type, int key, int argc, char *argv[])
+{
+  struct multiboot_tag_module *module;
+  grub_ssize_t argslen = 0;
+  grub_err_t err;
+  char *p;
+  grub_addr_t module_addr;
+  int i;
+
+  /* Allocate enough space for the arguments and spaces between them.  */
+  for (i = 0; i < argc; i++)
+    argslen += grub_strlen (argv[i]) + 1;
+
+  /* Note: includes implicit 1-byte cmdline.  */
+  err = grub_mb2_tag_alloc (&module_addr, key,
+			   sizeof (struct multiboot_tag_module) + argslen);
+  if (err)
+    return grub_errno;
+
+  module = (struct multiboot_tag_module *) module_addr;
+  module->addr = modaddr;
+  module->size = modsize;
+  grub_strcpy(module->type, type);
+
+  /* Fill in the command line.  */
+  p = module->cmdline;
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *p++ = ' ';
+    }
+  module->cmdline[argslen] = '\0';
+
+  for (i=0; i < argslen+8; i++)
+    grub_printf(" %x", module->cmdline[i]);
+  grub_printf("\n");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load ELF32 or ELF64.  */
+static grub_err_t
+grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[])
+{
+  grub_addr_t kern_base;
+  grub_size_t kern_size;
+  grub_err_t err;
+
+  if (grub_elf_is_elf32 (elf))
+    {
+      entry = elf->ehdr.ehdr32.e_entry;
+      err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base,
+			     &kern_size);
+    }
+  else if (grub_elf_is_elf64 (elf))
+    {
+      entry = elf->ehdr.ehdr64.e_entry;
+      err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base,
+			     &kern_size);
+    }
+  else
+    err = grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
+
+  if (err)
+    goto fail;
+
+  grub_dprintf ("loader", "Entry point is 0x%lx.\n", (unsigned long) entry);
+
+  grub_mb2_tag_module_create (kern_base, kern_size, "kernel",
+			     MULTIBOOT2_TAG_MODULE, argc, argv);
+
+fail:
+  return err;
+}
+
+void
+grub_multiboot2 (int argc, char *argv[])
+{
+  char *buffer;
+  grub_file_t file = 0;
+  grub_elf_t elf = 0;
+  struct multiboot_header *header = 0;
+  char *p;
+  grub_ssize_t len;
+  grub_err_t err;
+  int header_found = 0;
+
+  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;
+    }
+
+  buffer = grub_malloc (MULTIBOOT2_HEADER_SEARCH);
+  if (! buffer)
+    return;
+
+  len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_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 (p = buffer; p <= buffer + len - 12; p += 4)
+    {
+      header = (struct multiboot_header *) p;
+      if (header->magic == MULTIBOOT2_HEADER_MAGIC)
+	{
+	  header_found = 1;
+	  break;
+	}
+    }
+
+  if (! header_found)
+    grub_dprintf ("loader", "No multiboot header found.\n");
+
+  /* Create the basic tags.  */
+  grub_dprintf ("loader", "Creating multiboot tags\n");
+  grub_mb2_tags_create ();
+
+  /* Load the kernel and create its tag.  */
+  elf = grub_elf_file (file);
+  if (elf)
+    {
+      grub_dprintf ("loader", "Loading ELF multiboot file.\n");
+      err = grub_mb2_load_elf (elf, argc-1, &argv[1]);
+      grub_elf_close (elf);
+    }
+  else
+    {
+      grub_dprintf ("loader", "Loading non-ELF multiboot file.\n");
+
+      if (header)
+	err = grub_mb2_load_other (file, header);
+      else
+	err = grub_error (GRUB_ERR_BAD_OS,
+			  "Need multiboot header to load non-ELF files.");
+      grub_file_close (file);
+    }
+
+  grub_free (buffer);
+
+  if (err)
+    goto fail;
+
+  /* Good to go.  */
+  grub_loader_set (grub_mb2_boot, grub_mb2_unload, 1);
+  return;
+
+fail:
+  grub_mb2_tags_free ();
+  grub_dl_unref (my_mod);
+}
+
+void
+grub_module2 (int argc, char *argv[])
+{
+  grub_file_t file;
+  grub_addr_t modaddr = 0;
+  grub_ssize_t modsize = 0;
+  grub_err_t err;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      return;
+    }
+
+  if (argc == 1)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified");
+      return;
+    }
+
+  if (entry == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+		  "You need to load the multiboot kernel first");
+      return;
+    }
+
+  /* Load module data.  */
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto out;
+
+  modsize = grub_file_size (file);
+  err = grub_mb2_arch_module_alloc (modsize, &modaddr);
+  if (err)
+    goto out;
+
+  grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr,
+		modaddr + modsize);
+  if (grub_file_read (file, (char *) modaddr, modsize) != modsize)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto out;
+    }
+
+  /* Create the module tag.  */
+  err = grub_mb2_tag_module_create (modaddr, modsize,
+				   argv[1], MULTIBOOT2_TAG_MODULE,
+				   argc-2, &argv[2]);
+  if (err)
+    goto out;
+
+out:
+  grub_error_push ();
+
+  if (file)
+    grub_file_close (file);
+
+  if (modaddr)
+    grub_mb2_arch_module_free (modaddr, modsize);
+
+  grub_error_pop ();
+}
diff -r b85dfdfcce16 loader/multiboot_loader.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/multiboot_loader.c	Thu Jul 05 17:46:39 2007 -0500
@@ -0,0 +1,199 @@
+/* multiboot_loader.c - boot multiboot 1 or 2 OS image */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  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 <multiboot2.h>
+#include <grub/multiboot_loader.h>
+#include <grub/multiboot.h>
+#include <grub/multiboot2.h>
+#include <grub/elf.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>
+
+grub_dl_t my_mod;
+
+/* This tracks which version of multiboot to use when using
+ * the module command. By default use multiboot version 1.
+ * values:
+ *      1 - Mulitboot version 1 
+ *      2 - Mutliboot version 2
+ */
+
+static unsigned int module_version_status = 1; 
+
+static int find_multi_boot1_header (grub_file_t file)
+{
+  struct grub_multiboot_header *header;
+  char buffer[MULTIBOOT_SEARCH];
+  int found_status = 0;
+  grub_ssize_t len;
+ 
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    return found_status;
+
+  /* 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))
+        {
+           found_status = 1;
+           break;
+        }
+     }
+
+   return found_status;
+}
+
+static int find_multi_boot2_header (grub_file_t file)
+{
+  char *buffer;
+  struct multiboot_header *header = 0;
+  grub_ssize_t len; 
+  int found_status = 0;
+  char *p;
+
+  len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH);
+  if (len < 32)
+    return found_status;
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (p = buffer; p <= buffer + len - 12; p += 4)
+    {
+      header = (struct multiboot_header *) p;
+      if (header->magic == MULTIBOOT2_HEADER_MAGIC)
+        {
+          found_status = 1;
+          break;
+        }
+    }
+}
+
+void grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
+{
+  
+  grub_file_t file = 0;
+  int header_multi_1_found = 0;
+  int header_multi_2_found = 0;
+
+  grub_dl_ref (my_mod);
+
+  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;
+    }
+
+  /* find which header is in the file */
+  if (find_multi_boot1_header(file))
+    header_multi_1_found = 1;
+  else if (find_multi_boot2_header(file))
+    header_multi_2_found = 1;
+  else
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found"); 
+      goto fail;
+    }
+
+   /* close file before calling functions */
+   if (file)
+     grub_file_close (file);
+
+   /* Launch multi boot with header */
+
+   /* XXX Find a better way to identify this. 
+      This is for i386-pc */
+#ifdef __i386__
+  if (header_multi_1_found)
+    {
+      grub_dprintf ("multiboot_loader",
+           "Launching multiboot 1 grub_multiboot() function");
+      grub_multiboot (argc, argv);     
+      module_version_status = 1;
+    }
+#endif
+  if (header_multi_2_found)
+    {
+      grub_dprintf ("multiboot_loader",
+           "Launching mulitboot 2 grub_multiboot2() function");
+      grub_multiboot2 (argc, argv);
+      module_version_status = 2;
+    }
+
+   return;
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  grub_dl_unref (my_mod);
+}
+
+void grub_rescue_cmd_module_loader (int argc, char *argv[])
+{
+
+#ifdef __i386__
+  if (module_version_status == 1)
+    {
+      grub_dprintf("multiboot_loader",
+           "Launching multiboot 1 grub_module() function");
+      grub_module (argc, argv);
+    }
+#endif
+  if (module_version_status == 2)
+    {
+      grub_dprintf("multiboot_loader",
+          "Launching multiboot 2 grub_module2() function");
+      grub_module2 (argc, argv);
+    }
+}
+
+GRUB_MOD_INIT(multiboot)
+{
+  grub_rescue_register_command ("multiboot", grub_rescue_cmd_multiboot_loader,
+				"load a multiboot kernel");
+  grub_rescue_register_command ("module", grub_rescue_cmd_module_loader,
+                               "load a multiboot module");
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(multiboot)
+{
+  grub_rescue_unregister_command ("mulitboot");
+  grub_rescue_unregister_command ("module");
+}
diff -r b85dfdfcce16 loader/multiboot_loader_normal.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/multiboot_loader_normal.c	Wed Jul 04 17:20:44 2007 -0500
@@ -0,0 +1,62 @@
+/* multiboot_loader_normal.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005  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 <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/multiboot_loader.h>
+
+static grub_err_t
+grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ ((unused)),
+			   int argc, char **args)
+{
+  grub_rescue_cmd_multiboot_loader (argc, args);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)),
+			int argc, char **args)
+{
+  grub_rescue_cmd_module_loader (argc, args);
+  return grub_errno;
+}
+
+GRUB_MOD_INIT(multiboot_loader_normal)
+{
+  (void) mod; /* To stop warning.  */
+  grub_register_command ("multiboot", grub_normal_cmd_multiboot,
+                         GRUB_COMMAND_FLAG_BOTH
+                         | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+                         "multiboot FILE [ARGS...]",
+                         "Load a Multiboot kernel.", 0);
+
+  grub_register_command ("module", grub_normal_cmd_module,
+			 GRUB_COMMAND_FLAG_BOTH
+                         | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+                         "module FILE [ARGS...]",
+                         "Load a Multiboot module.", 0);
+}
+
+GRUB_MOD_FINI(multiboot_loader_normal)
+{
+  grub_unregister_command ("multiboot");
+  grub_unregister_command ("module");
+}
diff -r b85dfdfcce16 loader/powerpc/ieee1275/multiboot2.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/powerpc/ieee1275/multiboot2.c	Thu Jul 05 08:12:29 2007 -0500
@@ -0,0 +1,120 @@
+/* multiboot.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  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 <multiboot2.h>
+#include <grub/loader.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/multiboot2.h>
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+
+typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
+                                unsigned long, unsigned long);
+
+/* Claim the memory occupied by the multiboot kernel.  */
+grub_err_t
+grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  int rc;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
+		phdr->p_paddr + phdr->p_memsz);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Claim the memory occupied by the multiboot kernel.  */
+grub_err_t
+grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  int rc;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
+		(unsigned long) phdr->p_paddr,
+		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+  int rc;
+
+  /* XXX Will need to map on some firmwares.  */
+  rc = grub_ieee1275_claim (0, size, MULTIBOOT2_MOD_ALIGN, addr);
+  if (rc)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Firmware couldn't allocate memory (size 0x%lx)", size);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size)
+{
+  grub_ieee1275_release (addr, size);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+  /* Nothing special.  */
+  return GRUB_ERR_NONE;
+}
+
+/* Release the memory we claimed from Open Firmware above.  */
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+  struct multiboot_tag_header *tag;
+
+  /* Free all module memory in the tag list.  */
+  for_each_tag (tag, tags)
+    {
+      if (tag->key == MULTIBOOT2_TAG_MODULE)
+	{
+	  struct multiboot_tag_module *module =
+	      (struct multiboot_tag_module *) tag;
+	  grub_ieee1275_release (module->addr, module->size);
+	}
+    }
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags)
+{
+  kernel_entry_t entry = (kernel_entry_t) entry_addr;
+  entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0);
+}

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

end of thread, other threads:[~2007-07-25 19:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-07 15:53 [RFC] [PATCH] Add multiboot 2 capabilities Jerone Young
2007-07-07 18:12 ` Otavio Salvador
2007-07-08  8:25   ` Jerone Young
2007-07-22 13:22     ` Marco Gerards
2007-07-24 18:04       ` Jerone Young
2007-07-25  9:53         ` Marco Gerards
2007-07-25 10:03           ` Stefan Reinauer
2007-07-25 10:12             ` Marco Gerards
2007-07-25 12:54             ` Hollis Blanchard
2007-07-25 19:18             ` Jerone Young

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.