2009-06-27 Pavel Roskin <proski@gnu.org>

2009-06-27  Robert Millan  <rmh.grub@aybabtu.com>

        * include/grub/dl.h: Include grub/elf.h.
        (struct grub_dl): Add symtab field.
        * kern/dl.c [GRUB_MACHINE_QEMU]: Define
        GRUB_MODULES_MACHINE_READONLY.
        (grub_dl_resolve_symbols): Populate mod->symtab, making a copy
        of the header for read-only modules.
        (grub_dl_unload): Free mod->symtab for read-only modules.
        * kern/i386/dl.c: Use mod->symtab.
        * kern/powerpc/dl.c: Likewise.
        * kern/sparc64/dl.c: Likewise.
        * kern/x86_64/dl.c: Likewise.

        * conf/i386-qemu.rmk: New file.
        * kern/i386/qemu/startup.S: Likewise.
        * kern/i386/qemu/mmap.c: Likewise.
        * boot/i386/qemu/boot.S: Likewise.
        * include/grub/i386/qemu/time.h: Likewise.
        * include/grub/i386/qemu/serial.h: Likewise.
        * include/grub/i386/qemu/kernel.h: Likewise.
        * include/grub/i386/qemu/console.h: Likewise.
        * include/grub/i386/qemu/boot.h: Likewise.
        * include/grub/i386/qemu/init.h: Likewise.
        * include/grub/i386/qemu/machine.h: Likewise.
        * include/grub/i386/qemu/loader.h: Likewise.
        * include/grub/i386/qemu/memory.h: Likewise.

        * conf/i386-coreboot.rmk (GRUB_BOOT_MACHINE_LINK_ADDR)
        (GRUB_KERNEL_MACHINE_LINK_ADDR): New variables.
        [qemu] (pkglib_IMAGES): Add `boot.img'.
        [qemu] (boot_img_SOURCES, boot_img_ASFLAGS, boot_img_LDFLAGS)
        [qemu] (boot_img_FORMAT): New variables.
        [qemu] (bin_UTILITIES): Add `grub-mkimage'.
        [qemu] (grub_mkimage_SOURCES, grub_mkimage_CFLAGS): New variables.
        [qemu] (kernel_img_SOURCES, kernel_img_HEADERS, kernel_img_CFLAGS)
        [qemu] (kernel_img_ASFLAGS, kernel_img_LDFLAGS)
        [qemu] (kernel_img_FORMAT): New variables.

        * configure.ac: Recognise `i386-qemu'.

        * util/i386/pc/grub-mkimage.c (compress_kernel): Add dummy variant
        (for no compression).
        [GRUB_MACHINE_QEMU] (generate_image): Misc adjustments to produce
        a valid i386 ROM image.  Make `GRUB_KERNEL_MACHINE_COMPRESSED_SIZE',
        `GRUB_KERNEL_MACHINE_INSTALL_DOS_PART' and
        `GRUB_KERNEL_MACHINE_INSTALL_BSD_PART' optional features (with
        ifdefs).
This commit is contained in:
robertmh 2009-06-27 11:18:10 +00:00
parent 97fe384ecb
commit 8231fb77c6
24 changed files with 584 additions and 19 deletions

View file

