+2010-01-07 Robert Millan <rmh.grub@aybabtu.com>
+
+ Reset Multiboot 2 support. New loader implements the draft in
+ /branches/multiboot2 and shares as much code as possible with the
+ production Multiboot 1 implementation.
+
+ * loader/ieee1275/multiboot2.c: Remove file. Update all users.
+ * loader/multiboot2.c: Likewise.
+ * loader/i386/multiboot_helper.S: Likewise.
+ * include/multiboot2.h: Replace with latest version from the draft
+ in /branches/multiboot2.
+
+ * conf/i386-coreboot.rmk (multiboot_mod_SOURCES): Remove
+ `loader/i386/multiboot_helper.S', `loader/i386/pc/multiboot2.c'
+ and `loader/multiboot2.c'.
+ (pkglib_MODULES): Add `multiboot2.mod'.
+ (multiboot2_mod_SOURCES): New variable.
+ (multiboot2_mod_LDFLAGS): Likewise.
+ (multiboot2_mod_CFLAGS): Likewise. Define `GRUB_USE_MULTIBOOT2'.
+
+ * conf/i386-pc.rmk: Likewise.
+
+ * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Remove `multiboot.mod'.
+ (multiboot_mod_SOURCES): Remove variable.
+ (multiboot_mod_LDFLAGS): Likewise.
+ (multiboot_mod_CFLAGS): Likewise.
+
+ * include/grub/multiboot.h [GRUB_USE_MULTIBOOT2]: Include
+ `<multiboot2.h>' instead of `<multiboot.h>'.
+ [GRUB_USE_MULTIBOOT2] (MULTIBOOT_BOOTLOADER_MAGIC)
+ (MULTIBOOT_HEADER_MAGIC): New macros.
+
+ * loader/multiboot_loader.c (module_version_status): Remove variable.
+ (find_multi_boot2_header): Remove function.
+ (grub_cmd_multiboot_loader): Remove Multiboot 2 / Multiboot 1 selection
+ logic. Always check for the Multiboot version we're compiling for.
+ (grub_cmd_module_loader): Likewise.
+ [GRUB_USE_MULTIBOOT2] (GRUB_MOD_INIT(multiboot)): Register `multiboot2'
+ command instead of `multiboot'.
+
2010-01-07 Robert Millan <rmh.grub@aybabtu.com>
* include/multiboot.h (MULTIBOOT_UNSUPPORTED): Moved from here ...
grub_mkrescue_SOURCES = util/grub-mkrescue.in
# Modules.
-pkglib_MODULES = linux.mod multiboot.mod \
+pkglib_MODULES = linux.mod \
aout.mod play.mod serial.mod \
memdisk.mod pci.mod lspci.mod reboot.mod \
halt.mod datetime.mod date.mod datehook.mod \
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For multiboot.mod.
+pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \
- loader/i386/multiboot_helper.S \
- loader/i386/pc/multiboot2.c \
- loader/multiboot2.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+pkglib_MODULES += multiboot2.mod
+multiboot2_mod_SOURCES = loader/i386/multiboot.c \
+ loader/multiboot_loader.c
+multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
+multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
# For aout.mod.
aout_mod_SOURCES = loader/aout.c
aout_mod_CFLAGS = $(COMMON_CFLAGS)
grub_mkrescue_SOURCES = util/grub-mkrescue.in
pkglib_MODULES = biosdisk.mod chain.mod \
- multiboot.mod reboot.mod halt.mod \
+ reboot.mod halt.mod \
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For multiboot.mod.
+pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \
- loader/i386/multiboot_helper.S \
- loader/i386/pc/multiboot2.c \
- loader/multiboot2.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+pkglib_MODULES += multiboot2.mod
+multiboot2_mod_SOURCES = loader/i386/multiboot.c \
+ loader/multiboot_loader.c
+multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
+multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
# For vbe.mod.
vbe_mod_SOURCES = video/i386/pc/vbe.c
vbe_mod_CFLAGS = $(COMMON_CFLAGS)
linux.mod \
reboot.mod \
suspend.mod \
- multiboot.mod \
memdisk.mod \
lsmmap.mod
halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For multiboot.mod
-multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
- loader/multiboot2.c \
- loader/multiboot_loader.c
-multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
-multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
# For memdisk.mod.
memdisk_mod_SOURCES = disk/memdisk.c
memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
/* multiboot.h - multiboot header file with grub definitions. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2007,2008,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#ifndef GRUB_MULTIBOOT_HEADER
#define GRUB_MULTIBOOT_HEADER 1
+#ifdef GRUB_USE_MULTIBOOT2
+#include <multiboot2.h>
+/* Same thing as far as our loader is concerned. */
+#define MULTIBOOT_BOOTLOADER_MAGIC MULTIBOOT2_BOOTLOADER_MAGIC
+#define MULTIBOOT_HEADER_MAGIC MULTIBOOT2_HEADER_MAGIC
+#else
#include <multiboot.h>
+#endif
void grub_multiboot (int argc, char *argv[]);
void grub_module (int argc, char *argv[]);
-/* multiboot2.h - multiboot 2 header file. */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2007,2009 Free Software Foundation, Inc.
+/* multiboot2.h - Multiboot 2 header file. */
+/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
*
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
*
- * 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.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
+ * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifndef MULTIBOOT2_HEADER
-#define MULTIBOOT2_HEADER 1
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
/* How many bytes from the start of the file we search for the header. */
-#define MULTIBOOT2_HEADER_SEARCH 8192
+#define MULTIBOOT_SEARCH 8192
/* The magic field should contain this. */
-#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
+#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
-/* Passed from the bootloader to the kernel. */
-#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
+/* This should be in %eax. */
+#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
/* Alignment of multiboot modules. */
-#define MULTIBOOT2_MOD_ALIGN 0x00001000
+#define MULTIBOOT_MOD_ALIGN 0x00001000
-#ifndef ASM_FILE
+/* Alignment of the multiboot info structure. */
+#define MULTIBOOT_INFO_ALIGN 0x00000004
-#ifndef __WORDSIZE
-#include <stdint.h>
-#endif
+/* Flags set in the 'flags' member of the multiboot header. */
-/* XXX not portable? */
-#if __WORDSIZE == 64
-typedef uint64_t multiboot2_word;
-#else
-typedef uint32_t multiboot2_word;
-#endif
+/* Align all boot modules on i386 page (4KB) boundaries. */
+#define MULTIBOOT_PAGE_ALIGN 0x00000001
-struct multiboot2_header
-{
- uint32_t magic;
- uint32_t flags;
-};
+/* Must pass memory information to OS. */
+#define MULTIBOOT_MEMORY_INFO 0x00000002
-struct multiboot2_tag_header
-{
- uint32_t key;
- uint32_t len;
-};
+/* Must pass video information to OS. */
+#define MULTIBOOT_VIDEO_MODE 0x00000004
-#define MULTIBOOT2_TAG_RESERVED1 0
-#define MULTIBOOT2_TAG_RESERVED2 (~0)
+/* This flag indicates the use of the address fields in the header. */
+#define MULTIBOOT_AOUT_KLUDGE 0x00010000
-#define MULTIBOOT2_TAG_START 1
-struct multiboot2_tag_start
-{
- struct multiboot2_tag_header header;
- multiboot2_word size; /* Total size of all multiboot tags. */
-};
+/* 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 */
-#define MULTIBOOT2_TAG_NAME 2
-struct multiboot2_tag_name
+/* 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
+
+#ifndef ASM_FILE
+
+typedef unsigned short multiboot_uint16_t;
+typedef unsigned int multiboot_uint32_t;
+typedef unsigned long long multiboot_uint64_t;
+
+struct multiboot_header
{
- struct multiboot2_tag_header header;
- char name[1];
+ /* Must be MULTIBOOT_MAGIC - see above. */
+ multiboot_uint32_t magic;
+
+ /* Feature flags. */
+ multiboot_uint32_t flags;
+
+ /* The above fields plus this one must equal 0 mod 2^32. */
+ multiboot_uint32_t checksum;
+
+ /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
+ multiboot_uint32_t header_addr;
+ multiboot_uint32_t load_addr;
+ multiboot_uint32_t load_end_addr;
+ multiboot_uint32_t bss_end_addr;
+ multiboot_uint32_t entry_addr;
+
+ /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
+ multiboot_uint32_t mode_type;
+ multiboot_uint32_t width;
+ multiboot_uint32_t height;
+ multiboot_uint32_t depth;
};
-#define MULTIBOOT2_TAG_MODULE 3
-struct multiboot2_tag_module
+/* The symbol table for a.out. */
+struct multiboot_aout_symbol_table
{
- struct multiboot2_tag_header header;
- multiboot2_word addr;
- multiboot2_word size;
- char type[36];
- char cmdline[1];
+ multiboot_uint32_t tabsize;
+ multiboot_uint32_t strsize;
+ multiboot_uint32_t addr;
+ multiboot_uint32_t reserved;
};
+typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
-#define MULTIBOOT2_TAG_MEMORY 4
-struct multiboot2_tag_memory
+/* The section header table for ELF. */
+struct multiboot_elf_section_header_table
{
- struct multiboot2_tag_header header;
- multiboot2_word addr;
- multiboot2_word size;
- multiboot2_word type;
+ multiboot_uint32_t num;
+ multiboot_uint32_t size;
+ multiboot_uint32_t addr;
+ multiboot_uint32_t shndx;
};
+typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
-#define MULTIBOOT2_TAG_UNUSED 5
-struct multiboot2_tag_unused
+struct multiboot_info
{
- struct multiboot2_tag_header header;
+ /* Multiboot info version number */
+ multiboot_uint32_t flags;
+
+ /* Available memory from BIOS */
+ multiboot_uint32_t mem_lower;
+ multiboot_uint32_t mem_upper;
+
+ /* "root" partition */
+ multiboot_uint32_t boot_device;
+
+ /* Kernel command line */
+ multiboot_uint32_t cmdline;
+
+ /* Boot-Module list */
+ multiboot_uint32_t mods_count;
+ multiboot_uint32_t mods_addr;
+
+ union
+ {
+ multiboot_aout_symbol_table_t aout_sym;
+ multiboot_elf_section_header_table_t elf_sec;
+ } u;
+
+ /* Memory Mapping buffer */
+ multiboot_uint32_t mmap_length;
+ multiboot_uint32_t mmap_addr;
+
+ /* Drive Info buffer */
+ multiboot_uint32_t drives_length;
+ multiboot_uint32_t drives_addr;
+
+ /* ROM configuration table */
+ multiboot_uint32_t config_table;
+
+ /* Boot Loader Name */
+ multiboot_uint32_t boot_loader_name;
+
+ /* APM table */
+ multiboot_uint32_t apm_table;
+
+ /* Video */
+ multiboot_uint32_t vbe_control_info;
+ multiboot_uint32_t vbe_mode_info;
+ multiboot_uint16_t vbe_mode;
+ multiboot_uint16_t vbe_interface_seg;
+ multiboot_uint16_t vbe_interface_off;
+ multiboot_uint16_t vbe_interface_len;
};
+typedef struct multiboot_info multiboot_info_t;
-#define MULTIBOOT2_TAG_END 0xffff
-struct multiboot2_tag_end
+struct multiboot_mmap_entry
+{
+ multiboot_uint32_t size;
+ multiboot_uint64_t addr;
+ multiboot_uint64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE 1
+#define MULTIBOOT_MEMORY_RESERVED 2
+ multiboot_uint32_t type;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
+
+struct multiboot_mod_list
{
- struct multiboot2_tag_header header;
+ /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+ multiboot_uint32_t mod_start;
+ multiboot_uint32_t mod_end;
+
+ /* Module command line */
+ multiboot_uint32_t cmdline;
+
+ /* padding to take it to 16 bytes (must be zero) */
+ multiboot_uint32_t pad;
};
+typedef struct multiboot_mod_list multiboot_module_t;
#endif /* ! ASM_FILE */
-#endif /* ! MULTIBOOT2_HEADER */
+#endif /* ! MULTIBOOT_HEADER */
+++ /dev/null
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,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/>.
- */
-
-#include <grub/symbol.h>
-#include <multiboot.h>
-#include <multiboot2.h>
-
- .p2align 2 /* force 4-byte alignment */
-
-/*
- * 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
-
- /* Interrupts should be disabled. */
- cli
-
- /* Move the magic value into eax and jump to the kernel. */
- movl $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
- popl %ecx
-
- cld
- jmp *%ecx
+++ /dev/null
-/* multiboot.c - boot a multiboot 2 OS image. */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2007,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/>.
- */
-
-#include <grub/loader.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/multiboot2.h>
-#include <multiboot2.h>
-#include <grub/err.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/machine/kernel.h>
-#include <grub/machine/loader.h>
-#ifdef __i386__
-#include <grub/cpu/multiboot.h>
-#endif
-
-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,
- grub_addr_t *addr __attribute__((unused)),
- int *do_load)
-{
- int rc;
-
- if (phdr->p_type != PT_LOAD)
- {
- *do_load = 0;
- return 0;
- }
- *do_load = 1;
-
- 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,
- grub_addr_t *addr __attribute__((unused)),
- int *do_load)
-{
- int rc;
-
- if (phdr->p_type != PT_LOAD)
- {
- *do_load = 0;
- return 0;
- }
- *do_load = 1;
-
- 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 multiboot2_tag_header *tags)
-{
- struct multiboot2_tag_header *tag;
-
- /* Free all module memory in the tag list. */
- for_each_tag (tag, tags)
- {
- if (tag->key == MULTIBOOT2_TAG_MODULE)
- {
- struct multiboot2_tag_module *module =
- (struct multiboot2_tag_module *) tag;
- grub_ieee1275_release (module->addr, module->size);
- }
- }
-}
-
-void
-grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags)
-{
-#if defined(__powerpc__)
- kernel_entry_t entry = (kernel_entry_t) entry_addr;
- entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0);
-#elif defined(__i386__)
- grub_multiboot2_real_boot (entry_addr, tags);
-#else
-#error
-#endif
-}
+++ /dev/null
-/* multiboot2.c - boot a multiboot 2 OS image. */
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2007,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/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/multiboot2.h>
-#include <multiboot2.h>
-#include <grub/elfload.h>
-#include <grub/file.h>
-#include <grub/err.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 multiboot2_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 (multiboot2_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 multiboot2_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 multiboot2_tag_start));
-}
-
-static grub_err_t
-grub_mb2_tag_name_create (void)
-{
- struct multiboot2_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 multiboot2_tag_name) +
- sizeof (grub_version) + 1);
- if (err)
- return err;
-
- name = (struct multiboot2_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 multiboot2_tag_start *start;
- grub_err_t err;
-
- /* Create the `end' tag. */
- err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END,
- sizeof (struct multiboot2_tag_end));
- if (err)
- goto error;
-
- /* We created the `start' tag first. Update it now. */
- start = (struct multiboot2_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 multiboot2_tag_header *tag;
- struct multiboot2_tag_header *tags =
- (struct multiboot2_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 multiboot2_tag_module *module =
- (struct multiboot2_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 (grub_file_t file __attribute__ ((unused)),
- void *buffer __attribute__ ((unused)))
-{
- /* 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 multiboot2_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 multiboot2_tag_module) + argslen);
- if (err)
- return grub_errno;
-
- module = (struct multiboot2_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';
-
- 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 multiboot2_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 8 bytes and aligned on a 8-byte boundary. */
- for (p = buffer; p <= buffer + len - 8; p += 8)
- {
- header = (struct multiboot2_header *) p;
- if (header->magic == MULTIBOOT2_HEADER_MAGIC)
- {
- header_found = 1;
- break;
- }
- }
-
- if (! header_found)
- grub_dprintf ("loader", "No multiboot 2 header found.\n");
-
-
- /* Create the basic tags. */
- grub_dprintf ("loader", "Creating multiboot 2 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 2 file.\n");
- err = grub_mb2_load_elf (elf, argc-1, &argv[1]);
- grub_elf_close (elf);
- }
- else
- {
- grub_errno = 0;
- grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n");
-
- if (header)
- err = grub_mb2_load_other (file, header);
- else
- err = grub_error (GRUB_ERR_BAD_OS,
- "need multiboot 2 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, (void *) 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 ();
-}
-/* multiboot_loader.c - boot multiboot 1 or 2 OS image */
+/* multiboot_loader.c - boot multiboot kernel image */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
#include <grub/multiboot.h>
-#include <grub/multiboot2.h>
-#include <multiboot2.h>
#include <grub/elf.h>
#include <grub/file.h>
#include <grub/err.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 - Multiboot version 1
- * 2 - Multiboot version 2
- */
-
-static unsigned int module_version_status = 1;
-
static int
find_multi_boot1_header (grub_file_t file)
{
return found_status;
}
-static int
-find_multi_boot2_header (grub_file_t file)
-{
- struct 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 8 bytes and aligned on a 8-byte boundary. */
- for (header = (struct multiboot_header *) buffer;
- ((char *) header <= buffer + len - 8) || (header = 0);
- header = (struct multiboot_header *) ((char *) header + 8))
- {
- if (header->magic == MULTIBOOT2_HEADER_MAGIC)
- {
- found_status = 1;
- break;
- }
- }
-
- return found_status;
-}
-
static grub_err_t
grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
/* find which header is in the file */
if (find_multi_boot1_header (file))
header_multi_ver_found = 1;
- else if (find_multi_boot2_header (file))
- header_multi_ver_found = 2;
else
{
grub_error (GRUB_ERR_BAD_OS, "multiboot header not found");
/* Launch multi boot with header */
- /* XXX Find a better way to identify this.
- This is for i386-pc */
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
- defined(GRUB_MACHINE_QEMU)
- if (header_multi_ver_found == 1)
- {
- grub_dprintf ("multiboot_loader",
- "Launching multiboot 1 grub_multiboot() function\n");
- grub_multiboot (argc, argv);
- module_version_status = 1;
- }
-#endif
- if (header_multi_ver_found == 0 || header_multi_ver_found == 2)
- {
- grub_dprintf ("multiboot_loader",
- "Launching multiboot 2 grub_multiboot2() function\n");
- grub_multiboot2 (argc, argv);
- module_version_status = 2;
- }
+ grub_dprintf ("multiboot_loader",
+ "Launching multiboot 1 grub_multiboot() function\n");
+ grub_multiboot (argc, argv);
return grub_errno;
int argc, char *argv[])
{
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
- defined(GRUB_MACHINE_QEMU)
- if (module_version_status == 1)
- {
- grub_dprintf("multiboot_loader",
- "Launching multiboot 1 grub_module() function\n");
- grub_module (argc, argv);
- }
-#endif
- if (module_version_status == 2)
- {
- grub_dprintf("multiboot_loader",
- "Launching multiboot 2 grub_module2() function\n");
- grub_module2 (argc, argv);
- }
+ grub_dprintf("multiboot_loader",
+ "Launching multiboot 1 grub_module() function\n");
+ grub_module (argc, argv);
return grub_errno;
}
GRUB_MOD_INIT(multiboot)
{
cmd_multiboot =
+#ifdef GRUB_USE_MULTIBOOT2
+ grub_register_command ("multiboot2", grub_cmd_multiboot_loader,
+ 0, "Load a multiboot 2 kernel.");
+#else
grub_register_command ("multiboot", grub_cmd_multiboot_loader,
0, "Load a multiboot kernel.");
+#endif
+
cmd_module =
grub_register_command ("module", grub_cmd_module_loader,
0, "Load a multiboot module.");