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 powerpc 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. So if your OS is multiboot 2 capable, the user would do the following to load it up from a grub prompt: grub> multiboot <location of kernel> <kernel args> grub> module <some image> <multiboot tag> <image arguments> grub> module <isome mage> <multiboot tag> <image arguments> grub ..... 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. But mulitboot 2 may still need a little more testing and work for i386-pc. Powerpc multiboot 2 has been heavily tested and does work.
This commit is contained in:
parent
daf0f0ba3e
commit
e5dfe7775a
17 changed files with 1315 additions and 300 deletions
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
2007-07-24 Jerone Young <jerone@gmail.com>
|
||||
|
||||
* conf/i386-pc.rmk: Add Multiboot loader and multiboot 2 to multiboot
|
||||
modules for compilation.
|
||||
* conf/powerpc-ieee1275.rmk: Likewise.
|
||||
|
||||
* include/multiboot.h: Move multiboot definitions to one file. Rename
|
||||
many definitions to not get grub specific.
|
||||
* include/multiboot2.h: Create header with multiboot 2 definitions.
|
||||
* include/grub/multiboot.h: Header for grub specific function
|
||||
prototypes and definitions.
|
||||
* include/grub/multiboot2.h: Likewise.
|
||||
* include/grub/multiboot_loader.h: Likewise.
|
||||
* include/grub/i386/pc/multiboot.h: Removed.
|
||||
* include/grub/powerpc/ieee1275/multiboot.h: Removed.
|
||||
|
||||
* loader/multiboot_loader.c: Created to act as a proxy for multiboot 1
|
||||
and 2 to allow for one multiboot and module commands.
|
||||
* loader/multiboot2.c: Add multiboot2 functionality.
|
||||
* loader/i386/pc/multiboot.c: Modify for new multiboot header location
|
||||
and definition names.
|
||||
* loader/i386/pc/multiboot2.c: Created to add i386 specific multiboot
|
||||
2 functions.
|
||||
* loader/powerpc/ieee1275/multiboot2.c: Created to add powerpc
|
||||
ieee1275 specific multiboot2 code.
|
||||
|
||||
* kern/i386/pc/startup.S: Change headers and definition names for
|
||||
multiboot. Add function grub_multiboot2_real_boot for multiboot 2.
|
||||
|
||||
2007-07-22 Robert Millan <rmh@aybabtu.com>
|
||||
|
||||
* geninitheader.sh: Process file specified in first parameter rather
|
||||
|
|
|
@ -177,12 +177,15 @@ serial_mod_CFLAGS = $(COMMON_CFLAGS)
|
|||
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)
|
||||
|
||||
|
|
|
@ -103,7 +103,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
|
||||
|
@ -141,5 +143,18 @@ halt_mod_SOURCES = commands/ieee1275/halt.c
|
|||
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
|
||||
|
||||
|
|
|
@ -21,11 +21,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));
|
||||
|
@ -37,12 +39,13 @@ void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attr
|
|||
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 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* multiboot.h - multiboot header file. */
|
||||
/* multiboot.h - multiboot header file with grub definitions. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2007 Free Software Foundation, Inc.
|
||||
|
@ -17,77 +17,13 @@
|
|||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_MULTIBOOT_MACHINE_HEADER
|
||||
#define GRUB_MULTIBOOT_MACHINE_HEADER 1
|
||||
#ifndef GRUB_MULTIBOOT_HEADER
|
||||
#define GRUB_MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define GRUB_MB_SEARCH 8192
|
||||
#include <multiboot.h>
|
||||
|
||||
/* 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
|
||||
void grub_multiboot (int argc, char *argv[]);
|
||||
void grub_module (int argc, char *argv[]);
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
|
@ -95,7 +31,7 @@
|
|||
|
||||
struct grub_multiboot_header
|
||||
{
|
||||
/* Must be GRUB_MB_MAGIC - see above. */
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
grub_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
|
@ -104,14 +40,14 @@ struct grub_multiboot_header
|
|||
/* 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. */
|
||||
/* 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 GRUB_MB_VIDEO_MODE is set. */
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
grub_uint32_t mode_type;
|
||||
grub_uint32_t width;
|
||||
grub_uint32_t height;
|
||||
|
@ -180,4 +116,4 @@ struct grub_mod_list
|
|||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! GRUB_MULTIBOOT_MACHINE_HEADER */
|
||||
#endif /* ! GRUB_MULTIBOOT_HEADER */
|
64
include/grub/multiboot2.h
Normal file
64
include/grub/multiboot2.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* multiboot2.h - multiboot2 header file with grub definitions. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007 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/>.
|
||||
*/
|
||||
|
||||
#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 */
|
28
include/grub/multiboot_loader.h
Normal file
28
include/grub/multiboot_loader.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* multiboot_loader.h - multiboot loader header file. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#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 */
|
|
@ -1,183 +0,0 @@
|
|||
/* multiboot.h - multiboot header file. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2004,2007 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/>.
|
||||
*/
|
||||
|
||||
#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 */
|
92
include/multiboot.h
Normal file
92
include/multiboot.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* multiboot.h - multiboot header file. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2007 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/>.
|
||||
*/
|
||||
|
||||
#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 */
|
107
include/multiboot2.h
Normal file
107
include/multiboot2.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* multiboot2.h - multiboot 2 header file. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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/>.
|
||||
*/
|
||||
|
||||
#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 */
|
|
@ -49,7 +49,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)
|
||||
|
||||
|
@ -813,10 +814,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)
|
||||
|
|
|
@ -32,7 +32,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>
|
||||
|
@ -43,7 +43,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;
|
||||
|
||||
|
@ -107,7 +107,7 @@ grub_multiboot_load_elf32 (grub_file_t file, void *buffer)
|
|||
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;
|
||||
|
@ -177,7 +177,7 @@ grub_multiboot_load_elf64 (grub_file_t file, void *buffer)
|
|||
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 */
|
||||
|
@ -236,16 +236,14 @@ grub_multiboot_load_elf (grub_file_t file, void *buffer)
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -261,7 +259,7 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
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");
|
||||
|
@ -274,7 +272,7 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
((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;
|
||||
}
|
||||
|
@ -285,7 +283,7 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
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);
|
||||
|
@ -299,7 +297,7 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
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;
|
||||
|
@ -321,10 +319,10 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
/* 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);
|
||||
|
@ -343,7 +341,7 @@ grub_rescue_cmd_multiboot (int argc, char *argv[])
|
|||
|
||||
|
||||
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;
|
||||
|
@ -368,7 +366,7 @@ grub_rescue_cmd_module (int argc, char *argv[])
|
|||
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;
|
||||
|
||||
|
@ -394,7 +392,7 @@ grub_rescue_cmd_module (int argc, char *argv[])
|
|||
/* 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;
|
||||
|
||||
|
@ -421,7 +419,7 @@ grub_rescue_cmd_module (int argc, char *argv[])
|
|||
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:
|
||||
|
@ -434,19 +432,3 @@ grub_rescue_cmd_module (int argc, char *argv[])
|
|||
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");
|
||||
}
|
||||
|
|
101
loader/i386/pc/multiboot2.c
Normal file
101
loader/i386/pc/multiboot2.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* multiboot2.c - boot a multiboot 2 OS image. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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 <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;
|
||||
}
|
460
loader/multiboot2.c
Normal file
460
loader/multiboot2.c
Normal file
|
@ -0,0 +1,460 @@
|
|||
/* multiboot2.c - boot a multiboot 2 OS image. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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 <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';
|
||||
|
||||
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 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_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, (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 ();
|
||||
}
|
176
loader/multiboot_loader.c
Normal file
176
loader/multiboot_loader.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* multiboot_loader.c - boot multiboot 1 or 2 OS image */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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 <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;
|
||||
}
|
||||
|
||||
void
|
||||
grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
|
||||
{
|
||||
|
||||
grub_file_t file = 0;
|
||||
int header_multi_ver_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_ver_found = 1;
|
||||
else
|
||||
{
|
||||
/* The behavior is that if you don't find a multiboot 1 header
|
||||
use multiboot 2 loader (as you do not have to have a header
|
||||
to use multiboot 2 */
|
||||
grub_dprintf ("multiboot_loader", "No multiboot 1 header found. \n \
|
||||
Using multiboot 2 loader\n");
|
||||
header_multi_ver_found = 0;
|
||||
}
|
||||
|
||||
/* 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_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 mulitboot 2 grub_multiboot2() function\n");
|
||||
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\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_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");
|
||||
}
|
61
loader/multiboot_loader_normal.c
Normal file
61
loader/multiboot_loader_normal.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* multiboot_loader_normal.c - boot another boot loader */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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/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");
|
||||
}
|
119
loader/powerpc/ieee1275/multiboot2.c
Normal file
119
loader/powerpc/ieee1275/multiboot2.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* multiboot.c - boot a multiboot 2 OS image. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007 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 <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);
|
||||
}
|
Loading…
Reference in a new issue