@ -1,3 +1,53 @@
2009-06-27 Pavel Roskin <proski@gnu.org>
2009-06-27 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/dl.h: Include grub/elf.h.
(struct grub_dl): Add symtab field.
* kern/dl.c [GRUB_MACHINE_QEMU]: Define
GRUB_MODULES_MACHINE_READONLY.
(grub_dl_resolve_symbols): Populate mod->symtab, making a copy
of the header for read-only modules.
(grub_dl_unload): Free mod->symtab for read-only modules.
* kern/i386/dl.c: Use mod->symtab.
* kern/powerpc/dl.c: Likewise.
* kern/sparc64/dl.c: Likewise.
* kern/x86_64/dl.c: Likewise.
* conf/i386-qemu.rmk: New file.
* kern/i386/qemu/startup.S: Likewise.
* kern/i386/qemu/mmap.c: Likewise.
* boot/i386/qemu/boot.S: Likewise.
* include/grub/i386/qemu/time.h: Likewise.
* include/grub/i386/qemu/serial.h: Likewise.
* include/grub/i386/qemu/kernel.h: Likewise.
* include/grub/i386/qemu/console.h: Likewise.
* include/grub/i386/qemu/boot.h: Likewise.
* include/grub/i386/qemu/init.h: Likewise.
* include/grub/i386/qemu/machine.h: Likewise.
* include/grub/i386/qemu/loader.h: Likewise.
* include/grub/i386/qemu/memory.h: Likewise.
* conf/i386-coreboot.rmk (GRUB_BOOT_MACHINE_LINK_ADDR)
(GRUB_KERNEL_MACHINE_LINK_ADDR): New variables.
[qemu] (pkglib_IMAGES): Add `boot.img'.
[qemu] (boot_img_SOURCES, boot_img_ASFLAGS, boot_img_LDFLAGS)
[qemu] (boot_img_FORMAT): New variables.
[qemu] (bin_UTILITIES): Add `grub-mkimage'.
[qemu] (grub_mkimage_SOURCES, grub_mkimage_CFLAGS): New variables.
[qemu] (kernel_img_SOURCES, kernel_img_HEADERS, kernel_img_CFLAGS)
[qemu] (kernel_img_ASFLAGS, kernel_img_LDFLAGS)
[qemu] (kernel_img_FORMAT): New variables.
* configure.ac: Recognise `i386-qemu'.
* util/i386/pc/grub-mkimage.c (compress_kernel): Add dummy variant
(for no compression).
[GRUB_MACHINE_QEMU] (generate_image): Misc adjustments to produce
a valid i386 ROM image. Make `GRUB_KERNEL_MACHINE_COMPRESSED_SIZE',
`GRUB_KERNEL_MACHINE_INSTALL_DOS_PART' and
`GRUB_KERNEL_MACHINE_INSTALL_BSD_PART' optional features (with
ifdefs).
2009-06-27 Pavel Roskin <proski@gnu.org> 2009-06-27 Pavel Roskin <proski@gnu.org>
* efiemu/prepare.c: Eliminate TYPE macro, it makes code hard to * efiemu/prepare.c: Eliminate TYPE macro, it makes code hard to

67
boot/i386/qemu/boot.S Normal file
View file

@ -0,0 +1,67 @@
/*
* 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 <config.h>
#include <grub/symbol.h>
#include <grub/machine/memory.h>
#include <grub/machine/boot.h>
#include <grub/machine/kernel.h>
.text
.code16
.globl _start
_start:
/* Disable interrupts. */
cli
jmp 1f
. = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR
VARIABLE(grub_core_entry_addr)
.long 0
1:
/* Process VGA rom. */
call $0xc000, $0x3
/* Set up %ds, %ss, and %es. */
xorw %ax, %ax
movw %ax, %ds
movw %ax, %ss
movw %ax, %es
/* Set up the real mode stack. */
movl $GRUB_MEMORY_MACHINE_REAL_STACK, %esp
/* Transition to protected mode. We use pushl to force generation
of a flat return address. */
pushl $1f
DATA32 jmp real_to_prot
.code32
1:
movl grub_core_entry_addr, %edx
jmp *%edx
#include "../../../kern/i386/realmode.S"
/* Intel, in its infinite wisdom, decided to put the i8086 entry point
*right here* and this is why we need this kludge. */
. = GRUB_BOOT_MACHINE_SIZE - 16
jmp _start
. = GRUB_BOOT_MACHINE_SIZE

View file

