Hi, I ported GRUB to QEMU. It's mostly based on the coreboot port, with the main difference being that we include code to transition from i8086 mode, an i386 firmware entry point and produce raw code images instead of ELF.
The result is you can do e.g. $ sudo grub-mkrawimage at_keyboard normal etc -o /usr/share/qemu/grub and then: $ qemu -bios grub -hda /dev/zero grub-mkrawimage will automatically generate an image of arbitrary size, depending on the number of modules that were included (or the size of the memdisk). The only restriction imposed by qemu is that it must be 64k-aligned (zero-padding is used to archieve that). This patch is incomplete, still includes a few hacks and needs general cleanup. I'll send a few cleanup patches separately so we can integrate this avoiding code duplication and ugly kludges. -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all."
Index: conf/i386-qemu.rmk =================================================================== --- conf/i386-qemu.rmk (revision 0) +++ conf/i386-qemu.rmk (revision 0) @@ -0,0 +1,2 @@ +# -*- makefile -*- +include $(srcdir)/conf/i386-coreboot.mk Index: conf/i386-coreboot.rmk =================================================================== --- conf/i386-coreboot.rmk (revision 2353) +++ conf/i386-coreboot.rmk (working copy) @@ -8,10 +8,11 @@ script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. -pkglib_PROGRAMS = kernel.elf -# For kernel.elf. -kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ +ifeq ($(platform), coreboot) + +pkglib_PROGRAMS += kernel.img +kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/coreboot/init.c \ kern/i386/multiboot_mmap.c \ kern/main.c kern/device.c \ @@ -26,22 +27,66 @@ kern/env.c \ term/i386/pc/vga_text.c term/i386/vga_common.c \ symlist.c -kernel_elf_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ +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_elf_CFLAGS = $(COMMON_CFLAGS) -kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) -kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic +endif + +ifeq ($(platform), qemu) + +GRUB_MEMORY_MACHINE_LINK_ADDR = 0x8200 + +pkglib_IMAGES += boot.img +boot_img_SOURCES = boot/i386/qemu/boot.S +boot_img_ASFLAGS = $(COMMON_ASFLAGS) +boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x0 +boot_img_FORMAT = binary + +bin_UTILITIES += grub-mkrawimage +grub_mkrawimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ + util/resolve.c +grub_mkrawimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR) + +pkglib_IMAGES += kernel.img +kernel_img_SOURCES = kern/i386/qemu/startup.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) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_MEMORY_MACHINE_LINK_ADDR) +kernel_img_FORMAT = binary +endif + MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) # Utilities. Index: kern/i386/qemu/startup.S =================================================================== --- kern/i386/qemu/startup.S (revision 0) +++ kern/i386/qemu/startup.S (revision 0) @@ -0,0 +1,113 @@ +/* + * 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 + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = _start + 0x8 + +VARIABLE(grub_total_module_size) + .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 + (which depends on the rom size). */ + call 1f +1: popl %esi + + /* We know rom size is a multiple of 64 kiB. */ + xorw %si, %si + + /* And it spans untill top of memory. */ + movl %esi, %ecx + negl %ecx + + movl $GRUB_MEMORY_MACHINE_LINK_ADDR, %edi + cld + rep + movsb + ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f +1: + + /* copy modules before cleaning out the bss */ + movl EXT_C(grub_total_module_size), %ecx + movl EXT_C(grub_kernel_image_size), %esi + addl %ecx, %esi + addl $_start, %esi + decl %esi + movl $END_SYMBOL, %edi + addl %ecx, %edi + decl %edi + std + rep + movsb + +#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) Index: kern/i386/qemu/mmap.c =================================================================== --- kern/i386/qemu/mmap.c (revision 0) +++ kern/i386/qemu/mmap.c (revision 0) @@ -0,0 +1,62 @@ +/* + * 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/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)) + +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) << 8 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW); + mem_size *= 65536; + + /* 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)) +{ + /* This trashes the video bios, but for now we don't use it. */ + if (hook (0, 0xffe00, GRUB_MACHINE_MEMORY_AVAILABLE)) + return 1; + + /* Protect the gdt. */ + if (hook (0xffe00, 0x200, GRUB_MACHINE_MEMORY_RESERVED)) + return 1; + if (hook ((grub_uint32_t) -0x200, 0x200, GRUB_MACHINE_MEMORY_RESERVED)) + return 1; + + if (hook (0x100000, min (mem_size, (grub_uint32_t) -0x200) - 0x100000, GRUB_MACHINE_MEMORY_AVAILABLE)) + return 1; + + return 0; +} Index: kern/i386/realmode.S =================================================================== --- kern/i386/realmode.S (revision 2353) +++ kern/i386/realmode.S (working copy) @@ -107,7 +107,7 @@ /* this is the GDT descriptor */ gdtdesc: .word 0x27 /* limit */ - .long gdt /* addr */ + .long (0xffe00 + gdt) /* addr */ /* * These next routine, "prot_to_real" is structured in a very Index: kern/i386/coreboot/startup.S =================================================================== --- kern/i386/coreboot/startup.S (revision 2353) +++ kern/i386/coreboot/startup.S (working copy) @@ -78,14 +78,6 @@ jmp EXT_C(grub_main) /* - * This call is special... it never returns... in fact it should simply - * hang at this point! - */ -FUNCTION(grub_stop) - hlt - jmp EXT_C(grub_stop) - -/* * prot_to_real and associated structures (but NOT real_to_prot, that is * only needed for BIOS gates). */ Index: kern/i386/coreboot/init.c =================================================================== --- kern/i386/coreboot/init.c (revision 2353) +++ kern/i386/coreboot/init.c (working copy) @@ -50,6 +50,17 @@ grub_fatal ("grub_get_rtc() is not implemented.\n"); } +/* + * This call is special... it never returns... in fact it should simply + * hang at this point! + */ +void +grub_stop () +{ + while (1) + __asm__ ("hlt"); +} + /* Stop the floppy drive from spinning, so that other software is jumped to with a known state. */ void @@ -144,5 +155,6 @@ grub_addr_t grub_arch_modules_addr (void) { - return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); +// return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); + return _end; } Index: boot/i386/qemu/boot.S =================================================================== --- boot/i386/qemu/boot.S (revision 0) +++ boot/i386/qemu/boot.S (revision 0) @@ -0,0 +1,116 @@ +/* + * 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> + +#define SIZE 512 + + .text + .code16 + .globl _start +_start: + /* Disable interrupts. */ + cli + + jmp 1f + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = _start + 0x8 +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 $(0xffe00 + 1f) + DATA32 jmp real_to_prot + .code32 +1: + movl (0xffe00 + grub_core_entry_addr), %edx + jmp *%edx + +#include "kern/i386/realmode.S" + +real_to_prot: + .code16 + cli + + /* load the GDT register */ + DATA32 ADDR32 lgdt %cs:(0xfe00 + gdtdesc) + + /* turn on protected mode */ + movl %cr0, %eax + orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + movl %eax, %cr0 + + data32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $(0xffe00 + protcseg) + + .code32 + .align 4 +protcseg: + cli + + /* reload other segment registers */ + movw $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* put the return address in a known safe location */ + movl (%esp), %eax + movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK + + /* get protected mode stack */ + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %eax + movl %eax, %esp + movl %eax, %ebp + + /* get return address onto the right stack */ + movl GRUB_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, (%esp) + + /* zero %eax */ + xorl %eax, %eax + + /* return on the old (or initialized) stack! */ + ret + + . = SIZE - 16 +entry: + jmp _start + . = SIZE Index: configure.ac =================================================================== --- configure.ac (revision 2353) +++ configure.ac (working copy) @@ -85,6 +85,7 @@ i386-coreboot) ;; i386-linuxbios) platform=coreboot ;; i386-ieee1275) ;; + i386-qemu) ;; powerpc-ieee1275) ;; sparc64-ieee1275) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; @@ -414,7 +415,7 @@ # Check symbols provided by linker script. CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" fi - if test "x$platform" = xpc && test "x$TARGET_APPLE_CC" != x1 ; then + if test "x$TARGET_APPLE_CC" != x1 ; then grub_CHECK_BSS_START_SYMBOL grub_CHECK_END_SYMBOL fi Index: include/grub/i386/qemu/time.h =================================================================== --- include/grub/i386/qemu/time.h (revision 0) +++ include/grub/i386/qemu/time.h (revision 0) @@ -0,0 +1 @@ +#include <grub/i386/coreboot/time.h> Index: include/grub/i386/qemu/serial.h =================================================================== --- include/grub/i386/qemu/serial.h (revision 0) +++ include/grub/i386/qemu/serial.h (revision 0) @@ -0,0 +1 @@ +#include <grub/i386/coreboot/serial.h> Index: include/grub/i386/qemu/kernel.h =================================================================== --- include/grub/i386/qemu/kernel.h (revision 0) +++ include/grub/i386/qemu/kernel.h (revision 0) @@ -0,0 +1,51 @@ +/* + * 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_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 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> + +/* 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 */ Index: include/grub/i386/qemu/console.h =================================================================== --- include/grub/i386/qemu/console.h (revision 0) +++ include/grub/i386/qemu/console.h (revision 0) @@ -0,0 +1 @@ +#include <grub/i386/coreboot/console.h> Index: include/grub/i386/qemu/boot.h =================================================================== --- include/grub/i386/qemu/boot.h (revision 0) +++ include/grub/i386/qemu/boot.h (revision 0) @@ -0,0 +1 @@ +#include <grub/i386/coreboot/boot.h> Index: include/grub/i386/qemu/init.h =================================================================== --- include/grub/i386/qemu/init.h (revision 0) +++ include/grub/i386/qemu/init.h (revision 0) @@ -0,0 +1 @@ +#include <grub/i386/coreboot/init.h> Index: include/grub/i386/qemu/machine.h =================================================================== --- include/grub/i386/qemu/machine.h (revision 0) +++ include/grub/i386/qemu/machine.h (revision 0) @@ -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 */ Index: include/grub/i386/qemu/loader.h =================================================================== --- include/grub/i386/qemu/loader.h (revision 0) +++ include/grub/i386/qemu/loader.h (revision 0) @@ -0,0 +1 @@ +#include <grub/cpu/loader.h> Index: include/grub/i386/qemu/memory.h =================================================================== --- include/grub/i386/qemu/memory.h (revision 0) +++ include/grub/i386/qemu/memory.h (revision 0) @@ -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 */ Index: include/grub/i386/coreboot/kernel.h =================================================================== --- include/grub/i386/coreboot/kernel.h (revision 2353) +++ include/grub/i386/coreboot/kernel.h (working copy) @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * 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 @@ -19,10 +19,33 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 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> -#ifndef ASM_FILE +/* 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 +#endif /* ! ASM_FILE */ + #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ Index: util/i386/pc/grub-mkimage.c =================================================================== --- util/i386/pc/grub-mkimage.c (revision 2353) +++ util/i386/pc/grub-mkimage.c (working copy) @@ -124,6 +124,17 @@ *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 static void @@ -169,9 +180,11 @@ kernel_img = xmalloc (kernel_size + total_module_size); grub_util_load_image (kernel_path, kernel_img); +#ifdef GRUB_KERNEL_MACHINE_PREFIX if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); +#endif /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); @@ -237,6 +250,7 @@ if (num > 0xffff) grub_util_error ("the core image is too big"); +#if 0 boot_path = grub_util_get_path (dir, "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); if (boot_size != GRUB_DISK_SECTOR_SIZE) @@ -252,14 +266,18 @@ grub_util_write_image (boot_img, boot_size, out); free (boot_img); free (boot_path); +#endif *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) = grub_cpu_to_le32 (total_module_size); *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) = grub_cpu_to_le32 (kernel_size); +#ifdef 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); +#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 prepend the drive told by BIOS. */ if (prefix[0] == '(') @@ -269,10 +287,41 @@ *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) = grub_cpu_to_le32 (-2); } +#endif +#if 1 + { + 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); + + memcpy (rom_img, core_img, core_size); + + *((grub_int32_t *) (boot_img + 0x8)) + = 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); + } +#else if (GRUB_MEMORY_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) grub_util_error ("Core image is too big (%p > %p)\n", GRUB_MEMORY_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER); +#endif grub_util_write_image (core_img, core_size, out); free (kernel_img);
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel