[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[2005] 2009-02-27 Robert Millan <address@hidden>
From: |
Robert Millan |
Subject: |
[2005] 2009-02-27 Robert Millan <address@hidden> |
Date: |
Fri, 27 Feb 2009 21:19:01 +0000 |
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 <address@hidden>
* 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 <address@hidden>
+ * loader/i386/pc/multiboot.c: Move from here ...
+ * loader/i386/multiboot.c: ... to here. Update all users.
+
+2009-02-27 Robert Millan <address@hidden>
+
Patch from Alexandre Bique <address@hidden>
* 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);
- }
-}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [2005] 2009-02-27 Robert Millan <address@hidden>,
Robert Millan <=