@ -8,9 +8,12 @@ COMMON_LDFLAGS = -m32 -nostdlib
script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
# Images. # Images.
pkglib_PROGRAMS = kernel.img
# For kernel.img. GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
ifeq ($(platform), coreboot)
pkglib_PROGRAMS += kernel.img
kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kernel_img_SOURCES = kern/i386/coreboot/startup.S \
kern/i386/misc.S \ kern/i386/misc.S \
kern/i386/coreboot/init.c \ kern/i386/coreboot/init.c \
@ -34,7 +37,52 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
machine/memory.h machine/loader.h list.h handler.h command.h machine/memory.h machine/loader.h list.h handler.h command.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
endif
ifeq ($(platform), qemu)
GRUB_BOOT_MACHINE_LINK_ADDR = 0xffe00
pkglib_IMAGES += boot.img
boot_img_SOURCES = boot/i386/qemu/boot.S
boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
boot_img_FORMAT = binary
bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
pkglib_IMAGES += kernel.img
kernel_img_SOURCES = kern/i386/qemu/startup.S \
kern/i386/misc.S \
kern/i386/coreboot/init.c \
kern/i386/qemu/mmap.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c \
kern/env.c \
term/i386/pc/vga_text.c term/i386/vga_common.c \
symlist.c
kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h list.h handler.h command.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)
kernel_img_FORMAT = binary
endif
MOSTLYCLEANFILES += symlist.c kernel_syms.lst MOSTLYCLEANFILES += symlist.c kernel_syms.lst
DEFSYMFILES += kernel_syms.lst DEFSYMFILES += kernel_syms.lst

2
conf/i386-qemu.rmk Normal file
View file

@ -0,0 +1,2 @@
# -*- makefile -*-
include $(srcdir)/conf/i386-coreboot.mk

View file

@ -85,6 +85,7 @@ case "$target_cpu"-"$platform" in
i386-coreboot) ;; i386-coreboot) ;;
i386-linuxbios) platform=coreboot ;; i386-linuxbios) platform=coreboot ;;
i386-ieee1275) ;; i386-ieee1275) ;;
i386-qemu) ;;
powerpc-ieee1275) ;; powerpc-ieee1275) ;;
sparc64-ieee1275) ;; sparc64-ieee1275) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;

View file

@ -1,7 +1,7 @@
/* dl.h - types and prototypes for loadable module support */ /* dl.h - types and prototypes for loadable module support */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007,2008 Free Software Foundation, Inc. * Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/elf.h>
#define GRUB_MOD_INIT(name) \ #define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
@ -78,6 +79,7 @@ struct grub_dl
int ref_count; int ref_count;
grub_dl_dep_t dep; grub_dl_dep_t dep;
grub_dl_segment_t segment; grub_dl_segment_t segment;
Elf_Sym *symtab;
void (*init) (struct grub_dl *mod); void (*init) (struct grub_dl *mod);
void (*fini) (void); void (*fini) (void);
}; };

View file

@ -0,0 +1,28 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_BOOT_MACHINE_HEADER
#define GRUB_BOOT_MACHINE_HEADER 1
/* The size of boot.img. */
#define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR)
/* The offset of GRUB_CORE_ENTRY_ADDR. */
#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4
#endif

View file

@ -0,0 +1 @@
#include <grub/i386/coreboot/console.h>

View file

@ -0,0 +1 @@
#include <grub/i386/coreboot/init.h>

View file

@ -0,0 +1,53 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_KERNEL_MACHINE_HEADER
#define GRUB_KERNEL_MACHINE_HEADER 1
/* The offset of GRUB_CORE_ENTRY_ADDR. */
#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8
/* The offset of GRUB_KERNEL_IMAGE_SIZE. */
#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc
/* The offset of GRUB_PREFIX. */
#define GRUB_KERNEL_MACHINE_PREFIX 0x10
/* End of the data section. */
#define GRUB_KERNEL_MACHINE_DATA_END 0x50
#ifndef ASM_FILE
#include <grub/symbol.h>
#include <grub/types.h>
extern grub_addr_t grub_core_entry_addr;
/* The size of kernel image. */
extern grub_int32_t grub_kernel_image_size;
/* The total size of module images following the kernel. */
extern grub_int32_t grub_total_module_size;
/* The prefix which points to the directory where GRUB modules and its
configuration file are located. */
extern char grub_prefix[];
#endif /* ! ASM_FILE */
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */

View file

@ -0,0 +1 @@
#include <grub/cpu/loader.h>

View file

@ -0,0 +1,24 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_MACHINE_MACHINE_HEADER
#define GRUB_MACHINE_MACHINE_HEADER 1
#define GRUB_MACHINE_QEMU 1
#endif /* ! GRUB_MACHINE_MACHINE_HEADER */

View file

@ -0,0 +1,45 @@
/* memory.h - describe the memory map */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,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_MEMORY_MACHINE_HEADER
#define _GRUB_MEMORY_MACHINE_HEADER 1
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#ifndef ASM_FILE
#include <grub/err.h>
#include <grub/types.h>
#endif
#define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */
#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */
#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START
#ifndef ASM_FILE
void grub_machine_mmap_init (void);
grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
#endif
#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */

View file

@ -0,0 +1 @@
#include <grub/i386/coreboot/serial.h>

View file

@ -0,0 +1 @@
#include <grub/i386/coreboot/time.h>

View file

@ -1,7 +1,7 @@
/* dl.c - loadable module support */ /* dl.c - loadable module support */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. * Copyright (C) 2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,6 +28,12 @@
#include <grub/file.h> #include <grub/file.h>
#include <grub/env.h> #include <grub/env.h>
#include <grub/cache.h> #include <grub/cache.h>
#include <grub/machine/machine.h>
/* Platforms where modules are in a readonly area of memory. */
#if defined(GRUB_MACHINE_QEMU)
#define GRUB_MODULES_MACHINE_READONLY
#endif
@ -309,7 +315,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
if (i == e->e_shnum) if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table"); return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
sym = (Elf_Sym *) ((char *) e + s->sh_offset); #ifdef GRUB_MODULES_MACHINE_READONLY
mod->symtab = grub_malloc (s->sh_size);
memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
#else
mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
#endif
sym = mod->symtab;
size = s->sh_size; size = s->sh_size;
entsize = s->sh_entsize; entsize = s->sh_entsize;
@ -671,6 +683,9 @@ grub_dl_unload (grub_dl_t mod)
} }
grub_free (mod->name); grub_free (mod->name);
#ifdef GRUB_MODULES_MACHINE_READONLY
grub_free (mod->symtab);
#endif
grub_free (mod); grub_free (mod);
return 1; return 1;
} }

View file

@ -1,6 +1,6 @@
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/machine/console.h> #include <grub/machine/console.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>
#include <grub/machine/machine.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/dl.h> #include <grub/dl.h>
@ -144,5 +145,9 @@ grub_machine_fini (void)
grub_addr_t grub_addr_t
grub_arch_modules_addr (void) grub_arch_modules_addr (void)
{ {
#ifdef GRUB_MACHINE_QEMU
return grub_core_entry_addr + grub_kernel_image_size;
#else
return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
#endif
} }

View file

@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{ {
Elf32_Ehdr *e = ehdr; Elf32_Ehdr *e = ehdr;
Elf32_Shdr *s; Elf32_Shdr *s;
Elf32_Sym *symtab;
Elf32_Word entsize; Elf32_Word entsize;
unsigned i; unsigned i;
@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (i == e->e_shnum) if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize; entsize = s->sh_entsize;
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
@ -89,7 +87,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
"reloc offset is out of the segment"); "reloc offset is out of the segment");
addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf32_Sym *) ((char *) symtab sym = (Elf32_Sym *) ((char *) mod->symtab
+ entsize * ELF32_R_SYM (rel->r_info)); + entsize * ELF32_R_SYM (rel->r_info));
switch (ELF32_R_TYPE (rel->r_info)) switch (ELF32_R_TYPE (rel->r_info))

74
kern/i386/qemu/mmap.c Normal file
View file

@ -0,0 +1,74 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/machine/init.h>
#include <grub/machine/memory.h>
#include <grub/machine/boot.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/i386/cmos.h>
#define QEMU_CMOS_MEMSIZE_HIGH 0x35
#define QEMU_CMOS_MEMSIZE_LOW 0x34
#define min(a,b) ((a) > (b) ? (b) : (a))
extern char _start[];
extern char _end[];
grub_size_t grub_lower_mem, grub_upper_mem;
grub_uint64_t mem_size;
void
grub_machine_mmap_init ()
{
mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16;
/* Don't ask... */
mem_size += (16 * 1024 * 1024);
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
{
if (hook (0x0,
_start,
GRUB_MACHINE_MEMORY_AVAILABLE))
return 1;
if (hook (GRUB_MEMORY_MACHINE_UPPER,
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
GRUB_MACHINE_MEMORY_RESERVED))
return 1;
/* Protect boot.img, which contains the gdt. It is mapped at the top of memory
(it is also mapped below 0x100000, but we already reserved that area). */
if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
GRUB_BOOT_MACHINE_SIZE,
GRUB_MACHINE_MEMORY_RESERVED))
return 1;
/* Everything else is free. */
if (hook (0x100000,
min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
GRUB_MACHINE_MEMORY_AVAILABLE))
return 1;
return 0;
}

97
kern/i386/qemu/startup.S Normal file
View file

@ -0,0 +1,97 @@
/*
* 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 <config.h>
#include <grub/symbol.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>
.text
.code32
.globl _start
_start:
jmp codestart
. = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR
VARIABLE(grub_core_entry_addr)
.long 0
VARIABLE(grub_kernel_image_size)
.long 0
VARIABLE(grub_prefix)
/* to be filled by grub-mkimage */
/*
* Leave some breathing room for the prefix.
*/
. = _start + GRUB_KERNEL_MACHINE_DATA_END
codestart:
/* Relocate to low memory. First we figure out our location.
We will derive the rom start address from it. */
call 1f
1: popl %esi
/* Rom size is a multiple of 64 kiB. With this we get the
value of `grub_core_entry_addr' in %esi. */
xorw %si, %si
/* ... which allows us to access `grub_kernel_image_size'
before relocation. */
movl (grub_kernel_image_size - _start)(%esi), %ecx
movl $_start, %edi
cld
rep
movsb
ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
1:
#ifdef APPLE_CC
/* clean out the bss */
bss_start_abs = ABS (bss_start)
bss_end_abs = ABS (bss_end)
movl bss_start_abs, %edi
/* compute the bss length */
movl bss_end_abs, %ecx
subl %edi, %ecx
#else
/* clean out the bss */
movl $BSS_START_SYMBOL, %edi
/* compute the bss length */
movl $END_SYMBOL, %ecx
subl %edi, %ecx
#endif
/* clean out */
xorl %eax, %eax
cld
rep
stosb
/*
* Call the start of main body of C code.
*/
call EXT_C(grub_main)
/* This should never happen. */
jmp EXT_C(grub_stop)

View file

@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{ {
Elf32_Ehdr *e = ehdr; Elf32_Ehdr *e = ehdr;
Elf32_Shdr *s; Elf32_Shdr *s;
Elf32_Sym *symtab;
Elf32_Word entsize; Elf32_Word entsize;
unsigned i; unsigned i;
@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (i == e->e_shnum) if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize; entsize = s->sh_entsize;
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
@ -91,7 +89,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
"reloc offset is out of the segment"); "reloc offset is out of the segment");
addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf32_Sym *) ((char *) symtab sym = (Elf32_Sym *) ((char *) mod->symtab
+ entsize * ELF32_R_SYM (rel->r_info)); + entsize * ELF32_R_SYM (rel->r_info));
/* On the PPC the value does not have an explicit /* On the PPC the value does not have an explicit

View file

@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{ {
Elf64_Ehdr *e = ehdr; Elf64_Ehdr *e = ehdr;
Elf64_Shdr *s; Elf64_Shdr *s;
Elf64_Sym *symtab;
Elf64_Word entsize; Elf64_Word entsize;
unsigned i; unsigned i;
@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (i == e->e_shnum) if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize; entsize = s->sh_entsize;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
@ -91,7 +89,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
"reloc offset is out of the segment"); "reloc offset is out of the segment");
addr = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); addr = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf64_Sym *) ((char *) symtab sym = (Elf64_Sym *) ((char *) mod->symtab
+ entsize * ELF64_R_SYM (rel->r_info)); + entsize * ELF64_R_SYM (rel->r_info));
value = sym->st_value + rel->r_addend; value = sym->st_value + rel->r_addend;

View file

@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{ {
Elf64_Ehdr *e = ehdr; Elf64_Ehdr *e = ehdr;
Elf64_Shdr *s; Elf64_Shdr *s;
Elf64_Sym *symtab;
Elf64_Word entsize; Elf64_Word entsize;
unsigned i; unsigned i;
@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (i == e->e_shnum) if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize; entsize = s->sh_entsize;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
@ -91,7 +89,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
addr64 = (Elf64_Xword *) addr32; addr64 = (Elf64_Xword *) addr32;
sym = (Elf64_Sym *) ((char *) symtab sym = (Elf64_Sym *) ((char *) mod->symtab
+ entsize * ELF64_R_SYM (rel->r_info)); + entsize * ELF64_R_SYM (rel->r_info));
switch (ELF64_R_TYPE (rel->r_info)) switch (ELF64_R_TYPE (rel->r_info))

View file

@ -124,6 +124,17 @@ compress_kernel (char *kernel_img, size_t kernel_size,
*core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE;
} }
#else
static void
compress_kernel (char *kernel_img, size_t kernel_size,
char **core_img, size_t *core_size)
{
*core_img = xmalloc (kernel_size);
memcpy (*core_img, kernel_img, kernel_size);
*core_size = kernel_size;
}
#endif #endif
static void static void
@ -237,6 +248,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
if (num > 0xffff) if (num > 0xffff)
grub_util_error ("the core image is too big"); grub_util_error ("the core image is too big");
#if defined(GRUB_MACHINE_PCBIOS)
boot_path = grub_util_get_path (dir, "diskboot.img"); boot_path = grub_util_get_path (dir, "diskboot.img");
boot_size = grub_util_get_image_size (boot_path); boot_size = grub_util_get_image_size (boot_path);
if (boot_size != GRUB_DISK_SECTOR_SIZE) if (boot_size != GRUB_DISK_SECTOR_SIZE)
@ -253,13 +266,54 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
free (boot_img); free (boot_img);
free (boot_path); free (boot_path);
#elif defined(GRUB_MACHINE_QEMU)
{
char *rom_img;
size_t rom_size;
boot_path = grub_util_get_path (dir, "boot.img");
boot_size = grub_util_get_image_size (boot_path);
boot_img = grub_util_read_image (boot_path);
/* Rom sizes must be 64k-aligned. */
rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
rom_img = xmalloc (rom_size);
memset (rom_img, 0, rom_size);
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR))
= grub_cpu_to_le32 ((grub_uint32_t) -rom_size);
memcpy (rom_img, core_img, core_size);
*((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR))
= grub_cpu_to_le32 ((grub_uint32_t) -rom_size);
memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
free (core_img);
core_img = rom_img;
core_size = rom_size;
free (boot_img);
free (boot_path);
}
#endif
#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
= grub_cpu_to_le32 (total_module_size); = grub_cpu_to_le32 (total_module_size);
#endif
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
= grub_cpu_to_le32 (kernel_size); = grub_cpu_to_le32 (kernel_size);
#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
= grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); = grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
#endif
#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
/* If we included a drive in our prefix, let GRUB know it doesn't have to /* If we included a drive in our prefix, let GRUB know it doesn't have to
prepend the drive told by BIOS. */ prepend the drive told by BIOS. */
if (prefix[0] == '(') if (prefix[0] == '(')
@ -269,10 +323,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
= grub_cpu_to_le32 (-2); = grub_cpu_to_le32 (-2);
} }
#endif
#ifdef GRUB_MACHINE_PCBIOS
if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
grub_util_error ("Core image is too big (%p > %p)\n", grub_util_error ("Core image is too big (%p > %p)\n",
GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER); GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER);
#endif
grub_util_write_image (core_img, core_size, out); grub_util_write_image (core_img, core_size, out);
free (kernel_img); free (kernel_img);