All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i386-qemu port
@ 2009-06-21 18:17 Robert Millan
  2009-06-21 18:50 ` does module area require alignment? (Re: [PATCH] i386-qemu port) Robert Millan
                   ` (8 more replies)
  0 siblings, 9 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-21 18:17 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]


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."

[-- Attachment #2: qemu.diff --]
[-- Type: text/x-diff, Size: 25224 bytes --]

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);

^ permalink raw reply	[flat|nested] 71+ messages in thread

* does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
@ 2009-06-21 18:50 ` Robert Millan
  2009-06-21 19:08   ` Pavel Roskin
  2009-06-21 18:54 ` [PATCH] move grub_stop() " Robert Millan
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 18:50 UTC (permalink / raw)
  To: grub-devel

On Sun, Jun 21, 2009 at 08:17:48PM +0200, Robert Millan wrote:
>  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;
>  }

Some comments on this one.  It seems coreboot cares about alignment in
modbase because all ELF targets do.  This comes from elf/grub-mkimage.c:

      /* Place modules just after grub segment.  */
      modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);

However, I don't see why this is necessary.  The module area is unaligned
on i386-pc and this works just fine there.  Same for i386-qemu.

Does anyone know why do we align ELF targets?  When I did the coreboot port,
the ELF part was based on existing Ieee1275 code, so I guess I just mimicked
it.  Is there some issue with non-i386 CPUs or with some Ieee1275
implementations that makes this alignment a requirement?

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
  2009-06-21 18:50 ` does module area require alignment? (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-21 18:54 ` Robert Millan
  2009-06-21 19:05   ` Pavel Roskin
  2009-06-21 19:00 ` [PATCH] i386-qemu port Pavel Roskin
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 18:54 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 300 bytes --]


Move grub_stop to init.c to ease code sharing with i386-qemu.

-- 
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."

[-- Attachment #2: stop.diff --]
[-- Type: text/x-diff, Size: 1284 bytes --]

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

	* kern/i386/coreboot/startup.S (grub_stop): Move from here ...
	* kern/i386/coreboot/init.c (grub_stop): ... to here.

Index: kern/i386/coreboot/startup.S
===================================================================
--- kern/i386/coreboot/startup.S	(revision 2353)
+++ kern/i386/coreboot/startup.S	(working copy)
@@ -78,14 +78,6 @@ codestart:
 	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_get_rtc (void)
   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)
+    grub_cpu_idle ();
+}
+
 /* Stop the floppy drive from spinning, so that other software is
    jumped to with a known state.  */
 void

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
  2009-06-21 18:50 ` does module area require alignment? (Re: [PATCH] i386-qemu port) Robert Millan
  2009-06-21 18:54 ` [PATCH] move grub_stop() " Robert Millan
@ 2009-06-21 19:00 ` Pavel Roskin
  2009-06-21 19:30   ` Robert Millan
  2009-06-21 20:34   ` Robert Millan
  2009-06-21 19:19 ` [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port) Robert Millan
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-21 19:00 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 20:17 +0200, Robert Millan wrote:
> 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.

That's great news!  Eventually, it would be nice to have support for
many other platforms supported by qemu, such as arm and mips.  This way,
it will be possible to emulate many platforms in qemu without having to
implement the platform specific firmware.

> The result is you can do e.g.
> 
>   $ sudo grub-mkrawimage at_keyboard normal etc -o /usr/share/qemu/grub

Please consider if we can call it grub-mkimage unless grub-mkimage would
make sense as a separate executable for that platform.

> 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.

It should be one of our priorities to make the code easy to maintain and
extend.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-21 18:54 ` [PATCH] move grub_stop() " Robert Millan
@ 2009-06-21 19:05   ` Pavel Roskin
  2009-06-21 19:25     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-21 19:05 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 20:54 +0200, Robert Millan wrote:
> Move grub_stop to init.c to ease code sharing with i386-qemu.

That's not quite a movement.  grub_cpu_idle() does nothing.

I think we need to have several implementations of grub_stop: hard halt
with interrupts disabled, exit from qemu, exit from other emulators if
it's different, power off, exit to BIOS.  Then different platforms
should enable and try whatever is appropriate for them.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-21 18:50 ` does module area require alignment? (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-21 19:08   ` Pavel Roskin
  2009-06-21 19:33     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-21 19:08 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 20:50 +0200, Robert Millan wrote:

> Does anyone know why do we align ELF targets?  When I did the coreboot port,
> the ELF part was based on existing Ieee1275 code, so I guess I just mimicked
> it.  Is there some issue with non-i386 CPUs or with some Ieee1275
> implementations that makes this alignment a requirement?

It was a hack for PowerPC openfirmware.  I don't know why it was needed.
I didn't have time and desire to debug openfirmware to find out what it
wants.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (2 preceding siblings ...)
  2009-06-21 19:00 ` [PATCH] i386-qemu port Pavel Roskin
@ 2009-06-21 19:19 ` Robert Millan
  2009-06-22  2:20   ` Pavel Roskin
  2009-06-21 19:52 ` [PATCH] swap real_to_prot() and prot_to_real() " Robert Millan
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 19:19 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]


If you check my earlier patch, you'll see i386-qemu.rmk is just a stub
that includes i386-coreboot.rmk.  This is to reduce code duplication
(untill we have a more flexible build system).

This patch renames kernel.elf to kernel.img in ELF platforms, so that
more variables / etc can be shared with non-ELF ones.

It has no user-visible effect.

-- 
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."

[-- Attachment #2: elf_to_img.diff --]
[-- Type: text/x-diff, Size: 7133 bytes --]

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

	* conf/i386-ieee1275.rmk (pkglib_PROGRAMS): Replace `kernel.elf'
	with `kernel.img'.
	(kernel_elf_SOURCES): Rename to ...
	(kernel_img_SOURCES): ... this.
	(kernel_elf_HEADERS): Rename to ...
	(kernel_img_HEADERS): ... this.  Update all users.
	(kernel_elf_CFLAGS): Rename to ...
	(kernel_img_CFLAGS): ... this.
	(kernel_elf_LDFLAGS): Rename to ...
	(kernel_img_LDFLAGS): ... this.
	* conf/i386-coreboot.rmk: Likewise.
	* conf/powerpc-ieee1275.rmk: Likewise.

	* util/elf/grub-mkimage.c (add_segments): Replace "kernel.elf"
	with "kernel.img".

Index: conf/i386-ieee1275.rmk
===================================================================
--- conf/i386-ieee1275.rmk	(revision 2353)
+++ conf/i386-ieee1275.rmk	(working copy)
@@ -8,10 +8,10 @@
 script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
-pkglib_PROGRAMS = kernel.elf
+pkglib_PROGRAMS = kernel.img
 
-# For kernel.elf.
-kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
 	kern/ieee1275/init.c \
 	kern/ieee1275/mmap.c \
 	kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
@@ -27,21 +27,21 @@
 	term/ieee1275/ofconsole.c \
 	disk/ieee1275/ofdisk.c \
 	symlist.c
-kernel_elf_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \
+kernel_img_HEADERS = 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 \
 	ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
 	list.h handler.h command.h
-kernel_elf_CFLAGS = $(COMMON_CFLAGS)
-kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
 
 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: conf/i386-coreboot.rmk
===================================================================
--- conf/i386-coreboot.rmk	(revision 2353)
+++ conf/i386-coreboot.rmk	(working copy)
@@ -8,10 +8,10 @@
 script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
-pkglib_PROGRAMS = kernel.elf
+pkglib_PROGRAMS = kernel.img
 
-# For kernel.elf.
-kernel_elf_SOURCES = kern/i386/coreboot/startup.S \
+# For 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 +26,22 @@
 	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
 
 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: conf/powerpc-ieee1275.rmk
===================================================================
--- conf/powerpc-ieee1275.rmk	(revision 2353)
+++ conf/powerpc-ieee1275.rmk	(working copy)
@@ -13,20 +13,20 @@
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
 
-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 misc.h mm.h net.h parser.h reader.h \
 	symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
 	pc_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \
 	command.h
 
-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)
 
 # Programs
-pkglib_PROGRAMS = kernel.elf
+pkglib_PROGRAMS = kernel.img
 
 # Utilities.
 sbin_UTILITIES = grub-mkdevicemap
@@ -82,7 +82,7 @@
 
 grub_emu_LDFLAGS = $(LIBCURSES)
 
-kernel_elf_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
+kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
 	kern/ieee1275/ieee1275.c kern/main.c kern/device.c 		\
 	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c 		\
 	kern/misc.c kern/mm.c kern/reader.c kern/term.c 	\
@@ -95,9 +95,9 @@
 	kern/parser.c kern/partition.c kern/env.c kern/powerpc/dl.c 	\
 	kern/generic/millisleep.c kern/time.c                            \
 	symlist.c kern/powerpc/cache.S
-kernel_elf_CFLAGS = $(COMMON_CFLAGS)
-kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
 	-Wl,-N,-S,-Ttext,0x200000,-Bstatic
 
 # Scripts.
Index: util/elf/grub-mkimage.c
===================================================================
--- util/elf/grub-mkimage.c	(revision 2353)
+++ util/elf/grub-mkimage.c	(working copy)
@@ -193,7 +193,7 @@
   int i, phdr_size;
 
   /* Read ELF header.  */
-  kernel_path = grub_util_get_path (dir, "kernel.elf");
+  kernel_path = grub_util_get_path (dir, "kernel.img");
   in = fopen (kernel_path, "rb");
   if (! in)
     grub_util_error ("cannot open %s", kernel_path);

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-21 19:05   ` Pavel Roskin
@ 2009-06-21 19:25     ` Robert Millan
  2009-06-22  2:14       ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 19:25 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 03:05:56PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 20:54 +0200, Robert Millan wrote:
> > Move grub_stop to init.c to ease code sharing with i386-qemu.
> 
> That's not quite a movement.  grub_cpu_idle() does nothing.

Well, the major problem with grub_cpu_idle() doing nothing on coreboot
is CPU consumption during polls.  grub_stop() is quite a corner case,
only seen when you hit an error.

> I think we need to have several implementations of grub_stop: hard halt
> with interrupts disabled, exit from qemu, exit from other emulators if
> it's different, power off, exit to BIOS.  Then different platforms
> should enable and try whatever is appropriate for them.

Note that we already have:

  grub_stop: Just hang.

  grub_exit: Exit to BIOS/whatever.  On coreboot (and on i386-qemu)
  there's really no "proper" thing to do.  Maybe fallback to
  grub_halt or grub_fatal.

  grub_halt: Power off.  Theoretically we can have it anywhere,
  although in some platforms like coreboot it's not easy; otherwise
  it can fallback to grub_stop.

I think grub_stop is intended to have this behaviour in all platforms.
But I'm not sure how useful is it.  Perhaps it could be ditched in
favour of grub_exit?

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 19:00 ` [PATCH] i386-qemu port Pavel Roskin
@ 2009-06-21 19:30   ` Robert Millan
  2009-06-22 12:45     ` Robert Millan
  2009-06-21 20:34   ` Robert Millan
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 19:30 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 03:00:42PM -0400, Pavel Roskin wrote:
> > The result is you can do e.g.
> > 
> >   $ sudo grub-mkrawimage at_keyboard normal etc -o /usr/share/qemu/grub
> 
> Please consider if we can call it grub-mkimage unless grub-mkimage would
> make sense as a separate executable for that platform.

Well, calling it grub-mkrawimage makes life a bit easier for packagers as
it brings us closer to a situation in which two ports don't conflict with
each other.  In debian we already ship a single copy of grub-mkelfimage
this way (grub-common package).

That said, in practice it isn't yet possible for two ports to coexist in
the same system, so it doesn't bring much benefit in short term.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-21 19:08   ` Pavel Roskin
@ 2009-06-21 19:33     ` Robert Millan
  2009-06-22 12:31       ` [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port)) Robert Millan
  2009-06-22 19:51       ` does module area require alignment? (Re: [PATCH] i386-qemu port) Pavel Roskin
  0 siblings, 2 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-21 19:33 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 03:08:19PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 20:50 +0200, Robert Millan wrote:
> 
> > Does anyone know why do we align ELF targets?  When I did the coreboot port,
> > the ELF part was based on existing Ieee1275 code, so I guess I just mimicked
> > it.  Is there some issue with non-i386 CPUs or with some Ieee1275
> > implementations that makes this alignment a requirement?
> 
> It was a hack for PowerPC openfirmware.  I don't know why it was needed.
> I didn't have time and desire to debug openfirmware to find out what it
> wants.

Is the hack you're referring to GRUB_MOD_GAP, GRUB_MOD_ALIGN or both?

Btw, I suspect GRUB_MOD_GAP might be related to the modules overlapping with
the BSS because of a firmware loader bug.  Is there a correlation between
the needed GRUB_MOD_GAP and the BSS size?

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] swap real_to_prot() and prot_to_real() (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (3 preceding siblings ...)
  2009-06-21 19:19 ` [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-21 19:52 ` Robert Millan
  2009-06-22  1:56   ` Pavel Roskin
  2009-06-21 20:22 ` [PATCH] i386-qemu port Robert Millan
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 19:52 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 828 bytes --]


When doing the i386-coreboot port I made this choice completely backwards.

I thought real_to_prot() was only useful on i386-pc, because we needed it
for returning from BIOS, and prot_to_real() was useful elsewhere, because
the Linux loader would use it.

Turns out we need real_to_prot() on i386-qemu for the initial transition
to i386 mode, AND we don't need prot_to_real() anywhere other than i386-pc,
because OSes that expect to be loaded in i8086 mode are going to rely on
BIOS calls.

So this patch swaps them.  real_to_prot() goes to realmode.S and
prot_to_real() back to startup.S.

-- 
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."

[-- Attachment #2: real_prot.diff --]
[-- Type: text/x-diff, Size: 5550 bytes --]

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

	* kern/i386/pc/startup.S (real_to_prot): Move from here ...
	* kern/i386/realmode.S (real_to_prot): ... to here.

	* kern/i386/realmode.S (prot_to_real): Move from here ...
	* kern/i386/pc/startup.S (prot_to_real): ... to here.

Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S	(revision 2353)
+++ kern/i386/pc/startup.S	(working copy)
@@ -302,62 +302,73 @@
 	.p2align	2	/* force 4-byte alignment */
 
 /*
- *  These next two routines, "real_to_prot" and "prot_to_real" are structured
- *  in a very specific way.  Be very careful when changing them.
+ *  This next routine, "prot_to_real" is structured in a very
+ *  specific way.  Be very careful when changing it.
  *
- *  NOTE:  Use of either one messes up %eax and %ebp.
+ *  NOTE:  Use of it messes up %eax and %ebp.
  */
 
-real_to_prot:
-	.code16
-	cli
+prot_to_real:
+	/* just in case, set GDT */
+	lgdt	gdtdesc
 
-	/* load the GDT register */
-#ifdef APPLE_CC
-	mov %cs, %ax
-	mov %ax, %ds
-	DATA32	ADDR32	lgdt	gdtdesc
-#else
-	DATA32	ADDR32	lgdt	%cs:gdtdesc
-#endif
+	/* save the protected mode stack */
+	movl	%esp, %eax
+	movl	%eax, protstack
 
-	/* turn on protected mode */
-	movl	%cr0, %eax
-	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
-	movl	%eax, %cr0
+	/* get the return address */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
 
-	/* jump to relocation, flush prefetch queue, and reload %cs */
-	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
+	/* set up new stack */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
 
-	.code32
-protcseg:
-	/* reload other segment registers */
-	movw	$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+	/* set up segment limits */
+	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_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
+	/* this might be an extra step */
+	/* jump to a 16 bit segment */
+	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
 
-	/* get protected mode stack */
-	movl	protstack, %eax
-	movl	%eax, %esp
-	movl	%eax, %ebp
+tmpcseg:
+	.code16
 
-	/* get return address onto the right stack */
-	movl	GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-	movl	%eax, (%esp)
+	/* clear the PE bit of CR0 */
+	movl	%cr0, %eax
+	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
+	movl	%eax, %cr0
 
+	/* flush prefetch queue, reload %cs */
+	DATA32	ljmp	$0, $realcseg
+
+realcseg:
+	/* we are in real mode now
+	 * set up the real mode segment registers : DS, SS, ES
+	 */
 	/* zero %eax */
 	xorl	%eax, %eax
 
-	/* return on the old (or initialized) stack! */
-	ret
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
 
+	/* restore interrupts */
+	sti
+
+	/* return on new stack! */
+	DATA32	ret
+
+	.code32
+
 /*
  * grub_gate_a20(int on)
  *
Index: kern/i386/realmode.S
===================================================================
--- kern/i386/realmode.S	(revision 2353)
+++ kern/i386/realmode.S	(working copy)
@@ -110,69 +110,59 @@
 	.long	gdt			/* addr */
 
 /*
- *  These next routine, "prot_to_real" is structured in a very
+ *  This next routine, "real_to_prot" is structured in a very
  *  specific way.  Be very careful when changing it.
  *
  *  NOTE:  Use of it messes up %eax and %ebp.
  */
 
-prot_to_real:
-	/* just in case, set GDT */
-	lgdt	gdtdesc
+real_to_prot:
+	.code16
+	cli
 
-	/* save the protected mode stack */
-	movl	%esp, %eax
-	movl	%eax, protstack
+	/* load the GDT register */
+#ifdef APPLE_CC
+	mov %cs, %ax
+	mov %ax, %ds
+	DATA32	ADDR32	lgdt	gdtdesc
+#else
+	DATA32	ADDR32	lgdt	%cs:gdtdesc
+#endif
 
-	/* get the return address */
-	movl	(%esp), %eax
-	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
+	/* turn on protected mode */
+	movl	%cr0, %eax
+	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
+	movl	%eax, %cr0
 
-	/* set up new stack */
-	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-	movl	%eax, %esp
-	movl	%eax, %ebp
+	/* jump to relocation, flush prefetch queue, and reload %cs */
+	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
 
-	/* set up segment limits */
-	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+	.code32
+protcseg:
+	/* 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
 
-	/* this might be an extra step */
-	/* jump to a 16 bit segment */
-	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
+	/* put the return address in a known safe location */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
 
-tmpcseg:
-	.code16
+	/* get protected mode stack */
+	movl	protstack, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
 
-	/* clear the PE bit of CR0 */
-	movl	%cr0, %eax
-	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
-	movl	%eax, %cr0
+	/* get return address onto the right stack */
+	movl	GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, (%esp)
 
-	/* flush prefetch queue, reload %cs */
-	DATA32	ljmp	$0, $realcseg
-
-realcseg:
-	/* we are in real mode now
-	 * set up the real mode segment registers : DS, SS, ES
-	 */
 	/* zero %eax */
 	xorl	%eax, %eax
 
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %fs
-	movw	%ax, %gs
-	movw	%ax, %ss
-
-	/* restore interrupts */
-	sti
-
-	/* return on new stack! */
-	DATA32	ret
-
+	/* return on the old (or initialized) stack! */
+	ret
 	.code32

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (4 preceding siblings ...)
  2009-06-21 19:52 ` [PATCH] swap real_to_prot() and prot_to_real() " Robert Millan
@ 2009-06-21 20:22 ` Robert Millan
  2009-06-22  1:50   ` Pavel Roskin
  2009-06-21 22:53 ` [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port) Robert Millan
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 20:22 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 344 bytes --]


New patch, after a bunch of misc cleanup, turning hardcoded numbers into
macros, improving comments, etc.

-- 
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."

[-- Attachment #2: qemu.diff --]
[-- Type: text/x-diff, Size: 25241 bytes --]

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 2354)
+++ 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)0xffe00
+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,108 @@
+/*
+ *  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_TOTAL_MODULE_SIZE
+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.
+	   We will derive the rom start address and size from it.  */
+	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,71 @@
+/*
+ *  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))
+
+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))
+{
+  /* This trashes the video bios, but for now we don't use it.  */
+  if (hook (0, 0x100000 - GRUB_BOOT_MACHINE_SIZE, GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  /* Protect boot.img, which contains the gdt.  It is mapped below 0x100000 ... */
+  if (hook (0x100000 - GRUB_BOOT_MACHINE_SIZE,
+	    GRUB_BOOT_MACHINE_SIZE,
+	    GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* ... and to the top of memory.  */
+  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;
+}
Index: kern/i386/coreboot/startup.S
===================================================================
--- kern/i386/coreboot/startup.S	(revision 2354)
+++ 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 2354)
+++ 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,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/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"
+
+real_to_prot:
+	.code16
+	cli
+
+	/* load the GDT register */
+	DATA32	ADDR32	lgdt	%cs:((0x10000 - GRUB_BOOT_MACHINE_SIZE) + (gdtdesc - _start))
+
+	/* 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, $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
+
+	/* 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
+entry:
+	jmp _start
+	. = GRUB_BOOT_MACHINE_SIZE
Index: configure.ac
===================================================================
--- configure.ac	(revision 2354)
+++ 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"]) ;;
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,29 @@
+/*
+ *  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			0x200
+
+/* The offset of GRUB_CORE_ENTRY_ADDR.  */
+#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR	0x8
+
+
+#endif
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 2354)
+++ 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 2354)
+++ 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
@@ -237,6 +248,8 @@
   if (num > 0xffff)
     grub_util_error ("the core image is too big");
 
+#if defined(GRUB_MACHINE_PCBIOS)
+
   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)
@@ -253,13 +266,48 @@
   free (boot_img);
   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);
+
+    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
+
   *((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,6 +317,7 @@
       *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
 	= grub_cpu_to_le32 (-2);
     }
+#endif
 
   if (GRUB_MEMORY_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
     grub_util_error ("Core image is too big (%p > %p)\n",

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 19:00 ` [PATCH] i386-qemu port Pavel Roskin
  2009-06-21 19:30   ` Robert Millan
@ 2009-06-21 20:34   ` Robert Millan
  2009-06-21 20:40     ` Vladimir 'phcoder' Serbinenko
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 20:34 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 03:00:42PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 20:17 +0200, Robert Millan wrote:
> > 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.
> 
> That's great news!  Eventually, it would be nice to have support for
> many other platforms supported by qemu, such as arm and mips.

Sure!  I hope it's going to be easier for arm and mips.  For i386 GRUB had
to jump between FOUR areas of code in memory before it can call grub_main()

(this is what happens after 30 years of backward compatibility 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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 20:34   ` Robert Millan
@ 2009-06-21 20:40     ` Vladimir 'phcoder' Serbinenko
  0 siblings, 0 replies; 71+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-06-21 20:40 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1368 bytes --]

On Sun, Jun 21, 2009 at 10:34 PM, Robert Millan <rmh@aybabtu.com> wrote:

> On Sun, Jun 21, 2009 at 03:00:42PM -0400, Pavel Roskin wrote:
> > On Sun, 2009-06-21 at 20:17 +0200, Robert Millan wrote:
> > > 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.
> >
> > That's great news!  Eventually, it would be nice to have support for
> > many other platforms supported by qemu, such as arm and mips.
>
> Sure!  I hope it's going to be easier for arm and mips.  For i386 GRUB had
> to jump between FOUR areas of code in memory before it can call grub_main()
>
I'll try to do mips

>
> (this is what happens after 30 years of backward compatibility 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."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git

[-- Attachment #2: Type: text/html, Size: 2259 bytes --]

^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (5 preceding siblings ...)
  2009-06-21 20:22 ` [PATCH] i386-qemu port Robert Millan
@ 2009-06-21 22:53 ` Robert Millan
  2009-06-22  1:22   ` Pavel Roskin
  2009-06-22 15:02 ` [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port) Robert Millan
  2009-06-22 23:07 ` clean patch for i386-qemu port " Robert Millan
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-21 22:53 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 798 bytes --]


In this line of code in real_to_prot():

	DATA32  ADDR32  lgdt    %cs:gdtdesc

GAS generates an absolute address for `gdtdesc' (not relative to segment),
and so for the code to work %cs must be zero.  In current usage of
real_to_prot(), %cs is always zero because we jump to 0x0:0x82xx early on.

However, in other situations this is not possible.  On i386-qemu, before
moving to i386 mode the code we're running is in the 0xf0000-0x100000
range, which is inaccessible from segment 0.

This patch changes this to access gdtdesc from segment 0 unconditionally.

-- 
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."

[-- Attachment #2: cs_in_real_to_prot.diff --]
[-- Type: text/x-diff, Size: 1092 bytes --]

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

	* kern/i386/pc/startup.S (real_to_prot): Access `gdtdesc' using
	segment 0x0 unconditionally, because the reference generated by
	GAS is an absolute address.

Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S	(revision 2353)
+++ kern/i386/pc/startup.S	(working copy)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *  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
@@ -313,13 +313,9 @@
 	cli
 
 	/* load the GDT register */
-#ifdef APPLE_CC
-	mov %cs, %ax
-	mov %ax, %ds
-	DATA32	ADDR32	lgdt	gdtdesc
-#else
-	DATA32	ADDR32	lgdt	%cs:gdtdesc
-#endif
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	DATA32	ADDR32	lgdt	%ds:gdtdesc
 
 	/* turn on protected mode */
 	movl	%cr0, %eax

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-21 22:53 ` [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-22  1:22   ` Pavel Roskin
  2009-06-22  9:52     ` Robert Millan
  2009-06-22 10:26     ` about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)) Robert Millan
  0 siblings, 2 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22  1:22 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 00:53 +0200, Robert Millan wrote:
> In this line of code in real_to_prot():
> 
> 	DATA32  ADDR32  lgdt    %cs:gdtdesc
> 
> GAS generates an absolute address for `gdtdesc' (not relative to segment),
> and so for the code to work %cs must be zero.  In current usage of
> real_to_prot(), %cs is always zero because we jump to 0x0:0x82xx early on.
> 
> However, in other situations this is not possible.  On i386-qemu, before
> moving to i386 mode the code we're running is in the 0xf0000-0x100000
> range, which is inaccessible from segment 0.

But gdtdesc should be next to the code we are running, since startup.S
includes realmode.S where gdtdesc is defined, so they compile into one
object file.

Since %cs is pointing to the code, it should be possible to point it to
gdtdesc.  They should be nearby.

Maybe you are trying to use a copy of gdtdesc in the beginning of
memory?  If GRUB serves as BIOS in i386-qemu, I'd rather use the "BIOS"
value in the 0xF000 segment rather than the "RAM".

As for the APPLE_CC issue, I guess the Apple compiler doesn't understand
the segment prefix at that position.  The right fix would be to use
".byte" statements to create the same bytecode instead of introducing a
different behavior to work around a compiler limitation.

Then I guess the Apple compiler won't accepted %ds: either, so if we
want to use %ds, we should omit it.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 20:22 ` [PATCH] i386-qemu port Robert Millan
@ 2009-06-22  1:50   ` Pavel Roskin
  2009-06-22 10:57     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22  1:50 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 22:22 +0200, Robert Millan wrote:
> New patch, after a bunch of misc cleanup, turning hardcoded numbers into
> macros, improving comments, etc.

kernel_img_FORMAT is defined but never used.

GRUB_MEMORY_MACHINE_LINK_ADDR doesn't need to be conditional, it's the
same for coreboot and qemu.

Renaming kernel.elf to kernel.img could be done separately.  Since it's
a trivial patch, it can be committed without review provided that is
compiles.

Please don't add trailing whitespace.

When compiling for coreboot, a warning appears:

/home/proski/src/grub2.git/kern/i386/coreboot/init.c: In function
'grub_arch_modules_addr':
/home/proski/src/grub2.git/kern/i386/coreboot/init.c:159: warning:
return makes integer from pointer without a cast

Compilation for qemu fails when compiling in a separate directory:

/home/proski/src/grub2.git/boot/i386/qemu/boot.S:60:32: error:
kern/i386/realmode.S: No such file or directory

The fix is to use relative path to include realmode.S:

#include "../../../kern/i386/realmode.S"

Here's my fix for compile warnings and errors.  Please incorporate.

diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S
index 81cdc24..177453b 100644
--- a/boot/i386/qemu/boot.S
+++ b/boot/i386/qemu/boot.S
@@ -57,7 +57,7 @@ VARIABLE(grub_core_entry_addr)
 	movl	grub_core_entry_addr, %edx
 	jmp	*%edx
 
-#include "kern/i386/realmode.S"
+#include "../../../kern/i386/realmode.S"
 
 real_to_prot:
 	.code16
diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
index 89e1e58..8a27c2b 100644
--- a/kern/i386/coreboot/init.c
+++ b/kern/i386/coreboot/init.c
@@ -156,5 +156,5 @@ grub_addr_t
 grub_arch_modules_addr (void)
 {
 //  return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
-  return _end;
+  return (grub_addr_t) _end;
 }

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH] swap real_to_prot() and prot_to_real() (Re: [PATCH] i386-qemu port)
  2009-06-21 19:52 ` [PATCH] swap real_to_prot() and prot_to_real() " Robert Millan
@ 2009-06-22  1:56   ` Pavel Roskin
  2009-06-22 10:45     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22  1:56 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1049 bytes --]

On Sun, 2009-06-21 at 21:52 +0200, Robert Millan wrote:
> When doing the i386-coreboot port I made this choice completely backwards.
> 
> I thought real_to_prot() was only useful on i386-pc, because we needed it
> for returning from BIOS, and prot_to_real() was useful elsewhere, because
> the Linux loader would use it.
> 
> Turns out we need real_to_prot() on i386-qemu for the initial transition
> to i386 mode, AND we don't need prot_to_real() anywhere other than i386-pc,
> because OSes that expect to be loaded in i8086 mode are going to rely on
> BIOS calls.
> 
> So this patch swaps them.  real_to_prot() goes to realmode.S and
> prot_to_real() back to startup.S.

You have my approval as long as it compiles and doesn't introduce any
warnings.

I'm attaching the script I'm using to test all platforms at once.  The
compiler path needs to be adjusted, as well as the target names, as they
affect search for the target compiler.  That's the version with qemu
support.  If every Log2make is empty, please go ahead.

-- 
Regards,
Pavel Roskin

[-- Attachment #2: grub-all-qemu --]
[-- Type: application/x-shellscript, Size: 620 bytes --]

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-21 19:25     ` Robert Millan
@ 2009-06-22  2:14       ` Pavel Roskin
  2009-06-22 10:10         ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22  2:14 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 21:25 +0200, Robert Millan wrote:
> On Sun, Jun 21, 2009 at 03:05:56PM -0400, Pavel Roskin wrote:
> > On Sun, 2009-06-21 at 20:54 +0200, Robert Millan wrote:
> > > Move grub_stop to init.c to ease code sharing with i386-qemu.
> > 
> > That's not quite a movement.  grub_cpu_idle() does nothing.
> 
> Well, the major problem with grub_cpu_idle() doing nothing on coreboot
> is CPU consumption during polls.  grub_stop() is quite a corner case,
> only seen when you hit an error.

I think this should do the right thing if our goal is to stop:

	cli
halt:
	hlt
	jmp halt

The last "jmp" is just in case for non-maskable interrupts.

> > I think we need to have several implementations of grub_stop: hard halt
> > with interrupts disabled, exit from qemu, exit from other emulators if
> > it's different, power off, exit to BIOS.  Then different platforms
> > should enable and try whatever is appropriate for them.
> 
> Note that we already have:
> 
>   grub_stop: Just hang.
> 
>   grub_exit: Exit to BIOS/whatever.  On coreboot (and on i386-qemu)
>   there's really no "proper" thing to do.  Maybe fallback to
>   grub_halt or grub_fatal.
> 
>   grub_halt: Power off.  Theoretically we can have it anywhere,
>   although in some platforms like coreboot it's not easy; otherwise
>   it can fallback to grub_stop.
> 
> I think grub_stop is intended to have this behaviour in all platforms.
> But I'm not sure how useful is it.  Perhaps it could be ditched in
> favour of grub_exit?

From the user's standpoint, I think three "stop-like" calls make sense:

Try to exit so that BIOS can try another media.  Failing that, hang.
That would be appropriate for installations on disks that may or may not
be bootable.  That's grub_exit().

Try for power down the system (that includes telling the emulator to
stop).  Failing that, hang.  That would be appropriate for data centers
where we don't want non-functioning systems to consume power.  That's
grub_halt().

Just stop.  Appropriate if there is an important message on the screen
that the user must see.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port)
  2009-06-21 19:19 ` [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-22  2:20   ` Pavel Roskin
  2009-06-22 10:27     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22  2:20 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 21:19 +0200, Robert Millan wrote:
> If you check my earlier patch, you'll see i386-qemu.rmk is just a stub
> that includes i386-coreboot.rmk.  This is to reduce code duplication
> (untill we have a more flexible build system).
> 
> This patch renames kernel.elf to kernel.img in ELF platforms, so that
> more variables / etc can be shared with non-ELF ones.

No objections as long as it compiles without warnings.  Sharing more
code is a good thing.

By please note that I had to add kernel_elf_ASFLAGS in
i386-ieee1275.rmk, or with would not compile on x86_64, as some compiler
invocations would miss -m32.  So you patch will need to be adjusted for
that.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22  1:22   ` Pavel Roskin
@ 2009-06-22  9:52     ` Robert Millan
  2009-06-22 19:39       ` Pavel Roskin
  2009-06-22 10:26     ` about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)) Robert Millan
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22  9:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 09:22:41PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 00:53 +0200, Robert Millan wrote:
> > In this line of code in real_to_prot():
> > 
> > 	DATA32  ADDR32  lgdt    %cs:gdtdesc
> > 
> > GAS generates an absolute address for `gdtdesc' (not relative to segment),
> > and so for the code to work %cs must be zero.  In current usage of
> > real_to_prot(), %cs is always zero because we jump to 0x0:0x82xx early on.
> > 
> > However, in other situations this is not possible.  On i386-qemu, before
> > moving to i386 mode the code we're running is in the 0xf0000-0x100000
> > range, which is inaccessible from segment 0.
> 
> But gdtdesc should be next to the code we are running, since startup.S
> includes realmode.S where gdtdesc is defined, so they compile into one
> object file.
> 
> Since %cs is pointing to the code, it should be possible to point it to
> gdtdesc.  They should be nearby.

It is nearby, but the address reference for `gdtdesc' is absolute, NOT
relative to %cs.  Of course, when %cs is 0 that's no problem.  But in my
case I can't set %cs to 0 because my code is above 0x10000.

> As for the APPLE_CC issue, I guess the Apple compiler doesn't understand
> the segment prefix at that position.  The right fix would be to use
> ".byte" statements to create the same bytecode instead of introducing a
> different behavior to work around a compiler limitation.
> 
> Then I guess the Apple compiler won't accepted %ds: either, so if we
> want to use %ds, we should omit it.

Yes, this should work.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-22  2:14       ` Pavel Roskin
@ 2009-06-22 10:10         ` Robert Millan
  2009-06-22 16:16           ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 10:10 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 10:14:13PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 21:25 +0200, Robert Millan wrote:
> > On Sun, Jun 21, 2009 at 03:05:56PM -0400, Pavel Roskin wrote:
> > > On Sun, 2009-06-21 at 20:54 +0200, Robert Millan wrote:
> > > > Move grub_stop to init.c to ease code sharing with i386-qemu.
> > > 
> > > That's not quite a movement.  grub_cpu_idle() does nothing.
> > 
> > Well, the major problem with grub_cpu_idle() doing nothing on coreboot
> > is CPU consumption during polls.  grub_stop() is quite a corner case,
> > only seen when you hit an error.
> 
> I think this should do the right thing if our goal is to stop:
> 
> 	cli
> halt:
> 	hlt
> 	jmp halt
> 
> The last "jmp" is just in case for non-maskable interrupts.

My aim was to move this to C code so it can be shared between i386-qemu
and i386-coreboot.  However, this code will be the same on other i386
ports, but we don't yet have a generic .S file for i386 code.

How about kern/i386/misc.S ?

> >   grub_stop: Just hang.
> > 
> >   grub_exit: Exit to BIOS/whatever.  On coreboot (and on i386-qemu)
> >   there's really no "proper" thing to do.  Maybe fallback to
> >   grub_halt or grub_fatal.
> > 
> >   grub_halt: Power off.  Theoretically we can have it anywhere,
> >   although in some platforms like coreboot it's not easy; otherwise
> >   it can fallback to grub_stop.
> > 
> > I think grub_stop is intended to have this behaviour in all platforms.
> > But I'm not sure how useful is it.  Perhaps it could be ditched in
> > favour of grub_exit?
> 
> >From the user's standpoint, I think three "stop-like" calls make sense:
> 
> Try to exit so that BIOS can try another media.  Failing that, hang.
> That would be appropriate for installations on disks that may or may not
> be bootable.  That's grub_exit().
> 
> Try for power down the system (that includes telling the emulator to
> stop).  Failing that, hang.  That would be appropriate for data centers
> where we don't want non-functioning systems to consume power.  That's
> grub_halt().
> 
> Just stop.  Appropriate if there is an important message on the screen
> that the user must see.

This seems to be the current behaviour, unless I missed something.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port))
  2009-06-22  1:22   ` Pavel Roskin
  2009-06-22  9:52     ` Robert Millan
@ 2009-06-22 10:26     ` Robert Millan
  2009-06-22 16:10       ` Pavel Roskin
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 10:26 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 09:22:41PM -0400, Pavel Roskin wrote:
> 
> Then I guess the Apple compiler won't accepted %ds: either, so if we
> want to use %ds, we should omit it.

Btw, it's Apple assembler that matters here.  AFAIK their compiler is GCC.

I think those checks would need some adjustment, or it'll be a mess when
we want to support GNU binutils on MacOS.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port)
  2009-06-22  2:20   ` Pavel Roskin
@ 2009-06-22 10:27     ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 10:27 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 10:20:04PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 21:19 +0200, Robert Millan wrote:
> > If you check my earlier patch, you'll see i386-qemu.rmk is just a stub
> > that includes i386-coreboot.rmk.  This is to reduce code duplication
> > (untill we have a more flexible build system).
> > 
> > This patch renames kernel.elf to kernel.img in ELF platforms, so that
> > more variables / etc can be shared with non-ELF ones.
> 
> No objections as long as it compiles without warnings.  Sharing more
> code is a good thing.
> 
> By please note that I had to add kernel_elf_ASFLAGS in
> i386-ieee1275.rmk, or with would not compile on x86_64, as some compiler
> invocations would miss -m32.  So you patch will need to be adjusted for
> that.

Updated, verified warning-free and committed.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] swap real_to_prot() and prot_to_real() (Re: [PATCH] i386-qemu port)
  2009-06-22  1:56   ` Pavel Roskin
@ 2009-06-22 10:45     ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 10:45 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 09:56:42PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 21:52 +0200, Robert Millan wrote:
> > When doing the i386-coreboot port I made this choice completely backwards.
> > 
> > I thought real_to_prot() was only useful on i386-pc, because we needed it
> > for returning from BIOS, and prot_to_real() was useful elsewhere, because
> > the Linux loader would use it.
> > 
> > Turns out we need real_to_prot() on i386-qemu for the initial transition
> > to i386 mode, AND we don't need prot_to_real() anywhere other than i386-pc,
> > because OSes that expect to be loaded in i8086 mode are going to rely on
> > BIOS calls.
> > 
> > So this patch swaps them.  real_to_prot() goes to realmode.S and
> > prot_to_real() back to startup.S.
> 
> You have my approval as long as it compiles and doesn't introduce any
> warnings.

Done, no warnings.  I decided to keep prot_to_real() in its current place
though.  It's probably going to be useful when we support processing ROMs
in i386-coreboot (e.g. for biosdisk or vbe).

> I'm attaching the script I'm using to test all platforms at once.  The
> compiler path needs to be adjusted, as well as the target names, as they
> affect search for the target compiler.  That's the version with qemu
> support.  If every Log2make is empty, please go ahead.

Thanks.  Btw, maybe you find this useful:

-MAKE_JOBS=8
+MAKE_JOBS=`getconf _NPROCESSORS_ONLN || echo 1`

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-22  1:50   ` Pavel Roskin
@ 2009-06-22 10:57     ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 10:57 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 09:50:25PM -0400, Pavel Roskin wrote:
> On Sun, 2009-06-21 at 22:22 +0200, Robert Millan wrote:
> > New patch, after a bunch of misc cleanup, turning hardcoded numbers into
> > macros, improving comments, etc.
> 
> kernel_img_FORMAT is defined but never used.

It's used by the build system, see:

genmk.rb:       $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@

> GRUB_MEMORY_MACHINE_LINK_ADDR doesn't need to be conditional, it's the
> same for coreboot and qemu.

Ok.

> Renaming kernel.elf to kernel.img could be done separately.  Since it's
> a trivial patch, it can be committed without review provided that is
> compiles.

Committed already.

> Please don't add trailing whitespace.

Fixed.

> Here's my fix for compile warnings and errors.  Please incorporate.

Merged, thanks.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-21 19:33     ` Robert Millan
@ 2009-06-22 12:31       ` Robert Millan
  2009-06-22 19:43         ` Pavel Roskin
  2009-06-22 19:51       ` does module area require alignment? (Re: [PATCH] i386-qemu port) Pavel Roskin
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 12:31 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 413 bytes --]


Well it seems that OLPC (i386-ieee1275) needs alignment, but coreboot doesn't.
It must be some OFW-specific oddity.

This patch makes the alignment ieee1275-specific on i386.

-- 
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."

[-- Attachment #2: ieee1275_align.diff --]
[-- Type: text/x-diff, Size: 1257 bytes --]

Index: kern/i386/coreboot/init.c
===================================================================
--- kern/i386/coreboot/init.c	(revision 2358)
+++ kern/i386/coreboot/init.c	(working copy)
@@ -144,5 +144,5 @@ grub_machine_fini (void)
 grub_addr_t
 grub_arch_modules_addr (void)
 {
-  return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
+  return (grub_addr_t) _end;
 }
Index: include/grub/i386/kernel.h
===================================================================
--- include/grub/i386/kernel.h	(revision 2358)
+++ include/grub/i386/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,7 +19,13 @@
 #ifndef GRUB_KERNEL_CPU_HEADER
 #define GRUB_KERNEL_CPU_HEADER	1
 
-#define GRUB_MOD_ALIGN 0x1000
+#include <grub/machine/machine.h>
+
+#ifdef GRUB_MACHINE_IEEE1275
+#define GRUB_MOD_ALIGN	0x1000
+#else
+#define GRUB_MOD_ALIGN	0
+#endif
 
 /* Non-zero value is only needed for PowerMacs.  */
 #define GRUB_MOD_GAP 0x0

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] i386-qemu port
  2009-06-21 19:30   ` Robert Millan
@ 2009-06-22 12:45     ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 12:45 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 21, 2009 at 09:30:11PM +0200, Robert Millan wrote:
> On Sun, Jun 21, 2009 at 03:00:42PM -0400, Pavel Roskin wrote:
> > > The result is you can do e.g.
> > > 
> > >   $ sudo grub-mkrawimage at_keyboard normal etc -o /usr/share/qemu/grub
> > 
> > Please consider if we can call it grub-mkimage unless grub-mkimage would
> > make sense as a separate executable for that platform.
> 
> Well, calling it grub-mkrawimage makes life a bit easier for packagers as
> it brings us closer to a situation in which two ports don't conflict with
> each other.  In debian we already ship a single copy of grub-mkelfimage
> this way (grub-common package).
> 
> That said, in practice it isn't yet possible for two ports to coexist in
> the same system, so it doesn't bring much benefit in short term.

I'll just make it grub-mkimage for now.  We can always discuss about a rename
later on.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (6 preceding siblings ...)
  2009-06-21 22:53 ` [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-22 15:02 ` Robert Millan
  2009-06-22 19:00   ` Pavel Roskin
  2009-06-22 23:07 ` clean patch for i386-qemu port " Robert Millan
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 15:02 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]


My latest qemu patch removes the redundancy between boot.img link address
and GRUB_BOOT_MACHINE_SIZE.  This requires two macros for distinguishing
between kernel & boot link addresses:

  GRUB_BOOT_MACHINE_LINK_ADDR	= 0xffe00
  GRUB_KERNEL_MACHINE_LINK_ADDR	= 0x8200

whereas the existing GRUB_MEMORY_MACHINE_LINK_ADDR becomes ambigous.  This
patch discards it in favour of GRUB_KERNEL_MACHINE_LINK_ADDR (the i386-pc
bits need to be modified, since they share grub-mkimage code).

-- 
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."

[-- Attachment #2: memory_kernel.diff --]
[-- Type: text/x-diff, Size: 2145 bytes --]

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

	* conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): Rename to ...
	(GRUB_KERNEL_MACHINE_LINK_ADDR): ... this.  Update all users.

Index: conf/i386-pc.rmk
===================================================================
--- conf/i386-pc.rmk	(revision 2358)
+++ conf/i386-pc.rmk	(working copy)
@@ -1,6 +1,6 @@
 # -*- makefile -*-
 
-GRUB_MEMORY_MACHINE_LINK_ADDR = 0x8200
+GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
 
 COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
@@ -67,7 +67,7 @@
 	machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
 kernel_img_FORMAT = binary
 
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
@@ -95,7 +95,7 @@
 grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
 	util/resolve.c lib/LzmaEnc.c lib/LzFind.c
 endif
-grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR)
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
 util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
 
 # For grub-setup.
Index: util/i386/pc/grub-mkimage.c
===================================================================
--- util/i386/pc/grub-mkimage.c	(revision 2358)
+++ util/i386/pc/grub-mkimage.c	(working copy)
@@ -270,9 +270,9 @@
 	= grub_cpu_to_le32 (-2);
     }
 
-  if (GRUB_MEMORY_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_MEMORY_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER);
+ 		     GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER);
 
   grub_util_write_image (core_img, core_size, out);
   free (kernel_img);

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port))
  2009-06-22 10:26     ` about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)) Robert Millan
@ 2009-06-22 16:10       ` Pavel Roskin
  0 siblings, 0 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 16:10 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 12:26 +0200, Robert Millan wrote:
> On Sun, Jun 21, 2009 at 09:22:41PM -0400, Pavel Roskin wrote:
> > 
> > Then I guess the Apple compiler won't accepted %ds: either, so if we
> > want to use %ds, we should omit it.
> 
> Btw, it's Apple assembler that matters here.  AFAIK their compiler is GCC.
> 
> I think those checks would need some adjustment, or it'll be a mess when
> we want to support GNU binutils on MacOS.

In most cases, we just want to leave the APPLE_CC version, as it's more
portable.  But we should verify that the same bytecode is generated,
just to be safe.

In many cases, I'd like to see if there is a simpler workaround.
Unfortunately, I don't have access to the Apple compiler.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-22 10:10         ` Robert Millan
@ 2009-06-22 16:16           ` Pavel Roskin
  2009-06-22 18:05             ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 16:16 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 12:10 +0200, Robert Millan wrote:

> My aim was to move this to C code so it can be shared between i386-qemu
> and i386-coreboot.  However, this code will be the same on other i386
> ports, but we don't yet have a generic .S file for i386 code.
> 
> How about kern/i386/misc.S ?

Fine with me.  We shouldn't switch to inferior C code just because we
don't have a shared .S file.

> This seems to be the current behaviour, unless I missed something.

OK, never mind.  I should have done that analysis before bringing up the
issue.

Anyway, I think grub_halt() should be renamed to grub_poweroff() to be
more explicit about its goal.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] move grub_stop() (Re: [PATCH] i386-qemu port)
  2009-06-22 16:16           ` Pavel Roskin
@ 2009-06-22 18:05             ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 18:05 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 12:16:35PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 12:10 +0200, Robert Millan wrote:
> 
> > My aim was to move this to C code so it can be shared between i386-qemu
> > and i386-coreboot.  However, this code will be the same on other i386
> > ports, but we don't yet have a generic .S file for i386 code.
> > 
> > How about kern/i386/misc.S ?
> 
> Fine with me.  We shouldn't switch to inferior C code just because we
> don't have a shared .S file.

Agreed.  I just replaced the 3 instances we had of grub_stop() with a
single one in kern/i386/misc.S.

> Anyway, I think grub_halt() should be renamed to grub_poweroff() to be
> more explicit about its goal.

Fine with me.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port)
  2009-06-22 15:02 ` [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-22 19:00   ` Pavel Roskin
  0 siblings, 0 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 19:00 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 17:02 +0200, Robert Millan wrote:
> My latest qemu patch removes the redundancy between boot.img link address
> and GRUB_BOOT_MACHINE_SIZE.  This requires two macros for distinguishing
> between kernel & boot link addresses:
> 
>   GRUB_BOOT_MACHINE_LINK_ADDR	= 0xffe00
>   GRUB_KERNEL_MACHINE_LINK_ADDR	= 0x8200
> 
> whereas the existing GRUB_MEMORY_MACHINE_LINK_ADDR becomes ambigous.  This
> patch discards it in favour of GRUB_KERNEL_MACHINE_LINK_ADDR (the i386-pc
> bits need to be modified, since they share grub-mkimage code).

Fine with me.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22  9:52     ` Robert Millan
@ 2009-06-22 19:39       ` Pavel Roskin
  2009-06-22 20:52         ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 19:39 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 11:52 +0200, Robert Millan wrote: 
> > Since %cs is pointing to the code, it should be possible to point it to
> > gdtdesc.  They should be nearby.
> 
> It is nearby, but the address reference for `gdtdesc' is absolute, NOT
> relative to %cs.  Of course, when %cs is 0 that's no problem.  But in my
> case I can't set %cs to 0 because my code is above 0x10000.

I think we can remove ADDR32 from the command.  I tried that on i386-pc
and it works in qemu and on real hardware.  I don't see any need to use
a 32-bit address in the lgdt command.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 12:31       ` [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port)) Robert Millan
@ 2009-06-22 19:43         ` Pavel Roskin
  2009-06-22 20:41           ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 19:43 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 14:31 +0200, Robert Millan wrote:
> Well it seems that OLPC (i386-ieee1275) needs alignment, but coreboot doesn't.
> It must be some OFW-specific oddity.
> 
> This patch makes the alignment ieee1275-specific on i386.

We can define GRUB_MOD_ALIGN to 1 for such architectures and keep using
ALIGN_UP (or remove ALIGN_UP - it doesn't matter).  The value of 0 for
GRUB_MOD_ALIGN is meaningless, but the value of 1 has a meaning - align
to a byte boundary.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-21 19:33     ` Robert Millan
  2009-06-22 12:31       ` [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port)) Robert Millan
@ 2009-06-22 19:51       ` Pavel Roskin
  2009-06-22 22:50         ` Vladimir 'phcoder' Serbinenko
  1 sibling, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 19:51 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 21:33 +0200, Robert Millan wrote:
> On Sun, Jun 21, 2009 at 03:08:19PM -0400, Pavel Roskin wrote:
> > On Sun, 2009-06-21 at 20:50 +0200, Robert Millan wrote:
> > 
> > > Does anyone know why do we align ELF targets?  When I did the coreboot port,
> > > the ELF part was based on existing Ieee1275 code, so I guess I just mimicked
> > > it.  Is there some issue with non-i386 CPUs or with some Ieee1275
> > > implementations that makes this alignment a requirement?
> > 
> > It was a hack for PowerPC openfirmware.  I don't know why it was needed.
> > I didn't have time and desire to debug openfirmware to find out what it
> > wants.
> 
> Is the hack you're referring to GRUB_MOD_GAP, GRUB_MOD_ALIGN or both?

I'm referring to GRUB_MOD_GAP.

> Btw, I suspect GRUB_MOD_GAP might be related to the modules overlapping with
> the BSS because of a firmware loader bug.  Is there a correlation between
> the needed GRUB_MOD_GAP and the BSS size?

I don't see any correlation.

I made 3 images with the gap of 0x4000, 0x8000 and 0xc000.  Then I added
an uninitialized array to the kernel, 0x4000 bytes long, and made
another 3 images with the same gap sizes.  The images with the 0x4000
gap don't boot and the images with the gap sized 0x8000 and 0xc000 boot
regardless of the array.

That's PowerMac G3 "Blue and White".

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 19:43         ` Pavel Roskin
@ 2009-06-22 20:41           ` Robert Millan
  2009-06-22 20:51             ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 20:41 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 03:43:17PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 14:31 +0200, Robert Millan wrote:
> > Well it seems that OLPC (i386-ieee1275) needs alignment, but coreboot doesn't.
> > It must be some OFW-specific oddity.
> > 
> > This patch makes the alignment ieee1275-specific on i386.
> 
> We can define GRUB_MOD_ALIGN to 1 for such architectures and keep using
> ALIGN_UP (or remove ALIGN_UP - it doesn't matter).  The value of 0 for
> GRUB_MOD_ALIGN is meaningless, but the value of 1 has a meaning - align
> to a byte boundary.

Good idea, I just did that.  I didn't remove ALIGN_UP, since it's harmless.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 20:41           ` Robert Millan
@ 2009-06-22 20:51             ` Pavel Roskin
  2009-06-22 21:22               ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 20:51 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 22:41 +0200, Robert Millan wrote:
> On Mon, Jun 22, 2009 at 03:43:17PM -0400, Pavel Roskin wrote:
> > On Mon, 2009-06-22 at 14:31 +0200, Robert Millan wrote:
> > > Well it seems that OLPC (i386-ieee1275) needs alignment, but coreboot doesn't.
> > > It must be some OFW-specific oddity.
> > > 
> > > This patch makes the alignment ieee1275-specific on i386.
> > 
> > We can define GRUB_MOD_ALIGN to 1 for such architectures and keep using
> > ALIGN_UP (or remove ALIGN_UP - it doesn't matter).  The value of 0 for
> > GRUB_MOD_ALIGN is meaningless, but the value of 1 has a meaning - align
> > to a byte boundary.
> 
> Good idea, I just did that.  I didn't remove ALIGN_UP, since it's harmless.

By the way, it turns out that PowerPC needs alignment of 4 bytes.  That
would allow me to find the exact minimal gap and see if it's influenced
by anything.  The gap is between 0x8c50 and 0x8c60.

You may want to use 4 byte alignment too.  It's a good thing to align
32-bit addresses in the ELF headers.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 19:39       ` Pavel Roskin
@ 2009-06-22 20:52         ` Robert Millan
  2009-06-22 21:32           ` Robert Millan
  2009-06-22 21:36           ` Pavel Roskin
  0 siblings, 2 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 20:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 03:39:03PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 11:52 +0200, Robert Millan wrote: 
> > > Since %cs is pointing to the code, it should be possible to point it to
> > > gdtdesc.  They should be nearby.
> > 
> > It is nearby, but the address reference for `gdtdesc' is absolute, NOT
> > relative to %cs.  Of course, when %cs is 0 that's no problem.  But in my
> > case I can't set %cs to 0 because my code is above 0x10000.
> 
> I think we can remove ADDR32 from the command.  I tried that on i386-pc
> and it works in qemu and on real hardware.  I don't see any need to use
> a 32-bit address in the lgdt command.

This won't build.  I don't think it's possible to use relative addresses
with this particular instruction.  "DATA32 lgdt %cs:gdtdesc" results in:

  boot_img-boot_i386_qemu_boot.o: In function `real_to_prot':
  (.text+0x64): relocation truncated to fit: R_386_16 against `.text'

What's the problem with removing %cs?  It's presence there is bogus.  It
*seems* to indicate gdtdesc is a segment-relative reference, but in fact
it's not, and it just happens to work because %cs was set to 0.

Note: "ADDR32 lgdt %cs:gdtdesc" builds, but generates an absolute address
too.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 20:51             ` Pavel Roskin
@ 2009-06-22 21:22               ` Robert Millan
  2009-06-22 21:45                 ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 21:22 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 04:51:43PM -0400, Pavel Roskin wrote:
> 
> You may want to use 4 byte alignment too.  It's a good thing to align
> 32-bit addresses in the ELF headers.

Ok, but we aren't doing it on i386-pc, and this never caused trouble.  The
ELF headers in our modules are only loaded by GRUB itself, and if our
loader can cope with unaligned addresses, why bother trying to align
them?

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 20:52         ` Robert Millan
@ 2009-06-22 21:32           ` Robert Millan
  2009-06-22 21:44             ` Pavel Roskin
  2009-06-22 21:36           ` Pavel Roskin
  1 sibling, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 21:32 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 10:52:13PM +0200, Robert Millan wrote:
> I don't think it's possible to use relative addresses
> with this particular instruction.

Uhm sorry, this was silly.  Of course you can use addresses relative to a
segment in lgdt, but this doesn't change the fact that GAS always gives
you absolute ones.

Also, I'm not sure if it's possible to use a 16-bit field in this instruction,
it could be that the field is always 32-bit, even if it's relative to a
segment.  This dump is from the i386-pc kernel.img:

    836f:       2e 67 66 0f 01 15 68    addr32 lgdtl %cs:0x8368
    8376:       83 00 00 

a little-endian 0x00008368 is seen here, indicating the field is 32-bit.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 20:52         ` Robert Millan
  2009-06-22 21:32           ` Robert Millan
@ 2009-06-22 21:36           ` Pavel Roskin
  2009-06-22 22:52             ` Robert Millan
  1 sibling, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 21:36 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 22:52 +0200, Robert Millan wrote:
> On Mon, Jun 22, 2009 at 03:39:03PM -0400, Pavel Roskin wrote:
> > On Mon, 2009-06-22 at 11:52 +0200, Robert Millan wrote: 
> > > > Since %cs is pointing to the code, it should be possible to point it to
> > > > gdtdesc.  They should be nearby.
> > > 
> > > It is nearby, but the address reference for `gdtdesc' is absolute, NOT
> > > relative to %cs.  Of course, when %cs is 0 that's no problem.  But in my
> > > case I can't set %cs to 0 because my code is above 0x10000.
> > 
> > I think we can remove ADDR32 from the command.  I tried that on i386-pc
> > and it works in qemu and on real hardware.  I don't see any need to use
> > a 32-bit address in the lgdt command.
> 
> This won't build.  I don't think it's possible to use relative addresses
> with this particular instruction.  "DATA32 lgdt %cs:gdtdesc" results in:
> 
>   boot_img-boot_i386_qemu_boot.o: In function `real_to_prot':
>   (.text+0x64): relocation truncated to fit: R_386_16 against `.text'

My bad, I only checked it for i386-pc.  I see this error for
ieee1275-i386.

I believe it happens because we relocate the output too high in memory,
so we cannot relocate a 16-bit address there.

> What's the problem with removing %cs?  It's presence there is bogus.  It
> *seems* to indicate gdtdesc is a segment-relative reference, but in fact
> it's not, and it just happens to work because %cs was set to 0.

I just wanted to make sure we are not doing anything wrong.  I have a
feeling that somebody with a good knowledge of assembler tricks could
write the code to use %cs and a 16-bit address, but I don't know how to
do it.

Anyway, your code is correct and I have no objections.  Please commit.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 21:32           ` Robert Millan
@ 2009-06-22 21:44             ` Pavel Roskin
  2009-06-22 22:43               ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 21:44 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 23:32 +0200, Robert Millan wrote:
> On Mon, Jun 22, 2009 at 10:52:13PM +0200, Robert Millan wrote:
> > I don't think it's possible to use relative addresses
> > with this particular instruction.
> 
> Uhm sorry, this was silly.  Of course you can use addresses relative to a
> segment in lgdt, but this doesn't change the fact that GAS always gives
> you absolute ones.
> 
> Also, I'm not sure if it's possible to use a 16-bit field in this instruction,
> it could be that the field is always 32-bit, even if it's relative to a
> segment.  This dump is from the i386-pc kernel.img:
> 
>     836f:       2e 67 66 0f 01 15 68    addr32 lgdtl %cs:0x8368
>     8376:       83 00 00 
> 
> a little-endian 0x00008368 is seen here, indicating the field is 32-bit.

But if I omit ADDR32, I get:

0000016e <real_to_prot>:
 16e:   fa                      cli    
 16f:   2e 66 0f 01 16 68 01    lgdtl  %cs:0x168
 176:   0f 20 c0                mov    %cr0,%eax

The address is 16-bit.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 21:22               ` Robert Millan
@ 2009-06-22 21:45                 ` Pavel Roskin
  2009-06-22 22:31                   ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-22 21:45 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 23:22 +0200, Robert Millan wrote:
> On Mon, Jun 22, 2009 at 04:51:43PM -0400, Pavel Roskin wrote:
> > 
> > You may want to use 4 byte alignment too.  It's a good thing to align
> > 32-bit addresses in the ELF headers.
> 
> Ok, but we aren't doing it on i386-pc, and this never caused trouble.  The
> ELF headers in our modules are only loaded by GRUB itself, and if our
> loader can cope with unaligned addresses, why bother trying to align
> them?

Maybe to speed up things.  But I don't really care.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port))
  2009-06-22 21:45                 ` Pavel Roskin
@ 2009-06-22 22:31                   ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 22:31 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 05:45:54PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 23:22 +0200, Robert Millan wrote:
> > On Mon, Jun 22, 2009 at 04:51:43PM -0400, Pavel Roskin wrote:
> > > 
> > > You may want to use 4 byte alignment too.  It's a good thing to align
> > > 32-bit addresses in the ELF headers.
> > 
> > Ok, but we aren't doing it on i386-pc, and this never caused trouble.  The
> > ELF headers in our modules are only loaded by GRUB itself, and if our
> > loader can cope with unaligned addresses, why bother trying to align
> > them?
> 
> Maybe to speed up things.  But I don't really care.

Well, if there's interest in doing this, I would suggest finding a
platform-independant way.  For example the modinfo structure could remain
unaligned, with padding in-between its ELF modules or so.

If there's a speed improvement I'm fine with it.  But I can sleep at night
without alignment :-)

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 21:44             ` Pavel Roskin
@ 2009-06-22 22:43               ` Robert Millan
  2009-06-23  0:53                 ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 22:43 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 05:44:43PM -0400, Pavel Roskin wrote:
> On Mon, 2009-06-22 at 23:32 +0200, Robert Millan wrote:
> > On Mon, Jun 22, 2009 at 10:52:13PM +0200, Robert Millan wrote:
> > > I don't think it's possible to use relative addresses
> > > with this particular instruction.
> > 
> > Uhm sorry, this was silly.  Of course you can use addresses relative to a
> > segment in lgdt, but this doesn't change the fact that GAS always gives
> > you absolute ones.
> > 
> > Also, I'm not sure if it's possible to use a 16-bit field in this instruction,
> > it could be that the field is always 32-bit, even if it's relative to a
> > segment.  This dump is from the i386-pc kernel.img:
> > 
> >     836f:       2e 67 66 0f 01 15 68    addr32 lgdtl %cs:0x8368
> >     8376:       83 00 00 
> > 
> > a little-endian 0x00008368 is seen here, indicating the field is 32-bit.
> 
> But if I omit ADDR32, I get:
> 
> 0000016e <real_to_prot>:
>  16e:   fa                      cli    
>  16f:   2e 66 0f 01 16 68 01    lgdtl  %cs:0x168
>  176:   0f 20 c0                mov    %cr0,%eax
> 
> The address is 16-bit.

If I omit ADDR32 on i386-pc, I get:

    836f:       2e 66 0f 01 16 68 83    lgdtl  %cs:-0x7c98

"-0x7c98" being the signed version of 0x8368, which is also 16-bit.  What is
really odd is that you got 0x168 which is an offset to 0x8200, when in fact
%cs is 0, so I don't think your binary would work (did you test it?).

Btw my binutils version is 2.18.0.20080103.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-22 19:51       ` does module area require alignment? (Re: [PATCH] i386-qemu port) Pavel Roskin
@ 2009-06-22 22:50         ` Vladimir 'phcoder' Serbinenko
  2009-06-23  0:10           ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-06-22 22:50 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1850 bytes --]

On Mon, Jun 22, 2009 at 9:51 PM, Pavel Roskin <proski@gnu.org> wrote:

> On Sun, 2009-06-21 at 21:33 +0200, Robert Millan wrote:
> > On Sun, Jun 21, 2009 at 03:08:19PM -0400, Pavel Roskin wrote:
> > > On Sun, 2009-06-21 at 20:50 +0200, Robert Millan wrote:
> > >
> > > > Does anyone know why do we align ELF targets?  When I did the
> coreboot port,
> > > > the ELF part was based on existing Ieee1275 code, so I guess I just
> mimicked
> > > > it.  Is there some issue with non-i386 CPUs or with some Ieee1275
> > > > implementations that makes this alignment a requirement?
> > >
> > > It was a hack for PowerPC openfirmware.  I don't know why it was
> needed.
> > > I didn't have time and desire to debug openfirmware to find out what it
> > > wants.
> >
> > Is the hack you're referring to GRUB_MOD_GAP, GRUB_MOD_ALIGN or both?
>
> I'm referring to GRUB_MOD_GAP.
>
> > Btw, I suspect GRUB_MOD_GAP might be related to the modules overlapping
> with
> > the BSS because of a firmware loader bug.  Is there a correlation between
> > the needed GRUB_MOD_GAP and the BSS size?
>
> I don't see any correlation.
>
> I made 3 images with the gap of 0x4000, 0x8000 and 0xc000.  Then I added
> an uninitialized array to the kernel, 0x4000 bytes long, and made
> another 3 images with the same gap sizes.  The images with the 0x4000
> gap don't boot and the images with the gap sized 0x8000 and 0xc000 boot
> regardless of the array.

Stupid question but have you ensured/checked that this array isn't optimized
out?

>
>
> That's PowerMac G3 "Blue and White".
>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git

[-- Attachment #2: Type: text/html, Size: 2840 bytes --]

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 21:36           ` Pavel Roskin
@ 2009-06-22 22:52             ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-22 22:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 05:36:22PM -0400, Pavel Roskin wrote:
> > What's the problem with removing %cs?  It's presence there is bogus.  It
> > *seems* to indicate gdtdesc is a segment-relative reference, but in fact
> > it's not, and it just happens to work because %cs was set to 0.
> 
> I just wanted to make sure we are not doing anything wrong.  I have a
> feeling that somebody with a good knowledge of assembler tricks could
> write the code to use %cs and a 16-bit address, but I don't know how to
> do it.

We *could* convert the absolute reference generated by binutils into
something relative to %cs with a combination of macros (so realmode.S
knows what's the %cs value going to be), substract _start, bitshift,
etc.

But in that case I really think the added complexity makes it unworthy.

> Anyway, your code is correct and I have no objections.  Please commit.

Committed.  Feel free to get rid of ADDR32 if you figure out a clean way
to do it :-)

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)
  2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
                   ` (7 preceding siblings ...)
  2009-06-22 15:02 ` [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port) Robert Millan
@ 2009-06-22 23:07 ` Robert Millan
  2009-06-23  1:29   ` Pavel Roskin
  8 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-22 23:07 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 413 bytes --]


This is my first "clean" (kludge-free) patch for the i386-qemu port.  It
doesn't depend on any other patch;  I send it for some final review before
checking it in.

Comments?

-- 
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."

[-- Attachment #2: qemu.diff --]
[-- Type: text/x-diff, Size: 22277 bytes --]

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

	* 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).

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 2364)
+++ conf/i386-coreboot.rmk	(working copy)
@@ -1,5 +1,8 @@
 # -*- makefile -*-
 
+GRUB_BOOT_MACHINE_LINK_ADDR	= 0xffe00
+GRUB_KERNEL_MACHINE_LINK_ADDR	= 0x8200
+
 COMMON_ASFLAGS	= -nostdinc -fno-builtin -m32
 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
 COMMON_LDFLAGS	= -m32 -nostdlib
@@ -8,9 +11,9 @@
 script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
-pkglib_PROGRAMS = kernel.img
+ifeq ($(platform), coreboot)
 
-# For kernel.img.
+pkglib_PROGRAMS += kernel.img
 kernel_img_SOURCES = kern/i386/coreboot/startup.S \
 	kern/i386/misc.S \
 	kern/i386/coreboot/init.c \
@@ -34,8 +37,51 @@
 	machine/memory.h machine/loader.h list.h handler.h command.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)
 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)
+
+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
 DEFSYMFILES += kernel_syms.lst
 
Index: kern/i386/qemu/startup.S
===================================================================
--- kern/i386/qemu/startup.S	(revision 0)
+++ kern/i386/qemu/startup.S	(revision 0)
@@ -0,0 +1,108 @@
+/*
+ *  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_TOTAL_MODULE_SIZE
+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.
+	   We will derive the rom start address and size from it.  */
+	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_KERNEL_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,71 @@
+/*
+ *  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))
+
+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))
+{
+  /* This trashes the video bios, but for now we don't use it.  */
+  if (hook (0, GRUB_BOOT_MACHINE_LINK_ADDR, GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  /* Protect boot.img, which contains the gdt.  It is mapped below 0x100000 ... */
+  if (hook (GRUB_BOOT_MACHINE_LINK_ADDR,
+	    GRUB_BOOT_MACHINE_SIZE,
+	    GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* ... and at the top of memory.  */
+  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;
+}
Index: boot/i386/qemu/boot.S
===================================================================
--- boot/i386/qemu/boot.S	(revision 0)
+++ boot/i386/qemu/boot.S	(revision 0)
@@ -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
Index: configure.ac
===================================================================
--- configure.ac	(revision 2364)
+++ 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"]) ;;
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,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
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: util/i386/pc/grub-mkimage.c
===================================================================
--- util/i386/pc/grub-mkimage.c	(revision 2364)
+++ 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
@@ -237,6 +248,8 @@
   if (num > 0xffff)
     grub_util_error ("the core image is too big");
 
+#if defined(GRUB_MACHINE_PCBIOS)
+
   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)
@@ -253,13 +266,49 @@
   free (boot_img);
   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);
+
+    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
+
   *((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,6 +318,7 @@
       *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
 	= grub_cpu_to_le32 (-2);
     }
+#endif
 
   if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
     grub_util_error ("Core image is too big (%p > %p)\n",

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: does module area require alignment? (Re: [PATCH] i386-qemu port)
  2009-06-22 22:50         ` Vladimir 'phcoder' Serbinenko
@ 2009-06-23  0:10           ` Pavel Roskin
  0 siblings, 0 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-23  0:10 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 00:50 +0200, Vladimir 'phcoder' Serbinenko wrote:

>         I made 3 images with the gap of 0x4000, 0x8000 and 0xc000.
>          Then I added
>         an uninitialized array to the kernel, 0x4000 bytes long, and
>         made
>         another 3 images with the same gap sizes.  The images with the
>         0x4000
>         gap don't boot and the images with the gap sized 0x8000 and
>         0xc000 boot
>         regardless of the array.
> Stupid question but have you ensured/checked that this array isn't
> optimized out?

Yes, I checked that.

It turns out that small variables to to the .sbss section and reduce the
minimal gap side (0x8c50 and 0x8c54 are OK).  But larger arrays go to
the .bss section and don't change the gap (0x8c50 is bad, 0x8c54 is OK).

Maybe OpenFirmware is confused by the .sbss section.  I'll try a linker
script to merge .sbss into the .bss section.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-22 22:43               ` Robert Millan
@ 2009-06-23  0:53                 ` Pavel Roskin
  2009-06-23 11:02                   ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-23  0:53 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 00:43 +0200, Robert Millan wrote:

> If I omit ADDR32 on i386-pc, I get:
> 
>     836f:       2e 66 0f 01 16 68 83    lgdtl  %cs:-0x7c98
> 
> "-0x7c98" being the signed version of 0x8368, which is also 16-bit.  What is
> really odd is that you got 0x168 which is an offset to 0x8200, when in fact
> %cs is 0, so I don't think your binary would work (did you test it?).

That's because you are disassembling the linked image after relocation
and I'm disassembling the object file.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)
  2009-06-22 23:07 ` clean patch for i386-qemu port " Robert Millan
@ 2009-06-23  1:29   ` Pavel Roskin
  2009-06-23 11:38     ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-23  1:29 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 01:07 +0200, Robert Millan wrote:
> This is my first "clean" (kludge-free) patch for the i386-qemu port.  It
> doesn't depend on any other patch;  I send it for some final review before
> checking it in.

In some cases, "2" appears on the command line.  Perhaps the initial
keyboard state is not cleared.

If I use all modules, the image is too big:
grub-mkimage: error: Core image is too big (0xa8200 > 0xa0000)

If I exclude lua.mod, I can build the image, but it fails in qemu with
the message "no module name found".  Removing udf.mod helps.  Likewise,
removing several other modules helps.  I believe memory is corrupted if
there are too many modules.

Also, if "no module name found" appears, it's followed by:

Aborted. Press any key to exit.grub_exit() is not implemented.

And it appears on the new line every time a key is pressed.  I believe
grub_exit() should call grub_halt() for i386-coreboot and i386-qemu.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)
  2009-06-23  0:53                 ` Pavel Roskin
@ 2009-06-23 11:02                   ` Robert Millan
  0 siblings, 0 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-23 11:02 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 08:53:36PM -0400, Pavel Roskin wrote:
> On Tue, 2009-06-23 at 00:43 +0200, Robert Millan wrote:
> 
> > If I omit ADDR32 on i386-pc, I get:
> > 
> >     836f:       2e 66 0f 01 16 68 83    lgdtl  %cs:-0x7c98
> > 
> > "-0x7c98" being the signed version of 0x8368, which is also 16-bit.  What is
> > really odd is that you got 0x168 which is an offset to 0x8200, when in fact
> > %cs is 0, so I don't think your binary would work (did you test it?).
> 
> That's because you are disassembling the linked image after relocation
> and I'm disassembling the object file.

But it's the linked image that will be executed.  The object file is only
for ld consumption (and it doesn't contain any absolute addresses, even for
instructions that require them, because link address has not yet been
specified).

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)
  2009-06-23  1:29   ` Pavel Roskin
@ 2009-06-23 11:38     ` Robert Millan
  2009-06-23 12:13       ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-23 11:38 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 09:29:41PM -0400, Pavel Roskin wrote:
> On Tue, 2009-06-23 at 01:07 +0200, Robert Millan wrote:
> > This is my first "clean" (kludge-free) patch for the i386-qemu port.  It
> > doesn't depend on any other patch;  I send it for some final review before
> > checking it in.
> 
> In some cases, "2" appears on the command line.  Perhaps the initial
> keyboard state is not cleared.

I can't reproduce this, but we can flush the keyboard on startup.  Do you mind
if we discuss this after base qemu support is merged?

> If I use all modules, the image is too big:
> grub-mkimage: error: Core image is too big (0xa8200 > 0xa0000)

Strange, with all modules I get 0x88200.  Anyway, GRUB_MEMORY_MACHINE_UPPER
can be increased up to GRUB_BOOT_MACHINE_LINK_ADDR, this was just copied
from the coreboot port.

With GRUB_BOOT_MACHINE_LINK_ADDR (0xffe00) you should be able to fit all
of GRUB in.

Increasing it further would involve either compression or breaking the
0x100000 barrier (imposed by the Linux loader).  I think compression for
qemu is just silly, but fixing the Linux loader is not trivial (Vladimir's
memory management proposal could help on this).

> If I exclude lua.mod, I can build the image, but it fails in qemu with
> the message "no module name found".  Removing udf.mod helps.  Likewise,
> removing several other modules helps.  I believe memory is corrupted if
> there are too many modules.

I get memory corruption too.  I'll have a look.

> And it appears on the new line every time a key is pressed.  I believe
> grub_exit() should call grub_halt() for i386-coreboot and i386-qemu.

Is grub_halt() really what we want?  grub_exit() callers expect that the
user doesn't lose access to the machine when this function is invoked.

How about grub_reboot() instead?

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)
  2009-06-23 11:38     ` Robert Millan
@ 2009-06-23 12:13       ` Robert Millan
  2009-06-24  1:00         ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-23 12:13 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Jun 23, 2009 at 01:38:50PM +0200, Robert Millan wrote:
> > If I use all modules, the image is too big:
> > grub-mkimage: error: Core image is too big (0xa8200 > 0xa0000)
> 
> Strange, with all modules I get 0x88200.  Anyway, GRUB_MEMORY_MACHINE_UPPER
> can be increased up to GRUB_BOOT_MACHINE_LINK_ADDR, this was just copied
> from the coreboot port.
> 
> With GRUB_BOOT_MACHINE_LINK_ADDR (0xffe00) you should be able to fit all
> of GRUB in.
> 
> Increasing it further would involve either compression or breaking the
> 0x100000 barrier (imposed by the Linux loader).  I think compression for
> qemu is just silly, but fixing the Linux loader is not trivial (Vladimir's
> memory management proposal could help on this).

Actually, you can't step after 0xa0000 because there are I/O maps there
(there's 0xb8000 and I think other VGA stuff).

I think I'll just change the link address to 0x100000.  Then our limit is
almost 2 GiB, which gives plenty of room for a big memdisk in case user
wants that.

As for the Linux loader, I'll have to disable it on this port untill it
doesn't require that we reserve a hardcoded address for it.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)
  2009-06-23 12:13       ` Robert Millan
@ 2009-06-24  1:00         ` Robert Millan
  2009-06-24 23:10           ` [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)) Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-24  1:00 UTC (permalink / raw)
  To: The development of GRUB 2


Another solution is to just leave the modules where they are (I/O map at
top of memory), and load them directly from that location.  This allows
us to put the kernel in low memory without size problems.

However, our module loader assumes the memory that contains the ELFs is
writable (for example, grub_dl_resolve_symbols() modifies sym->st_value).

A possible solution to this could be to make grub_dl_load_core() create a
copy of the module and work on the copy.  This could even be ifdef'ed,
but I doubt the performance hit would be significant.

Another possibility could be to copy them into the heap in
grub_arch_modules_addr(), but this forces us to leak the memory that
contains them.

Or grub_arch_modules_addr() could copy them to 0x100000, but then we'd
have the beginning of the heap as limit.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-24  1:00         ` Robert Millan
@ 2009-06-24 23:10           ` Robert Millan
  2009-06-25 19:53             ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-24 23:10 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 803 bytes --]

On Wed, Jun 24, 2009 at 03:00:32AM +0200, Robert Millan wrote:
> A possible solution to this could be to make grub_dl_load_core() create a
> copy of the module and work on the copy.  This could even be ifdef'ed,
> but I doubt the performance hit would be significant.

I found a better approach;  instead of copiing the whole module, we just
need to copy the symbol tab.  A small adjustment to each of the functions
that will access it (grub_dl_resolve_symbols and
grub_arch_dl_relocate_symbols) will make them use the copy instead of
the original.

Patch attached.

-- 
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."

[-- Attachment #2: dl.diff --]
[-- Type: text/x-diff, Size: 6816 bytes --]

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

	* kern/dl.c (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr, Elf_Sym): Remove
	typedefs.
	(ELF_ST_BIND, ELF_ST_TYPE): Remove macros.

	* include/grub/elf.h (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr)
	(Elf_Sym, ELF_ST_BIND, ELF_ST_TYPE): New macros.

	* efiemu/loadcore64.c: Include `<grub/elf.h>'.
	(Elf_Word, Elf_Ehdr, Elf_Shdr, Elf_Sym, ELF_ST_BIND)
	(ELF_ST_TYPE): Undefine macros for native word length
	so that they can be redefined afterwards.
	* efiemu/loadcore32.c: Likewise.


	* include/grub/dl.h: Include `<grub/elf.h>'.
	(struct grub_dl): Add `symtab' member.

	* kern/dl.c (grub_dl_resolve_symbols): Copy symbol table to
	`mod->symtab', and use the copied structure for further writes
	rather than the original.

	* kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Initialize
	`symtab' using `mod->symtab'.
	* kern/sparc64/dl.c: Likewise.
	* kern/i386/dl.c: Likewise.
	* kern/x86_64/dl.c: Likewise.

Index: kern/powerpc/dl.c
===================================================================
--- kern/powerpc/dl.c	(revision 2358)
+++ kern/powerpc/dl.c	(working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+  symtab = mod->symtab;
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/dl.c
===================================================================
--- kern/dl.c	(revision 2358)
+++ kern/dl.c	(working copy)
@@ -29,30 +29,6 @@
 #include <grub/env.h>
 #include <grub/cache.h>
 
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF32_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF32_ST_TYPE (val)
-
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
-
-#endif
-
 \f
 
 struct grub_dl_list
@@ -333,9 +309,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
 
-  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
   size = s->sh_size;
   entsize = s->sh_entsize;
+  mod->symtab = grub_malloc (size);
+  memcpy (mod->symtab, (char *) e + s->sh_offset, size);
+  sym = mod->symtab;
 
   s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
   str = (char *) e + s->sh_offset;
@@ -695,6 +673,7 @@ grub_dl_unload (grub_dl_t mod)
     }
 
   grub_free (mod->name);
+  grub_free (mod->symtab);
   grub_free (mod);
   return 1;
 }
Index: kern/sparc64/dl.c
===================================================================
--- kern/sparc64/dl.c	(revision 2358)
+++ kern/sparc64/dl.c	(working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+  symtab = mod->symtab;
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: kern/i386/dl.c
===================================================================
--- kern/i386/dl.c	(revision 2358)
+++ kern/i386/dl.c	(working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+  symtab = mod->symtab;
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/x86_64/dl.c
===================================================================
--- kern/x86_64/dl.c	(revision 2358)
+++ kern/x86_64/dl.c	(working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+  symtab = mod->symtab;
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: efiemu/loadcore64.c
===================================================================
--- efiemu/loadcore64.c	(revision 2358)
+++ efiemu/loadcore64.c	(working copy)
@@ -18,6 +18,15 @@
  */
 
 #define SUFFIX(x) x ## 64
+
+#include <grub/elf.h>
+#undef Elf_Ehdr
+#undef Elf_Shdr
+#undef Elf_Sym
+#undef Elf_Word
+#undef ELF_ST_TYPE
+#undef ELF_ST_BIND
+
 #define Elf_Ehdr Elf64_Ehdr
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Sym Elf64_Sym
Index: efiemu/loadcore32.c
===================================================================
--- efiemu/loadcore32.c	(revision 2358)
+++ efiemu/loadcore32.c	(working copy)
@@ -18,10 +18,20 @@
  */
 
 #define SUFFIX(x) x ## 32
+
+#include <grub/elf.h>
+#undef Elf_Ehdr
+#undef Elf_Shdr
+#undef Elf_Sym
+#undef Elf_Word
+#undef ELF_ST_TYPE
+#undef ELF_ST_BIND
+
 #define Elf_Ehdr Elf32_Ehdr
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Word Elf32_Word
 #define ELF_ST_TYPE ELF32_ST_TYPE
 #define ELF_ST_BIND ELF32_ST_BIND
+
 #include "loadcore.c"
Index: include/grub/elf.h
===================================================================
--- include/grub/elf.h	(revision 2358)
+++ include/grub/elf.h	(working copy)
@@ -2330,4 +2330,28 @@ typedef Elf32_Addr Elf32_Conflict;
 
 #define R_X86_64_NUM		24
 
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+
+#define Elf_Word Elf32_Word
+#define Elf_Addr Elf32_Addr
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+
+# define ELF_ST_BIND(val)	ELF32_ST_BIND (val)
+# define ELF_ST_TYPE(val)	ELF32_ST_TYPE (val)
+
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+
+#define Elf_Word Elf64_Word
+#define Elf_Addr Elf64_Addr
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+
+# define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
+# define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
+
+#endif
+
 #endif /* ! GRUB_ELF_H */
Index: include/grub/dl.h
===================================================================
--- include/grub/dl.h	(revision 2358)
+++ include/grub/dl.h	(working copy)
@@ -23,6 +23,7 @@
 #include <grub/symbol.h>
 #include <grub/err.h>
 #include <grub/types.h>
+#include <grub/elf.h>
 
 #define GRUB_MOD_INIT(name)	\
 static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
@@ -78,6 +79,7 @@ struct grub_dl
   int ref_count;
   grub_dl_dep_t dep;
   grub_dl_segment_t segment;
+  Elf_Sym *symtab;
   void (*init) (struct grub_dl *mod);
   void (*fini) (void);
 };

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-24 23:10           ` [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)) Robert Millan
@ 2009-06-25 19:53             ` Pavel Roskin
  2009-06-25 20:31               ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-25 19:53 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, 2009-06-25 at 01:10 +0200, Robert Millan wrote:
> On Wed, Jun 24, 2009 at 03:00:32AM +0200, Robert Millan wrote:
> > A possible solution to this could be to make grub_dl_load_core() create a
> > copy of the module and work on the copy.  This could even be ifdef'ed,
> > but I doubt the performance hit would be significant.
> 
> I found a better approach;  instead of copiing the whole module, we just
> need to copy the symbol tab.  A small adjustment to each of the functions
> that will access it (grub_dl_resolve_symbols and
> grub_arch_dl_relocate_symbols) will make them use the copy instead of
> the original.

Massive use of undef seems inelegant.  Maybe it's better to use
distinctive names instead, e.g. target_Elf_Ehdr v.s. host_Elf_Ehdr?

Also, I'm getting many warnings on i386-pc about redefined Elf_Ehdr when
compiling on x86_64.

Generally, I like the idea for i386-qemu, but for other architectures,
the only change is the increased memory consumption.  I would be willing
to accept this change if you could suggest some universal benefit for
all platforms.

Otherwise, it would be better to use wrappers like get_header() and
put_header() what would do grub_malloc() and grub_free() only if needed
and return the original header otherwise.

I'm fine with adding the symtab field unconditionally, it doesn't cost
much memory.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-25 19:53             ` Pavel Roskin
@ 2009-06-25 20:31               ` Robert Millan
  2009-06-25 20:51                 ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-25 20:31 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, Jun 25, 2009 at 03:53:28PM -0400, Pavel Roskin wrote:
> On Thu, 2009-06-25 at 01:10 +0200, Robert Millan wrote:
> > On Wed, Jun 24, 2009 at 03:00:32AM +0200, Robert Millan wrote:
> > > A possible solution to this could be to make grub_dl_load_core() create a
> > > copy of the module and work on the copy.  This could even be ifdef'ed,
> > > but I doubt the performance hit would be significant.
> > 
> > I found a better approach;  instead of copiing the whole module, we just
> > need to copy the symbol tab.  A small adjustment to each of the functions
> > that will access it (grub_dl_resolve_symbols and
> > grub_arch_dl_relocate_symbols) will make them use the copy instead of
> > the original.
> 
> Massive use of undef seems inelegant.  Maybe it's better to use
> distinctive names instead, e.g. target_Elf_Ehdr v.s. host_Elf_Ehdr?

You mean for efiemu?  Seems fine.  But I wouldn't use "target/host"
naming, since it doesn't match with existing usage of those names
elsewhere, which makes it very confusing.

How about "native/cross"?

> Also, I'm getting many warnings on i386-pc about redefined Elf_Ehdr when
> compiling on x86_64.

I'll have a look.

> Generally, I like the idea for i386-qemu, but for other architectures,
> the only change is the increased memory consumption.  I would be willing
> to accept this change if you could suggest some universal benefit for
> all platforms.
> 
> Otherwise, it would be better to use wrappers like get_header() and
> put_header() what would do grub_malloc() and grub_free() only if needed
> and return the original header otherwise.
> 
> I'm fine with adding the symtab field unconditionally, it doesn't cost
> much memory.

I agree there's no point in making all architectures do this.  However,
note that we'll probably see more architectures with read-only modules
in the future (other qemu ports, but also any port where GRUB runs
standalone).

I was thinking that we could just #ifdef the symtab allocation (and the
symtab field declaration as well).  Since it's just a few lines, I think
it'll look readable.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-25 20:31               ` Robert Millan
@ 2009-06-25 20:51                 ` Pavel Roskin
  2009-06-26 14:41                   ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-25 20:51 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, 2009-06-25 at 22:31 +0200, Robert Millan wrote:

> You mean for efiemu?  Seems fine.  But I wouldn't use "target/host"
> naming, since it doesn't match with existing usage of those names
> elsewhere, which makes it very confusing.
> 
> How about "native/cross"?

Fine with me.  Whatever is meaningful.

> I agree there's no point in making all architectures do this.  However,
> note that we'll probably see more architectures with read-only modules
> in the future (other qemu ports, but also any port where GRUB runs
> standalone).
> 
> I was thinking that we could just #ifdef the symtab allocation (and the
> symtab field declaration as well).  Since it's just a few lines, I think
> it'll look readable.

I'd like to avoid preprocessor conditionals in kern/ARCH/dl.c files if
possible.  There is no harm in keeping mod->symtab and using it instead
of the local "symtab" variables.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-25 20:51                 ` Pavel Roskin
@ 2009-06-26 14:41                   ` Robert Millan
  2009-06-26 16:44                     ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-26 14:41 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 703 bytes --]

On Thu, Jun 25, 2009 at 04:51:11PM -0400, Pavel Roskin wrote:
> 
> I'd like to avoid preprocessor conditionals in kern/ARCH/dl.c files if
> possible.

Alright, here's a new patch.  It follows your earlier suggestion to use
a wrapper to obtain the initialization address for symtab.  This way we
don't put any ifdefs in kern/ARCH/dl.c files.

I also avoid the #undefs in efiemu.  This required many changes in
loadcore.c, but they're just a sed search & replace run.

-- 
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."

[-- Attachment #2: dl.diff --]
[-- Type: text/x-diff, Size: 14580 bytes --]

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

	* kern/dl.c (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr, Elf_Sym): Remove
	typedefs.
	(ELF_ST_BIND, ELF_ST_TYPE): Remove macros.
	* include/grub/elf.h (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr)
	(Elf_Sym, ELF_ST_BIND, ELF_ST_TYPE): New macros.

	* efiemu/loadcore64.c: Include `<grub/elf.h>'.
	(Elf_Word, Elf_Ehdr, Elf_Shdr, Elf_Sym, ELF_ST_BIND)
	(ELF_ST_TYPE): Rename to ...
	(ElfW_Word, ElfW_Ehdr, ElfW_Shdr, ElfW_Sym, ELFW_ST_BIND)
	(ELFW_ST_TYPE): ... this.  Update all users.
	* efiemu/loadcore32.c: Likewise.

	* include/grub/dl.h: Include `<grub/elf.h>' and
	`<grub/machine/machine.h>'.
	[GRUB_MACHINE_QEMU] (GRUB_MODULES_MACHINE_READONLY): New macro.
	[GRUB_MODULES_MACHINE_READONLY] (struct grub_dl): Add `symtab' member.
	(get_symtab): New macro.

	* kern/dl.c [GRUB_MODULES_MACHINE_READONLY]
	(grub_dl_resolve_symbols): Copy symbol table to `mod->symtab', and use
	the copied structure for further writes	rather than the original.

	* kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Initialize
	`symtab' using get_symtab().
	* kern/sparc64/dl.c: Likewise.
	* kern/i386/dl.c: Likewise.
	* kern/x86_64/dl.c: Likewise.

Index: kern/powerpc/dl.c
===================================================================
--- kern/powerpc/dl.c	(revision 2358)
+++ kern/powerpc/dl.c	(working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/dl.c
===================================================================
--- kern/dl.c	(revision 2358)
+++ kern/dl.c	(working copy)
@@ -1,7 +1,7 @@
 /* dl.c - loadable module support */
 /*
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -29,30 +29,6 @@
 #include <grub/env.h>
 #include <grub/cache.h>
 
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF32_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF32_ST_TYPE (val)
-
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
-
-#endif
-
 \f
 
 struct grub_dl_list
@@ -333,9 +309,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, 
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
 
-  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
   size = s->sh_size;
   entsize = s->sh_entsize;
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  mod->symtab = grub_malloc (size);
+  memcpy (mod->symtab, (char *) e + s->sh_offset, size);
+#endif
+  sym = get_symtab ();
 
   s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
   str = (char *) e + s->sh_offset;
@@ -695,6 +675,9 @@ grub_dl_unload (grub_dl_t mod)
     }
 
   grub_free (mod->name);
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  grub_free (mod->symtab);
+#endif
   grub_free (mod);
   return 1;
 }
Index: kern/sparc64/dl.c
===================================================================
--- kern/sparc64/dl.c	(revision 2358)
+++ kern/sparc64/dl.c	(working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: kern/i386/dl.c
===================================================================
--- kern/i386/dl.c	(revision 2358)
+++ kern/i386/dl.c	(working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/x86_64/dl.c
===================================================================
--- kern/x86_64/dl.c	(revision 2358)
+++ kern/x86_64/dl.c	(working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: efiemu/loadcore64.c
===================================================================
--- efiemu/loadcore64.c	(revision 2358)
+++ efiemu/loadcore64.c	(working copy)
@@ -18,10 +18,14 @@
  */
 
 #define SUFFIX(x) x ## 64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Word Elf64_Word
-#define ELF_ST_TYPE ELF64_ST_TYPE
-#define ELF_ST_BIND ELF64_ST_BIND
+
+#include <grub/elf.h>
+
+#define ElfW_Ehdr	Elf64_Ehdr
+#define ElfW_Shdr	Elf64_Shdr
+#define ElfW_Sym	Elf64_Sym
+#define ElfW_Word	Elf64_Word
+#define ELFW_ST_TYPE	ELF64_ST_TYPE
+#define ELFW_ST_BIND	ELF64_ST_BIND
+
 #include "loadcore.c"
Index: efiemu/loadcore.c
===================================================================
--- efiemu/loadcore.c	(revision 2358)
+++ efiemu/loadcore.c	(working copy)
@@ -59,10 +59,10 @@ SUFFIX (grub_efiemu_loadcore_unload) (vo
 int
 SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
 {
-  Elf_Ehdr *e = ehdr;
+  ElfW_Ehdr *e = ehdr;
 
   /* Check the header size.  */
-  if (size < sizeof (Elf_Ehdr))
+  if (size < sizeof (ElfW_Ehdr))
     return 0;
 
   /* Check the magic numbers.  */
@@ -80,16 +80,16 @@ SUFFIX (grub_efiemu_check_header) (void 
 
 /* Load all segments from memory specified by E.  */
 static grub_err_t
-grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
+grub_efiemu_load_segments (grub_efiemu_segment_t segs, const ElfW_Ehdr *e)
 {
-  Elf_Shdr *s;
+  ElfW_Shdr *s;
   grub_efiemu_segment_t cur;
 
   grub_dprintf ("efiemu", "loading segments\n");
 
   for (cur=segs; cur; cur = cur->next)
     {
-      s = (Elf_Shdr *)cur->srcptr;
+      s = (ElfW_Shdr *)cur->srcptr;
 
       if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
 	{
@@ -115,14 +115,14 @@ grub_efiemu_load_segments (grub_efiemu_s
 
 /* Get a string at offset OFFSET from strtab */
 static char *
-grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
+grub_efiemu_get_string (unsigned offset, const ElfW_Ehdr *e)
 {
   unsigned i;
-  Elf_Shdr *s;
+  ElfW_Shdr *s;
 
-  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+  for (i = 0, s = (ElfW_Shdr *)((char *) e + e->e_shoff);
        i < e->e_shnum;
-       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+       i++, s = (ElfW_Shdr *)((char *) s + e->e_shentsize))
     if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
       return (char *) e + s->sh_offset + offset;
   return 0;
@@ -130,14 +130,14 @@ grub_efiemu_get_string (unsigned offset,
 
 /* Request memory for segments and fill segments info */
 static grub_err_t
-grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
+grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const ElfW_Ehdr *e)
 {
   unsigned i;
-  Elf_Shdr *s;
+  ElfW_Shdr *s;
 
-  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+  for (i = 0, s = (ElfW_Shdr *)((char *) e + e->e_shoff);
        i < e->e_shnum;
-       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+       i++, s = (ElfW_Shdr *)((char *) s + e->e_shentsize))
     {
       if (s->sh_flags & SHF_ALLOC)
 	{
@@ -180,16 +180,16 @@ grub_efiemu_init_segments (grub_efiemu_s
 
 /* Count symbols and relocators and allocate/request memory for them */
 static grub_err_t
-grub_efiemu_count_symbols (const Elf_Ehdr *e)
+grub_efiemu_count_symbols (const ElfW_Ehdr *e)
 {
   unsigned i;
-  Elf_Shdr *s;
+  ElfW_Shdr *s;
   int num = 0;
 
   /* Symbols */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+  for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
        i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+       i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
     if (s->sh_type == SHT_SYMTAB)
       break;
 
@@ -201,9 +201,9 @@ grub_efiemu_count_symbols (const Elf_Ehd
     grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
 
   /* Relocators */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+  for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
        i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+       i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
     if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
       num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);
 
@@ -214,38 +214,38 @@ grub_efiemu_count_symbols (const Elf_Ehd
 
 /* Fill grub_efiemu_elfsyms with symbol values */
 static grub_err_t
-grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
+grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, ElfW_Ehdr *e)
 {
   unsigned i;
-  Elf_Shdr *s;
-  Elf_Sym *sym;
+  ElfW_Shdr *s;
+  ElfW_Sym *sym;
   const char *str;
-  Elf_Word size, entsize;
+  ElfW_Word size, entsize;
 
   grub_dprintf ("efiemu", "resolving symbols\n");
 
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+  for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
        i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+       i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
     if (s->sh_type == SHT_SYMTAB)
       break;
 
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
 
-  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
+  sym = (ElfW_Sym *) ((char *) e + s->sh_offset);
   size = s->sh_size;
   entsize = s->sh_entsize;
 
-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+  s = (ElfW_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
   str = (char *) e + s->sh_offset;
 
   for (i = 0;
        i < size / entsize;
-       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+       i++, sym = (ElfW_Sym *) ((char *) sym + entsize))
     {
-      unsigned char type = ELF_ST_TYPE (sym->st_info);
-      unsigned char bind = ELF_ST_BIND (sym->st_info);
+      unsigned char type = ELFW_ST_TYPE (sym->st_info);
+      unsigned char bind = ELFW_ST_BIND (sym->st_info);
       int handle;
       grub_off_t off;
       grub_err_t err;
@@ -325,7 +325,7 @@ grub_err_t
 SUFFIX (grub_efiemu_loadcore_init) (void *core, grub_size_t core_size,
 				    grub_efiemu_segment_t *segments)
 {
-  Elf_Ehdr *e = (Elf_Ehdr *) core;
+  ElfW_Ehdr *e = (ElfW_Ehdr *) core;
   grub_err_t err;
 
   if (e->e_type != ET_REL)
Index: efiemu/loadcore32.c
===================================================================
--- efiemu/loadcore32.c	(revision 2358)
+++ efiemu/loadcore32.c	(working copy)
@@ -18,10 +18,14 @@
  */
 
 #define SUFFIX(x) x ## 32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Word Elf32_Word
-#define ELF_ST_TYPE ELF32_ST_TYPE
-#define ELF_ST_BIND ELF32_ST_BIND
+
+#include <grub/elf.h>
+
+#define ElfW_Ehdr	Elf32_Ehdr
+#define ElfW_Shdr	Elf32_Shdr
+#define ElfW_Sym	Elf32_Sym
+#define ElfW_Word	Elf32_Word
+#define ELFW_ST_TYPE	ELF32_ST_TYPE
+#define ELFW_ST_BIND	ELF32_ST_BIND
+
 #include "loadcore.c"
Index: include/grub/elf.h
===================================================================
--- include/grub/elf.h	(revision 2358)
+++ include/grub/elf.h	(working copy)
@@ -1,5 +1,5 @@
 /* This file defines standard ELF types, structures, and macros.
-   Copyright (C) 1995-1999, 2000, 2001, 2002,2008 Free Software Foundation, Inc.
+   Copyright (C) 1995-1999,2000,2001,2002,2008,2009 Free Software Foundation, Inc.
    This file was part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -2330,4 +2330,28 @@ typedef Elf32_Addr Elf32_Conflict;
 
 #define R_X86_64_NUM		24
 
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+
+#define Elf_Word Elf32_Word
+#define Elf_Addr Elf32_Addr
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+
+# define ELF_ST_BIND(val)	ELF32_ST_BIND (val)
+# define ELF_ST_TYPE(val)	ELF32_ST_TYPE (val)
+
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+
+#define Elf_Word Elf64_Word
+#define Elf_Addr Elf64_Addr
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+
+# define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
+# define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
+
+#endif
+
 #endif /* ! GRUB_ELF_H */
Index: include/grub/dl.h
===================================================================
--- include/grub/dl.h	(revision 2358)
+++ include/grub/dl.h	(working copy)
@@ -1,7 +1,7 @@
 /* dl.h - types and prototypes for loadable module support */
 /*
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -23,6 +23,13 @@
 #include <grub/symbol.h>
 #include <grub/err.h>
 #include <grub/types.h>
+#include <grub/elf.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
 
 #define GRUB_MOD_INIT(name)	\
 static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
@@ -78,6 +85,12 @@ struct grub_dl
   int ref_count;
   grub_dl_dep_t dep;
   grub_dl_segment_t segment;
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  Elf_Sym *symtab;
+#define get_symtab()	mod->symtab
+#else
+#define get_symtab()	((Elf_Sym *) ((char *) e + s->sh_offset))
+#endif
   void (*init) (struct grub_dl *mod);
   void (*fini) (void);
 };

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 14:41                   ` Robert Millan
@ 2009-06-26 16:44                     ` Pavel Roskin
  2009-06-26 17:03                       ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-26 16:44 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

On Fri, 2009-06-26 at 16:41 +0200, Robert Millan wrote:
> On Thu, Jun 25, 2009 at 04:51:11PM -0400, Pavel Roskin wrote:
> > 
> > I'd like to avoid preprocessor conditionals in kern/ARCH/dl.c files if
> > possible.
> 
> Alright, here's a new patch.  It follows your earlier suggestion to use
> a wrapper to obtain the initialization address for symtab.  This way we
> don't put any ifdefs in kern/ARCH/dl.c files.
> 
> I also avoid the #undefs in efiemu.  This required many changes in
> loadcore.c, but they're just a sed search & replace run.

More redefinitions are needed to make all platforms compile.  At this
point I think maybe we should try something less intrusive.  But anyway,
02-elf-renames.patch contains those renames.

03-simple-symtab.patch simplifies the logic in kern/ARCH/dl.c files.

-- 
Regards,
Pavel Roskin

[-- Attachment #2: 02-elf-renames.patch --]
[-- Type: text/x-patch, Size: 29661 bytes --]

More elf definitions changed.

From: Pavel Roskin <proski@gnu.org>

Use ElfT in grub-mkelfimage, ElfK in loaders.
---

 loader/i386/bsd32.c           |    6 -
 loader/i386/bsd64.c           |    6 -
 loader/i386/bsdXX.c           |   44 +++--
 loader/i386/multiboot_elfxx.c |   18 +-
 util/i386/efi/grub-mkimage.c  |  344 +++++++++++++++++++++--------------------
 5 files changed, 209 insertions(+), 209 deletions(-)


diff --git a/loader/i386/bsd32.c b/loader/i386/bsd32.c
index 24dab6c..cf3e958 100644
--- a/loader/i386/bsd32.c
+++ b/loader/i386/bsd32.c
@@ -1,7 +1,7 @@
 #define SUFFIX(x) x ## 32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
+#define ElfK_Ehdr Elf32_Ehdr
+#define ElfK_Shdr Elf32_Shdr
+#define ElfK_Sym Elf32_Sym
 #define OBJSYM 0
 #include <grub/types.h>
 typedef grub_uint32_t grub_freebsd_addr_t;
diff --git a/loader/i386/bsd64.c b/loader/i386/bsd64.c
index f4ff8b2..514006f 100644
--- a/loader/i386/bsd64.c
+++ b/loader/i386/bsd64.c
@@ -1,7 +1,7 @@
 #define SUFFIX(x) x ## 64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
+#define ElfK_Ehdr Elf64_Ehdr
+#define ElfK_Shdr Elf64_Shdr
+#define ElfK_Sym Elf64_Sym
 #define OBJSYM 1
 #include <grub/types.h>
 typedef grub_uint64_t grub_freebsd_addr_t;
diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c
index 3f15579..4f67fb3 100644
--- a/loader/i386/bsdXX.c
+++ b/loader/i386/bsdXX.c
@@ -27,7 +27,7 @@ load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
 }
 
 static inline grub_err_t
-read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr)
+read_headers (grub_file_t file, ElfK_Ehdr *e, char **shdr)
 {
  if (grub_file_seek (file, 0) == (grub_off_t) -1)
     return grub_errno;
@@ -78,8 +78,8 @@ grub_err_t
 SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
 					  char *argv[], grub_addr_t *kern_end)
 {
-  Elf_Ehdr e;
-  Elf_Shdr *s;
+  ElfK_Ehdr e;
+  ElfK_Shdr *s;
   char *shdr;
   grub_addr_t curload, module;
   grub_err_t err;
@@ -90,9 +90,9 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
 
   curload = module = ALIGN_PAGE (*kern_end);
 
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
-						+ e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+  for (s = (ElfK_Shdr *) shdr; s < (ElfK_Shdr *) ((char *) shdr +
+						  e.e_shnum * e.e_shentsize);
+       s = (ElfK_Shdr *) ((char *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
 	continue;
@@ -146,8 +146,8 @@ grub_err_t
 SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
 				      grub_addr_t *kern_end)
 {
-  Elf_Ehdr e;
-  Elf_Shdr *s;
+  ElfK_Ehdr e;
+  ElfK_Shdr *s;
   char *shdr;
   grub_addr_t curload, module;
   grub_err_t err;
@@ -158,9 +158,9 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
 
   curload = module = ALIGN_PAGE (*kern_end);
 
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
-						+ e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+  for (s = (ElfK_Shdr *) shdr; s < (ElfK_Shdr *) ((char *) shdr +
+						  e.e_shnum * e.e_shentsize);
+       s = (ElfK_Shdr *) ((char *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
 	continue;
@@ -221,13 +221,13 @@ grub_err_t
 SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
 {
   grub_err_t err;
-  Elf_Ehdr e;
-  Elf_Shdr *s;
+  ElfK_Ehdr e;
+  ElfK_Shdr *s;
   char *shdr;
   unsigned symoff, stroff, symsize, strsize;
   grub_addr_t curload;
   grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
-  Elf_Sym *sym;
+  ElfK_Sym *sym;
   const char *str;
   unsigned i;
 
@@ -241,18 +241,18 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
   if (err)
     return err;
 
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
-						+ e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+  for (s = (ElfK_Shdr *) shdr; s < (ElfK_Shdr *) (shdr +
+						  e.e_shnum * e.e_shentsize);
+       s = (ElfK_Shdr *) ((char *) s + e.e_shentsize))
       if (s->sh_type == SHT_SYMTAB)
 	break;
-  if (s >= (Elf_Shdr *) ((char *) shdr
-			+ e.e_shnum * e.e_shentsize))
+  if (s >= (ElfK_Shdr *) ((char *) shdr +
+			  e.e_shnum * e.e_shentsize))
     return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
   symoff = s->sh_offset;
   symsize = s->sh_size;
   symentsize = s->sh_entsize;
-  s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
+  s = (ElfK_Shdr *) (shdr + e.e_shentsize * s->sh_link);
   stroff = s->sh_offset;
   strsize = s->sh_size;
 
@@ -266,7 +266,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
   curload += sizeof (grub_freebsd_addr_t);
   if (grub_file_seek (file, symoff) == (grub_off_t) -1)
     return grub_errno;
-  sym = (Elf_Sym *) UINT_TO_PTR (curload);
+  sym = (ElfK_Sym *) UINT_TO_PTR (curload);
   if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
       (grub_ssize_t) symsize)
     {
@@ -294,7 +294,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
 
   for (i = 0;
        i * symentsize < symsize;
-       i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
+       i++, sym = (ElfK_Sym *) ((char *) sym + symentsize))
     {
       const char *name = str + sym->st_name;
       if (grub_strcmp (name, "_DYNAMIC") == 0)
diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c
index 77c4711..732c90f 100644
--- a/loader/i386/multiboot_elfxx.c
+++ b/loader/i386/multiboot_elfxx.c
@@ -20,14 +20,14 @@
 # define XX		32
 # define E_MACHINE	EM_386
 # define ELFCLASSXX	ELFCLASS32
-# define Elf_Ehdr	Elf32_Ehdr
-# define Elf_Phdr	Elf32_Phdr
+# define ElfK_Ehdr	Elf32_Ehdr
+# define ElfK_Phdr	Elf32_Phdr
 #elif defined(MULTIBOOT_LOAD_ELF64)
 # define XX		64
 # define E_MACHINE	EM_X86_64
 # define ELFCLASSXX	ELFCLASS64
-# define Elf_Ehdr	Elf64_Ehdr
-# define Elf_Phdr	Elf64_Phdr
+# define ElfK_Ehdr	Elf64_Ehdr
+# define ElfK_Phdr	Elf64_Phdr
 #else
 #error "I'm confused"
 #endif
@@ -39,7 +39,7 @@
 static int
 CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
 {
-  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+  ElfK_Ehdr *ehdr = (ElfK_Ehdr *) buffer;
 
   return ehdr->e_ident[EI_CLASS] == ELFCLASSXX;
 }
@@ -47,7 +47,7 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
 static grub_err_t
 CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
 {
-  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+  ElfK_Ehdr *ehdr = (ElfK_Ehdr *) buffer;
   char *phdr_base;
   int lowest_segment = -1, highest_segment = -1;
   int i;
@@ -78,7 +78,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
 #endif
 
   phdr_base = (char *) buffer + ehdr->e_phoff;
-#define phdr(i)			((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+#define phdr(i)			((ElfK_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
 
   for (i = 0; i < ehdr->e_phnum; i++)
     if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
@@ -151,5 +151,5 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
 #undef XX
 #undef E_MACHINE
 #undef ELFCLASSXX
-#undef Elf_Ehdr
-#undef Elf_Phdr
+#undef ElfK_Ehdr
+#undef ElfK_Phdr
diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c
index 2813e79..2ab25f3 100644
--- a/util/i386/efi/grub-mkimage.c
+++ b/util/i386/efi/grub-mkimage.c
@@ -33,39 +33,39 @@
 
 #if GRUB_TARGET_SIZEOF_VOID_P == 4
 
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-typedef Elf32_Half Elf_Half;
-typedef Elf32_Off Elf_Off;
-typedef Elf32_Section Elf_Section;
-typedef Elf32_Rel Elf_Rel;
-typedef Elf32_Rela Elf_Rela;
-
-#define ELF_R_SYM	ELF32_R_SYM
-#define ELF_R_TYPE	ELF32_R_TYPE
-#define ELF_R_INFO	ELF32_R_INFO
+typedef Elf32_Word ElfT_Word;
+typedef Elf32_Addr ElfT_Addr;
+typedef Elf32_Ehdr ElfT_Ehdr;
+typedef Elf32_Shdr ElfT_Shdr;
+typedef Elf32_Sym ElfT_Sym;
+typedef Elf32_Half ElfT_Half;
+typedef Elf32_Off ElfT_Off;
+typedef Elf32_Section ElfT_Section;
+typedef Elf32_Rel ElfT_Rel;
+typedef Elf32_Rela ElfT_Rela;
+
+#define ELFT_R_SYM	ELF32_R_SYM
+#define ELFT_R_TYPE	ELF32_R_TYPE
+#define ELFT_R_INFO	ELF32_R_INFO
 
 #define grub_le_to_cpu	grub_le_to_cpu32
 
 #elif GRUB_TARGET_SIZEOF_VOID_P == 8
 
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-typedef Elf64_Half Elf_Half;
-typedef Elf64_Off Elf_Off;
-typedef Elf64_Section Elf_Section;
-typedef Elf64_Rel Elf_Rel;
-typedef Elf64_Rela Elf_Rela;
-
-#define ELF_R_SYM	ELF64_R_SYM
-#define ELF_R_TYPE	ELF64_R_TYPE
-#define ELF_R_INFO	ELF64_R_INFO
+typedef Elf64_Word ElfT_Word;
+typedef Elf64_Addr ElfT_Addr;
+typedef Elf64_Ehdr ElfT_Ehdr;
+typedef Elf64_Shdr ElfT_Shdr;
+typedef Elf64_Sym ElfT_Sym;
+typedef Elf64_Half ElfT_Half;
+typedef Elf64_Off ElfT_Off;
+typedef Elf64_Section ElfT_Section;
+typedef Elf64_Rel ElfT_Rel;
+typedef Elf64_Rela ElfT_Rela;
+
+#define ELFT_R_SYM	ELF64_R_SYM
+#define ELFT_R_TYPE	ELF64_R_TYPE
+#define ELFT_R_INFO	ELF64_R_INFO
 
 #define grub_le_to_cpu	grub_le_to_cpu64
 
@@ -73,14 +73,14 @@ typedef Elf64_Rela Elf_Rela;
 
 static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
 
-static inline Elf_Addr
-align_address (Elf_Addr addr, unsigned alignment)
+static inline ElfT_Addr
+align_address (ElfT_Addr addr, unsigned alignment)
 {
   return (addr + alignment - 1) & ~(alignment - 1);
 }
 
-static inline Elf_Addr
-align_pe32_section (Elf_Addr addr)
+static inline ElfT_Addr
+align_pe32_section (ElfT_Addr addr)
 {
   return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT);
 }
@@ -103,7 +103,7 @@ read_kernel_module (const char *dir, size_t *size)
 
 /* Return if the ELF header is valid.  */
 static int
-check_elf_header (Elf_Ehdr *e, size_t size)
+check_elf_header (ElfT_Ehdr *e, size_t size)
 {
   if (size < sizeof (*e)
       || e->e_ident[EI_MAG0] != ELFMAG0
@@ -125,7 +125,7 @@ check_elf_header (Elf_Ehdr *e, size_t size)
 /* Return the starting address right after the header,
    aligned by the section alignment. Allocate 4 section tables for
    .text, .data, .reloc, and mods.  */
-static Elf_Addr
+static ElfT_Addr
 get_starting_section_address (void)
 {
   return align_pe32_section (sizeof (struct grub_pe32_header)
@@ -135,7 +135,7 @@ get_starting_section_address (void)
 /* Determine if this section is a text section. Return false if this
    section is not allocated.  */
 static int
-is_text_section (Elf_Shdr *s)
+is_text_section (ElfT_Shdr *s)
 {
   return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC))
 	  == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC));
@@ -145,7 +145,7 @@ is_text_section (Elf_Shdr *s)
    BSS is also a data section, since the converter initializes BSS
    when producing PE32 to avoid a bug in EFI implementations.  */
 static int
-is_data_section (Elf_Shdr *s)
+is_data_section (ElfT_Shdr *s)
 {
   return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC)
 	  && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR)));
@@ -154,14 +154,14 @@ is_data_section (Elf_Shdr *s)
 /* Locate section addresses by merging code sections and data sections
    into .text and .data, respectively. Return the array of section
    addresses.  */
-static Elf_Addr *
-locate_sections (Elf_Shdr *sections, Elf_Half section_entsize,
-		 Elf_Half num_sections, const char *strtab)
+static ElfT_Addr *
+locate_sections (ElfT_Shdr *sections, ElfT_Half section_entsize,
+		 ElfT_Half num_sections, const char *strtab)
 {
   int i;
-  Elf_Addr current_address;
-  Elf_Addr *section_addresses;
-  Elf_Shdr *s;
+  ElfT_Addr current_address;
+  ElfT_Addr *section_addresses;
+  ElfT_Shdr *s;
 
   section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
   memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
@@ -171,10 +171,10 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize,
   /* .text */
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (is_text_section (s))
       {
-	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	ElfT_Word align = grub_le_to_cpu32 (s->sh_addralign);
 	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
 
 	if (align)
@@ -191,10 +191,10 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize,
   /* .data */
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (is_data_section (s))
       {
-	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	ElfT_Word align = grub_le_to_cpu32 (s->sh_addralign);
 	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
 
 	if (align)
@@ -210,16 +210,16 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize,
 }
 
 /* Return the symbol table section, if any.  */
-static Elf_Shdr *
-find_symtab_section (Elf_Shdr *sections,
-		     Elf_Half section_entsize, Elf_Half num_sections)
+static ElfT_Shdr *
+find_symtab_section (ElfT_Shdr *sections,
+		     ElfT_Half section_entsize, ElfT_Half num_sections)
 {
   int i;
-  Elf_Shdr *s;
+  ElfT_Shdr *s;
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB))
       return s;
 
@@ -228,12 +228,12 @@ find_symtab_section (Elf_Shdr *sections,
 
 /* Return the address of the string table.  */
 static const char *
-find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize)
+find_strtab (ElfT_Ehdr *e, ElfT_Shdr *sections, ElfT_Half section_entsize)
 {
-  Elf_Shdr *s;
+  ElfT_Shdr *s;
   char *strtab;
 
-  s = (Elf_Shdr *) ((char *) sections
+  s = (ElfT_Shdr *) ((char *) sections
 		      + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize);
   strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset);
   return strtab;
@@ -241,21 +241,21 @@ find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize)
 
 /* Relocate symbols; note that this function overwrites the symbol table.
    Return the address of a start symbol.  */
-static Elf_Addr
-relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections,
-		  Elf_Shdr *symtab_section, Elf_Addr *section_addresses,
-		  Elf_Half section_entsize, Elf_Half num_sections)
+static ElfT_Addr
+relocate_symbols (ElfT_Ehdr *e, ElfT_Shdr *sections,
+		  ElfT_Shdr *symtab_section, ElfT_Addr *section_addresses,
+		  ElfT_Half section_entsize, ElfT_Half num_sections)
 {
-  Elf_Word symtab_size, sym_size, num_syms;
-  Elf_Off symtab_offset;
-  Elf_Addr start_address = 0;
-  Elf_Sym *sym;
-  Elf_Word i;
-  Elf_Shdr *strtab_section;
+  ElfT_Word symtab_size, sym_size, num_syms;
+  ElfT_Off symtab_offset;
+  ElfT_Addr start_address = 0;
+  ElfT_Sym *sym;
+  ElfT_Word i;
+  ElfT_Shdr *strtab_section;
   const char *strtab;
 
   strtab_section
-    = (Elf_Shdr *) ((char *) sections
+    = (ElfT_Shdr *) ((char *) sections
 		      + (grub_le_to_cpu32 (symtab_section->sh_link)
 			 * section_entsize));
   strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset);
@@ -265,11 +265,11 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections,
   symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset);
   num_syms = symtab_size / sym_size;
 
-  for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
+  for (i = 0, sym = (ElfT_Sym *) ((char *) e + symtab_offset);
        i < num_syms;
-       i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
+       i++, sym = (ElfT_Sym *) ((char *) sym + sym_size))
     {
-      Elf_Section index;
+      ElfT_Section index;
       const char *name;
 
       name = strtab + grub_le_to_cpu32 (sym->st_name);
@@ -302,22 +302,22 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections,
 }
 
 /* Return the address of a symbol at the index I in the section S.  */
-static Elf_Addr
-get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i)
+static ElfT_Addr
+get_symbol_address (ElfT_Ehdr *e, ElfT_Shdr *s, ElfT_Word i)
 {
-  Elf_Sym *sym;
+  ElfT_Sym *sym;
 
-  sym = (Elf_Sym *) ((char *) e
+  sym = (ElfT_Sym *) ((char *) e
 		       + grub_le_to_cpu32 (s->sh_offset)
 		       + i * grub_le_to_cpu32 (s->sh_entsize));
   return sym->st_value;
 }
 
 /* Return the address of a modified value.  */
-static Elf_Addr *
-get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset)
+static ElfT_Addr *
+get_target_address (ElfT_Ehdr *e, ElfT_Shdr *s, ElfT_Addr offset)
 {
-  return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset);
+  return (ElfT_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset);
 }
 
 /* Deal with relocation information. This function relocates addresses
@@ -325,35 +325,35 @@ get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset)
    addresses can be fully resolved. Absolute addresses must be relocated
    again by a PE32 relocator when loaded.  */
 static void
-relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections,
-		    Elf_Addr *section_addresses,
-		    Elf_Half section_entsize, Elf_Half num_sections,
+relocate_addresses (ElfT_Ehdr *e, ElfT_Shdr *sections,
+		    ElfT_Addr *section_addresses,
+		    ElfT_Half section_entsize, ElfT_Half num_sections,
 		    const char *strtab)
 {
-  Elf_Half i;
-  Elf_Shdr *s;
+  ElfT_Half i;
+  ElfT_Shdr *s;
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) ||
         (s->sh_type == grub_cpu_to_le32 (SHT_RELA)))
       {
-	Elf_Rela *r;
-	Elf_Word rtab_size, r_size, num_rs;
-	Elf_Off rtab_offset;
-	Elf_Shdr *symtab_section;
-	Elf_Word target_section_index;
-	Elf_Addr target_section_addr;
-	Elf_Shdr *target_section;
-	Elf_Word j;
-
-	symtab_section = (Elf_Shdr *) ((char *) sections
+	ElfT_Rela *r;
+	ElfT_Word rtab_size, r_size, num_rs;
+	ElfT_Off rtab_offset;
+	ElfT_Shdr *symtab_section;
+	ElfT_Word target_section_index;
+	ElfT_Addr target_section_addr;
+	ElfT_Shdr *target_section;
+	ElfT_Word j;
+
+	symtab_section = (ElfT_Shdr *) ((char *) sections
 					 + (grub_le_to_cpu32 (s->sh_link)
 					    * section_entsize));
 	target_section_index = grub_le_to_cpu32 (s->sh_info);
 	target_section_addr = section_addresses[target_section_index];
-	target_section = (Elf_Shdr *) ((char *) sections
+	target_section = (ElfT_Shdr *) ((char *) sections
 					 + (target_section_index
 					    * section_entsize));
 
@@ -366,26 +366,26 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections,
 	rtab_offset = grub_le_to_cpu32 (s->sh_offset);
 	num_rs = rtab_size / r_size;
 
-	for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
+	for (j = 0, r = (ElfT_Rela *) ((char *) e + rtab_offset);
 	     j < num_rs;
-	     j++, r = (Elf_Rela *) ((char *) r + r_size))
+	     j++, r = (ElfT_Rela *) ((char *) r + r_size))
 	  {
-            Elf_Addr info;
-	    Elf_Addr offset;
-	    Elf_Addr sym_addr;
-	    Elf_Addr *target;
-	    Elf_Addr addend;
+            ElfT_Addr info;
+	    ElfT_Addr offset;
+	    ElfT_Addr sym_addr;
+	    ElfT_Addr *target;
+	    ElfT_Addr addend;
 
 	    offset = grub_le_to_cpu (r->r_offset);
 	    target = get_target_address (e, target_section, offset);
 	    info = grub_le_to_cpu (r->r_info);
 	    sym_addr = get_symbol_address (e, symtab_section,
-					   ELF_R_SYM (info));
+					   ELFT_R_SYM (info));
 
             addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ?
 	      r->r_addend : 0;
 
-            switch (ELF_R_TYPE (info))
+            switch (ELFT_R_TYPE (info))
 	      {
 #if GRUB_TARGET_SIZEOF_VOID_P == 4
 	      case R_386_NONE:
@@ -445,7 +445,7 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections,
 #endif
 	      default:
 		grub_util_error ("unknown relocation type %d",
-				 ELF_R_TYPE (info));
+				 ELFT_R_TYPE (info));
 		break;
 	      }
 	  }
@@ -464,9 +464,9 @@ write_padding (FILE *out, size_t size)
 
 /* Add a PE32's fixup entry for a relocation. Return the resulting address
    after having written to the file OUT.  */
-Elf_Addr
+ElfT_Addr
 add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type,
-		 Elf_Addr addr, int flush, Elf_Addr current_address,
+		 ElfT_Addr addr, int flush, ElfT_Addr current_address,
 		 FILE *out)
 {
   struct grub_pe32_fixup_block *b = *block;
@@ -482,7 +482,7 @@ add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type,
 	    {
 	      /* Add as much padding as necessary to align the address
 		 with a section boundary.  */
-	      Elf_Addr next_address;
+	      ElfT_Addr next_address;
 	      unsigned padding_size;
               size_t index;
 
@@ -555,10 +555,10 @@ add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type,
 }
 
 /* Write out zeros to make space for the header.  */
-static Elf_Addr
+static ElfT_Addr
 make_header_space (FILE *out)
 {
-  Elf_Addr addr;
+  ElfT_Addr addr;
 
   addr = get_starting_section_address ();
   write_padding (out, addr);
@@ -567,24 +567,24 @@ make_header_space (FILE *out)
 }
 
 /* Write text sections.  */
-static Elf_Addr
-write_text_sections (FILE *out, Elf_Addr current_address,
-		     Elf_Ehdr *e, Elf_Shdr *sections,
-		     Elf_Half section_entsize, Elf_Half num_sections,
+static ElfT_Addr
+write_text_sections (FILE *out, ElfT_Addr current_address,
+		     ElfT_Ehdr *e, ElfT_Shdr *sections,
+		     ElfT_Half section_entsize, ElfT_Half num_sections,
 		     const char *strtab)
 {
-  Elf_Half i;
-  Elf_Shdr *s;
-  Elf_Addr addr;
+  ElfT_Half i;
+  ElfT_Shdr *s;
+  ElfT_Addr addr;
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (is_text_section (s))
       {
-	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
-	Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
-	Elf_Word size = grub_le_to_cpu32 (s->sh_size);
+	ElfT_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	ElfT_Off offset = grub_le_to_cpu32 (s->sh_offset);
+	ElfT_Word size = grub_le_to_cpu32 (s->sh_size);
 	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
 
 	if (align)
@@ -620,24 +620,24 @@ write_text_sections (FILE *out, Elf_Addr current_address,
 }
 
 /* Write data sections.  */
-static Elf_Addr
-write_data_sections (FILE *out, Elf_Addr current_address,
-		     Elf_Ehdr *e, Elf_Shdr *sections,
-		     Elf_Half section_entsize, Elf_Half num_sections,
+static ElfT_Addr
+write_data_sections (FILE *out, ElfT_Addr current_address,
+		     ElfT_Ehdr *e, ElfT_Shdr *sections,
+		     ElfT_Half section_entsize, ElfT_Half num_sections,
 		     const char *strtab)
 {
-  Elf_Half i;
-  Elf_Shdr *s;
-  Elf_Addr addr;
+  ElfT_Half i;
+  ElfT_Shdr *s;
+  ElfT_Addr addr;
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (is_data_section (s))
       {
-	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
-	Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
-	Elf_Word size = grub_le_to_cpu32 (s->sh_size);
+	ElfT_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	ElfT_Off offset = grub_le_to_cpu32 (s->sh_offset);
+	ElfT_Word size = grub_le_to_cpu32 (s->sh_size);
 	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
 
 	if (align)
@@ -676,15 +676,15 @@ write_data_sections (FILE *out, Elf_Addr current_address,
 }
 
 /* Write modules.  */
-static Elf_Addr
-make_mods_section (FILE *out, Elf_Addr current_address,
+static ElfT_Addr
+make_mods_section (FILE *out, ElfT_Addr current_address,
 		   const char *dir, char *mods[])
 {
   struct grub_util_path_list *path_list;
   grub_size_t total_module_size;
   struct grub_util_path_list *p;
   struct grub_module_info modinfo;
-  Elf_Addr addr;
+  ElfT_Addr addr;
 
   memset (&modinfo, 0, sizeof (modinfo));
 
@@ -752,27 +752,27 @@ make_mods_section (FILE *out, Elf_Addr current_address,
 }
 
 /* Make a .reloc section.  */
-static Elf_Addr
-make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e,
-		    Elf_Addr *section_addresses, Elf_Shdr *sections,
-		    Elf_Half section_entsize, Elf_Half num_sections,
+static ElfT_Addr
+make_reloc_section (FILE *out, ElfT_Addr current_address, ElfT_Ehdr *e,
+		    ElfT_Addr *section_addresses, ElfT_Shdr *sections,
+		    ElfT_Half section_entsize, ElfT_Half num_sections,
 		    const char *strtab)
 {
-  Elf_Half i;
-  Elf_Shdr *s;
+  ElfT_Half i;
+  ElfT_Shdr *s;
   struct grub_pe32_fixup_block *fixup_block = 0;
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) ||
         (s->sh_type == grub_cpu_to_le32 (SHT_RELA)))
       {
-	Elf_Rel *r;
-	Elf_Word rtab_size, r_size, num_rs;
-	Elf_Off rtab_offset;
-	Elf_Addr section_address;
-	Elf_Word j;
+	ElfT_Rel *r;
+	ElfT_Word rtab_size, r_size, num_rs;
+	ElfT_Off rtab_offset;
+	ElfT_Addr section_address;
+	ElfT_Word j;
 
 	grub_util_info ("translating the relocation section %s",
 			strtab + grub_le_to_cpu32 (s->sh_name));
@@ -784,21 +784,21 @@ make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e,
 
 	section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)];
 
-	for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
+	for (j = 0, r = (ElfT_Rel *) ((char *) e + rtab_offset);
 	     j < num_rs;
-	     j++, r = (Elf_Rel *) ((char *) r + r_size))
+	     j++, r = (ElfT_Rel *) ((char *) r + r_size))
 	  {
-	    Elf_Addr info;
-	    Elf_Addr offset;
+	    ElfT_Addr info;
+	    ElfT_Addr offset;
 
 	    offset = grub_le_to_cpu32 (r->r_offset);
 	    info = grub_le_to_cpu32 (r->r_info);
 
 	    /* Necessary to relocate only absolute addresses.  */
 #if GRUB_TARGET_SIZEOF_VOID_P == 4
-	    if (ELF_R_TYPE (info) == R_386_32)
+	    if (ELFT_R_TYPE (info) == R_386_32)
 	      {
-		Elf_Addr addr;
+		ElfT_Addr addr;
 
 		addr = section_address + offset;
 		grub_util_info ("adding a relocation entry for 0x%x", addr);
@@ -808,14 +808,14 @@ make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e,
 						   out);
 	      }
 #else
-	    if ((ELF_R_TYPE (info) == R_X86_64_32) ||
-                (ELF_R_TYPE (info) == R_X86_64_32S))
+	    if ((ELFT_R_TYPE (info) == R_X86_64_32) ||
+                (ELFT_R_TYPE (info) == R_X86_64_32S))
 	      {
 		grub_util_error ("Can\'t add fixup entry for R_X86_64_32(S)");
 	      }
-	    else if (ELF_R_TYPE (info) == R_X86_64_64)
+	    else if (ELFT_R_TYPE (info) == R_X86_64_64)
 	      {
-		Elf_Addr addr;
+		ElfT_Addr addr;
 
 		addr = section_address + offset;
 		grub_util_info ("adding a relocation entry for 0x%llx", addr);
@@ -837,9 +837,9 @@ make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e,
 
 /* Create the header.  */
 static void
-make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address,
-	     Elf_Addr mods_address, Elf_Addr reloc_address,
-	     Elf_Addr end_address, Elf_Addr start_address)
+make_header (FILE *out, ElfT_Addr text_address, ElfT_Addr data_address,
+	     ElfT_Addr mods_address, ElfT_Addr reloc_address,
+	     ElfT_Addr end_address, ElfT_Addr start_address)
 {
   struct grub_pe32_header header;
   struct grub_pe32_coff_header *c;
@@ -964,22 +964,22 @@ convert_elf (const char *dir, char *prefix, FILE *out, char *mods[])
   char *kernel_image;
   size_t kernel_size;
   const char *strtab;
-  Elf_Ehdr *e;
-  Elf_Shdr *sections;
-  Elf_Off section_offset;
-  Elf_Half section_entsize;
-  Elf_Half num_sections;
-  Elf_Addr *section_addresses;
-  Elf_Shdr *symtab_section;
-  Elf_Addr start_address;
-  Elf_Addr text_address, data_address, reloc_address, mods_address;
-  Elf_Addr end_address;
-  Elf_Shdr *s;
+  ElfT_Ehdr *e;
+  ElfT_Shdr *sections;
+  ElfT_Off section_offset;
+  ElfT_Half section_entsize;
+  ElfT_Half num_sections;
+  ElfT_Addr *section_addresses;
+  ElfT_Shdr *symtab_section;
+  ElfT_Addr start_address;
+  ElfT_Addr text_address, data_address, reloc_address, mods_address;
+  ElfT_Addr end_address;
+  ElfT_Shdr *s;
   int i;
 
   /* Get the kernel image and check the format.  */
   kernel_image = read_kernel_module (dir, &kernel_size);
-  e = (Elf_Ehdr *) kernel_image;
+  e = (ElfT_Ehdr *) kernel_image;
   if (! check_elf_header (e, kernel_size))
     grub_util_error ("invalid ELF header");
 
@@ -990,15 +990,15 @@ convert_elf (const char *dir, char *prefix, FILE *out, char *mods[])
   if (kernel_size < section_offset + section_entsize * num_sections)
     grub_util_error ("invalid ELF format");
 
-  sections = (Elf_Shdr *) (kernel_image + section_offset);
+  sections = (ElfT_Shdr *) (kernel_image + section_offset);
   strtab = find_strtab (e, sections, section_entsize);
 
   for (i = 0, s = sections;
        i < num_sections;
-       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+       i++, s = (ElfT_Shdr *) ((char *) s + section_entsize))
     if (is_text_section (s))
       {
-	  Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
+	  ElfT_Off offset = grub_le_to_cpu32 (s->sh_offset);
 
 	  if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
 	    grub_util_error ("prefix too long");

[-- Attachment #3: 03-simple-symtab.patch --]
[-- Type: text/x-patch, Size: 5163 bytes --]

Simplify symtab logic

From: Pavel Roskin <proski@gnu.org>


---

 include/grub/dl.h |    5 -----
 kern/dl.c         |    4 +++-
 kern/i386/dl.c    |    4 +---
 kern/powerpc/dl.c |    4 +---
 kern/sparc64/dl.c |    4 +---
 kern/x86_64/dl.c  |    4 +---
 6 files changed, 7 insertions(+), 18 deletions(-)


diff --git a/include/grub/dl.h b/include/grub/dl.h
index fbd77b2..b507989 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -85,12 +85,7 @@ struct grub_dl
   int ref_count;
   grub_dl_dep_t dep;
   grub_dl_segment_t segment;
-#ifdef GRUB_MODULES_MACHINE_READONLY
   Elf_Sym *symtab;
-#define get_symtab()	mod->symtab
-#else
-#define get_symtab()	((Elf_Sym *) ((char *) e + s->sh_offset))
-#endif
   void (*init) (struct grub_dl *mod);
   void (*fini) (void);
 };
diff --git a/kern/dl.c b/kern/dl.c
index ce1e269..0ee4649 100644
--- a/kern/dl.c
+++ b/kern/dl.c
@@ -314,8 +314,10 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
 #ifdef GRUB_MODULES_MACHINE_READONLY
   mod->symtab = grub_malloc (size);
   memcpy (mod->symtab, (char *) e + s->sh_offset, size);
+#else
+  mod->symtab = ((Elf_Sym *) ((char *) e + s->sh_offset));
 #endif
-  sym = get_symtab ();
+  sym = mod->symtab;
 
   s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
   str = (char *) e + s->sh_offset;
diff --git a/kern/i386/dl.c b/kern/i386/dl.c
index 6d5b95a..a17f175 100644
--- a/kern/i386/dl.c
+++ b/kern/i386/dl.c
@@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf32_Ehdr *e = ehdr;
   Elf32_Shdr *s;
-  Elf32_Sym *symtab;
   Elf32_Word entsize;
   unsigned i;
 
@@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		switch (ELF32_R_TYPE (rel->r_info))
diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c
index a85ceef..9b1cb14 100644
--- a/kern/powerpc/dl.c
+++ b/kern/powerpc/dl.c
@@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf32_Ehdr *e = ehdr;
   Elf32_Shdr *s;
-  Elf32_Sym *symtab;
   Elf32_Word entsize;
   unsigned i;
 
@@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		/* On the PPC the value does not have an explicit
diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c
index e427468..5334896 100644
--- a/kern/sparc64/dl.c
+++ b/kern/sparc64/dl.c
@@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf64_Ehdr *e = ehdr;
   Elf64_Shdr *s;
-  Elf64_Sym *symtab;
   Elf64_Word entsize;
   unsigned i;
 
@@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		value = sym->st_value + rel->r_addend;
diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c
index 74ae188..9e5de6e 100644
--- a/kern/x86_64/dl.c
+++ b/kern/x86_64/dl.c
@@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf64_Ehdr *e = ehdr;
   Elf64_Shdr *s;
-  Elf64_Sym *symtab;
   Elf64_Word entsize;
   unsigned i;
 
@@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = get_symtab ();
   entsize = s->sh_entsize;
 
   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);
 		addr64 = (Elf64_Xword *) addr32;
-		sym = (Elf64_Sym *) ((char *) symtab
+		sym = (Elf64_Sym *) ((char *) mod->symtab
 				     + entsize * ELF64_R_SYM (rel->r_info));
 
 		switch (ELF64_R_TYPE (rel->r_info))

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 16:44                     ` Pavel Roskin
@ 2009-06-26 17:03                       ` Robert Millan
  2009-06-26 17:16                         ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-26 17:03 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 26, 2009 at 12:44:07PM -0400, Pavel Roskin wrote:
> On Fri, 2009-06-26 at 16:41 +0200, Robert Millan wrote:
> > On Thu, Jun 25, 2009 at 04:51:11PM -0400, Pavel Roskin wrote:
> > > 
> > > I'd like to avoid preprocessor conditionals in kern/ARCH/dl.c files if
> > > possible.
> > 
> > Alright, here's a new patch.  It follows your earlier suggestion to use
> > a wrapper to obtain the initialization address for symtab.  This way we
> > don't put any ifdefs in kern/ARCH/dl.c files.
> > 
> > I also avoid the #undefs in efiemu.  This required many changes in
> > loadcore.c, but they're just a sed search & replace run.
> 
> More redefinitions are needed to make all platforms compile.  At this
> point I think maybe we should try something less intrusive.  But anyway,
> 02-elf-renames.patch contains those renames.
> 
> 03-simple-symtab.patch simplifies the logic in kern/ARCH/dl.c files.

03-simple-symtab.patch looks nice, much cleaner than what I had.

But as for 02-elf-renames.patch we could try to make this more consistent.  In
efiemu I used 'W' (inspired by ElfW() macro in glibc), then in some places you
use 'K' and in other places 'T'.  Can we use the same everywhere?  I don't
care which letter, I'm not THAT much into bikeshed :-)

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 17:03                       ` Robert Millan
@ 2009-06-26 17:16                         ` Pavel Roskin
  2009-06-26 17:43                           ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-26 17:16 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, 2009-06-26 at 19:03 +0200, Robert Millan wrote:

> 03-simple-symtab.patch looks nice, much cleaner than what I had.

Thanks!

> But as for 02-elf-renames.patch we could try to make this more consistent.  In
> efiemu I used 'W' (inspired by ElfW() macro in glibc), then in some places you
> use 'K' and in other places 'T'.  Can we use the same everywhere?  I don't
> care which letter, I'm not THAT much into bikeshed :-)

"T" stands for "target" and "K" stands for "kernel".  Yes, we can use
ElfW everywhere.  But I would try to avoid any mass renames.  It's very
easy to write Elf instead of ElfW somewhere in the code, and it would
compile, but it won't work.

Maybe we could have two headers, elf32.h and elf64.h, and every file
that needs Elf definitions would include one of them, dependent on which
elf format it wants.  Including both elf32.h and elf64.h from one source
should be impossible.  It could be a separate patch that would go in
before the ROM modules support.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 17:16                         ` Pavel Roskin
@ 2009-06-26 17:43                           ` Robert Millan
  2009-06-26 19:52                             ` Pavel Roskin
  2009-06-26 22:26                             ` Pavel Roskin
  0 siblings, 2 replies; 71+ messages in thread
From: Robert Millan @ 2009-06-26 17:43 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 26, 2009 at 01:16:57PM -0400, Pavel Roskin wrote:
> > But as for 02-elf-renames.patch we could try to make this more consistent.  In
> > efiemu I used 'W' (inspired by ElfW() macro in glibc), then in some places you
> > use 'K' and in other places 'T'.  Can we use the same everywhere?  I don't
> > care which letter, I'm not THAT much into bikeshed :-)
> 
> "T" stands for "target" and "K" stands for "kernel".  Yes, we can use
> ElfW everywhere.  But I would try to avoid any mass renames.  It's very
> easy to write Elf instead of ElfW somewhere in the code, and it would
> compile, but it won't work.

Ok, I don't mind.  Unless you have any objections, I'll merge your two
patches with mine and commit that.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 17:43                           ` Robert Millan
@ 2009-06-26 19:52                             ` Pavel Roskin
  2009-06-26 22:26                             ` Pavel Roskin
  1 sibling, 0 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-26 19:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, 2009-06-26 at 19:43 +0200, Robert Millan wrote:

> Ok, I don't mind.  Unless you have any objections, I'll merge your two
> patches with mine and commit that.

Please let me try to do it in a nicer way.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 17:43                           ` Robert Millan
  2009-06-26 19:52                             ` Pavel Roskin
@ 2009-06-26 22:26                             ` Pavel Roskin
  2009-06-26 23:57                               ` Robert Millan
  1 sibling, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-26 22:26 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 977 bytes --]

On Fri, 2009-06-26 at 19:43 +0200, Robert Millan wrote:
> On Fri, Jun 26, 2009 at 01:16:57PM -0400, Pavel Roskin wrote:
> > > But as for 02-elf-renames.patch we could try to make this more consistent.  In
> > > efiemu I used 'W' (inspired by ElfW() macro in glibc), then in some places you
> > > use 'K' and in other places 'T'.  Can we use the same everywhere?  I don't
> > > care which letter, I'm not THAT much into bikeshed :-)
> > 
> > "T" stands for "target" and "K" stands for "kernel".  Yes, we can use
> > ElfW everywhere.  But I would try to avoid any mass renames.  It's very
> > easy to write Elf instead of ElfW somewhere in the code, and it would
> > compile, but it won't work.
> 
> Ok, I don't mind.  Unless you have any objections, I'll merge your two
> patches with mine and commit that.

Please consider following patches.  They avoid the massive rename.  ELF
header reorganization is split from adding support for modules in ROM.

-- 
Regards,
Pavel Roskin

[-- Attachment #2: 01-select-elf.patch --]
[-- Type: text/x-patch, Size: 6081 bytes --]

Select default ELF format in include/grub/elf.h

From: Pavel Roskin <proski@gnu.org>

ChangeLog:

	* include/grub/elf.h: Define symbols for 32-bit or 64-bit ELF
	based on DEFAULT_ELF_BITS.  Default to the target word size.
	* efiemu/loadcore32.c: Use DEFAULT_ELF_BITS instead of own
	definitions.
	* efiemu/loadcore64.c: Likewise.
	* loader/i386/bsd32.c: Likewise.
	* loader/i386/bsd64.c: Likewise.
	* kern/dl.c: Remove ELF definitions.
	* util/i386/efi/grub-mkimage.c: Likewise.
---

 efiemu/loadcore32.c          |    7 +------
 efiemu/loadcore64.c          |    7 +------
 include/grub/elf.h           |   44 ++++++++++++++++++++++++++++++++++++++++++
 kern/dl.c                    |   24 -----------------------
 loader/i386/bsd32.c          |    4 +---
 loader/i386/bsd64.c          |    4 +---
 util/i386/efi/grub-mkimage.c |   34 --------------------------------
 7 files changed, 48 insertions(+), 76 deletions(-)


diff --git a/efiemu/loadcore32.c b/efiemu/loadcore32.c
index b4f61c7..4e0fcc5 100644
--- a/efiemu/loadcore32.c
+++ b/efiemu/loadcore32.c
@@ -18,10 +18,5 @@
  */
 
 #define SUFFIX(x) x ## 32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Word Elf32_Word
-#define ELF_ST_TYPE ELF32_ST_TYPE
-#define ELF_ST_BIND ELF32_ST_BIND
+#define DEFAULT_ELF_BITS 32
 #include "loadcore.c"
diff --git a/efiemu/loadcore64.c b/efiemu/loadcore64.c
index 097276c..3c5cc54 100644
--- a/efiemu/loadcore64.c
+++ b/efiemu/loadcore64.c
@@ -18,10 +18,5 @@
  */
 
 #define SUFFIX(x) x ## 64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Word Elf64_Word
-#define ELF_ST_TYPE ELF64_ST_TYPE
-#define ELF_ST_BIND ELF64_ST_BIND
+#define DEFAULT_ELF_BITS 64
 #include "loadcore.c"
diff --git a/include/grub/elf.h b/include/grub/elf.h
index 319bc7c..23a8415 100644
--- a/include/grub/elf.h
+++ b/include/grub/elf.h
@@ -2330,4 +2330,48 @@ typedef Elf32_Addr Elf32_Conflict;
 
 #define R_X86_64_NUM		24
 
+#ifndef DEFAULT_ELF_BITS
+#define DEFAULT_ELF_BITS (8 * GRUB_TARGET_SIZEOF_VOID_P)
+#endif
+
+#if DEFAULT_ELF_BITS == 32
+
+typedef Elf32_Addr Elf_Addr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Half Elf_Half;
+typedef Elf32_Off Elf_Off;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Section Elf_Section;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Word Elf_Word;
+
+#define ELF_ST_BIND(val)	ELF32_ST_BIND(val)
+#define ELF_ST_TYPE(val)	ELF32_ST_TYPE(val)
+#define ELF_R_SYM(val)		ELF32_R_SYM(val)
+#define ELF_R_TYPE(val)		ELF32_R_TYPE(val)
+#define ELF_R_INFO(sym, type)	ELF32_R_INFO(sym, type)
+
+#elif DEFAULT_ELF_BITS == 64
+
+typedef Elf64_Addr Elf_Addr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Half Elf_Half;
+typedef Elf64_Off Elf_Off;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Section Elf_Section;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Word Elf_Word;
+
+#define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
+#define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
+#define ELF_R_SYM(val)		ELF64_R_SYM(val)
+#define ELF_R_TYPE(val)		ELF64_R_TYPE(val)
+#define ELF_R_INFO(sym, type)	ELF64_R_INFO(sym, type)
+
+#endif /* DEFAULT_ELF_BITS == 64 */
+
 #endif /* ! GRUB_ELF_H */
diff --git a/kern/dl.c b/kern/dl.c
index d729c08..cd34e31 100644
--- a/kern/dl.c
+++ b/kern/dl.c
@@ -29,30 +29,6 @@
 #include <grub/env.h>
 #include <grub/cache.h>
 
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF32_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF32_ST_TYPE (val)
-
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
-# define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
-
-#endif
-
 \f
 
 struct grub_dl_list
diff --git a/loader/i386/bsd32.c b/loader/i386/bsd32.c
index 24dab6c..a4fa48c 100644
--- a/loader/i386/bsd32.c
+++ b/loader/i386/bsd32.c
@@ -1,7 +1,5 @@
 #define SUFFIX(x) x ## 32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
+#define DEFAULT_ELF_BITS 32
 #define OBJSYM 0
 #include <grub/types.h>
 typedef grub_uint32_t grub_freebsd_addr_t;
diff --git a/loader/i386/bsd64.c b/loader/i386/bsd64.c
index f4ff8b2..8e3eba9 100644
--- a/loader/i386/bsd64.c
+++ b/loader/i386/bsd64.c
@@ -1,7 +1,5 @@
 #define SUFFIX(x) x ## 64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
+#define DEFAULT_ELF_BITS 64
 #define OBJSYM 1
 #include <grub/types.h>
 typedef grub_uint64_t grub_freebsd_addr_t;
diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c
index 2813e79..a92e6da 100644
--- a/util/i386/efi/grub-mkimage.c
+++ b/util/i386/efi/grub-mkimage.c
@@ -32,43 +32,9 @@
 #include <grub/machine/kernel.h>
 
 #if GRUB_TARGET_SIZEOF_VOID_P == 4
-
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-typedef Elf32_Half Elf_Half;
-typedef Elf32_Off Elf_Off;
-typedef Elf32_Section Elf_Section;
-typedef Elf32_Rel Elf_Rel;
-typedef Elf32_Rela Elf_Rela;
-
-#define ELF_R_SYM	ELF32_R_SYM
-#define ELF_R_TYPE	ELF32_R_TYPE
-#define ELF_R_INFO	ELF32_R_INFO
-
 #define grub_le_to_cpu	grub_le_to_cpu32
-
 #elif GRUB_TARGET_SIZEOF_VOID_P == 8
-
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-typedef Elf64_Half Elf_Half;
-typedef Elf64_Off Elf_Off;
-typedef Elf64_Section Elf_Section;
-typedef Elf64_Rel Elf_Rel;
-typedef Elf64_Rela Elf_Rela;
-
-#define ELF_R_SYM	ELF64_R_SYM
-#define ELF_R_TYPE	ELF64_R_TYPE
-#define ELF_R_INFO	ELF64_R_INFO
-
 #define grub_le_to_cpu	grub_le_to_cpu64
-
 #endif
 
 static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;

[-- Attachment #3: 02-module-ro.patch --]
[-- Type: text/x-patch, Size: 7207 bytes --]

Allow modules in ROM

From: Pavel Roskin <proski@gnu.org>

ChangeLog:

	* 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.
---

 include/grub/dl.h |    4 +++-
 kern/dl.c         |   19 +++++++++++++++++--
 kern/i386/dl.c    |    4 +---
 kern/powerpc/dl.c |    4 +---
 kern/sparc64/dl.c |    4 +---
 kern/x86_64/dl.c  |    4 +---
 6 files changed, 24 insertions(+), 15 deletions(-)


diff --git a/include/grub/dl.h b/include/grub/dl.h
index 894da1d..bebb810 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -1,7 +1,7 @@
 /* dl.h - types and prototypes for loadable module support */
 /*
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 #include <grub/symbol.h>
 #include <grub/err.h>
 #include <grub/types.h>
+#include <grub/elf.h>
 
 #define GRUB_MOD_INIT(name)	\
 static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
@@ -78,6 +79,7 @@ struct grub_dl
   int ref_count;
   grub_dl_dep_t dep;
   grub_dl_segment_t segment;
+  Elf_Sym *symtab;
   void (*init) (struct grub_dl *mod);
   void (*fini) (void);
 };
diff --git a/kern/dl.c b/kern/dl.c
index cd34e31..af4e5aa 100644
--- a/kern/dl.c
+++ b/kern/dl.c
@@ -1,7 +1,7 @@
 /* dl.c - loadable module support */
 /*
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -28,6 +28,12 @@
 #include <grub/file.h>
 #include <grub/env.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
 
 \f
 
@@ -309,7 +315,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
   if (i == e->e_shnum)
     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;
   entsize = s->sh_entsize;
 
@@ -671,6 +683,9 @@ grub_dl_unload (grub_dl_t mod)
     }
 
   grub_free (mod->name);
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  grub_free (mod->symtab);
+#endif
   grub_free (mod);
   return 1;
 }
diff --git a/kern/i386/dl.c b/kern/i386/dl.c
index 978bfb1..a17f175 100644
--- a/kern/i386/dl.c
+++ b/kern/i386/dl.c
@@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf32_Ehdr *e = ehdr;
   Elf32_Shdr *s;
-  Elf32_Sym *symtab;
   Elf32_Word entsize;
   unsigned i;
 
@@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		switch (ELF32_R_TYPE (rel->r_info))
diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c
index ae987c0..9b1cb14 100644
--- a/kern/powerpc/dl.c
+++ b/kern/powerpc/dl.c
@@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf32_Ehdr *e = ehdr;
   Elf32_Shdr *s;
-  Elf32_Sym *symtab;
   Elf32_Word entsize;
   unsigned i;
 
@@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		/* On the PPC the value does not have an explicit
diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c
index d998daf..5334896 100644
--- a/kern/sparc64/dl.c
+++ b/kern/sparc64/dl.c
@@ -44,7 +44,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf64_Ehdr *e = ehdr;
   Elf64_Shdr *s;
-  Elf64_Sym *symtab;
   Elf64_Word entsize;
   unsigned i;
 
@@ -58,7 +57,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
   entsize = s->sh_entsize;
 
   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");
 
 		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));
 
 		value = sym->st_value + rel->r_addend;
diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c
index a606901..9e5de6e 100644
--- a/kern/x86_64/dl.c
+++ b/kern/x86_64/dl.c
@@ -43,7 +43,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
 {
   Elf64_Ehdr *e = ehdr;
   Elf64_Shdr *s;
-  Elf64_Sym *symtab;
   Elf64_Word entsize;
   unsigned i;
 
@@ -57,7 +56,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (i == e->e_shnum)
     return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
 
-  symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
   entsize = s->sh_entsize;
 
   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);
 		addr64 = (Elf64_Xword *) addr32;
-		sym = (Elf64_Sym *) ((char *) symtab
+		sym = (Elf64_Sym *) ((char *) mod->symtab
 				     + entsize * ELF64_R_SYM (rel->r_info));
 
 		switch (ELF64_R_TYPE (rel->r_info))

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 22:26                             ` Pavel Roskin
@ 2009-06-26 23:57                               ` Robert Millan
  2009-06-27  3:08                                 ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-26 23:57 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 26, 2009 at 06:26:57PM -0400, Pavel Roskin wrote:
> --- a/include/grub/elf.h
> +++ b/include/grub/elf.h
> @@ -2330,4 +2330,48 @@ typedef Elf32_Addr Elf32_Conflict;
>  
>  #define R_X86_64_NUM		24
>  
> +#ifndef DEFAULT_ELF_BITS
> +#define DEFAULT_ELF_BITS (8 * GRUB_TARGET_SIZEOF_VOID_P)
> +#endif

Nice trick.  But it's not ELF-specific, so why not put it in the
same header that defines GRUB_TARGET_SIZEOF_VOID_P ? (with a different
name of course)

But either way, your patches look fine to me.

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-26 23:57                               ` Robert Millan
@ 2009-06-27  3:08                                 ` Pavel Roskin
  2009-06-27 11:18                                   ` Robert Millan
  0 siblings, 1 reply; 71+ messages in thread
From: Pavel Roskin @ 2009-06-27  3:08 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, 2009-06-27 at 01:57 +0200, Robert Millan wrote:
> On Fri, Jun 26, 2009 at 06:26:57PM -0400, Pavel Roskin wrote:
> > --- a/include/grub/elf.h
> > +++ b/include/grub/elf.h
> > @@ -2330,4 +2330,48 @@ typedef Elf32_Addr Elf32_Conflict;
> >  
> >  #define R_X86_64_NUM		24
> >  
> > +#ifndef DEFAULT_ELF_BITS
> > +#define DEFAULT_ELF_BITS (8 * GRUB_TARGET_SIZEOF_VOID_P)
> > +#endif
> 
> Nice trick.  But it's not ELF-specific, so why not put it in the
> same header that defines GRUB_TARGET_SIZEOF_VOID_P ? (with a different
> name of course)

Good idea!  Now it's GRUB_TARGET_WORDSIZE.  The first patch has been
committed.  The second patch should probably go after the qemu patch.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-27  3:08                                 ` Pavel Roskin
@ 2009-06-27 11:18                                   ` Robert Millan
  2009-06-29  3:48                                     ` Pavel Roskin
  0 siblings, 1 reply; 71+ messages in thread
From: Robert Millan @ 2009-06-27 11:18 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 26, 2009 at 11:08:23PM -0400, Pavel Roskin wrote:
> On Sat, 2009-06-27 at 01:57 +0200, Robert Millan wrote:
> > On Fri, Jun 26, 2009 at 06:26:57PM -0400, Pavel Roskin wrote:
> > > --- a/include/grub/elf.h
> > > +++ b/include/grub/elf.h
> > > @@ -2330,4 +2330,48 @@ typedef Elf32_Addr Elf32_Conflict;
> > >  
> > >  #define R_X86_64_NUM		24
> > >  
> > > +#ifndef DEFAULT_ELF_BITS
> > > +#define DEFAULT_ELF_BITS (8 * GRUB_TARGET_SIZEOF_VOID_P)
> > > +#endif
> > 
> > Nice trick.  But it's not ELF-specific, so why not put it in the
> > same header that defines GRUB_TARGET_SIZEOF_VOID_P ? (with a different
> > name of course)
> 
> Good idea!  Now it's GRUB_TARGET_WORDSIZE.  The first patch has been
> committed.

Ok but note that word size == pointer size is not always true.  In fact
I'm working on a project where it isn't :-)

  (if you're curious: https://savannah.gnu.org/task/?9437)

> The second patch should probably go after the qemu patch.

Actually, the qemu port won't work without the second patch.  I just merged it
with mine and made a joint commit (ROM + qemu).

-- 
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."



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port))
  2009-06-27 11:18                                   ` Robert Millan
@ 2009-06-29  3:48                                     ` Pavel Roskin
  0 siblings, 0 replies; 71+ messages in thread
From: Pavel Roskin @ 2009-06-29  3:48 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, 2009-06-27 at 13:18 +0200, Robert Millan wrote:

> Ok but note that word size == pointer size is not always true.  In fact
> I'm working on a project where it isn't :-)
> 
>   (if you're curious: https://savannah.gnu.org/task/?9437)

OK, when GRUB is changed to support that architecture, we'll make the
necessary adjustments.

> > The second patch should probably go after the qemu patch.
> 
> Actually, the qemu port won't work without the second patch.  I just merged it
> with mine and made a joint commit (ROM + qemu).

Good.  Thank you!

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2009-06-29  3:48 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-21 18:17 [PATCH] i386-qemu port Robert Millan
2009-06-21 18:50 ` does module area require alignment? (Re: [PATCH] i386-qemu port) Robert Millan
2009-06-21 19:08   ` Pavel Roskin
2009-06-21 19:33     ` Robert Millan
2009-06-22 12:31       ` [PATCH] define GRUB_MOD_ALIGN to 0 on non-ieee1275 (Re: does module area require alignment? (Re: [PATCH] i386-qemu port)) Robert Millan
2009-06-22 19:43         ` Pavel Roskin
2009-06-22 20:41           ` Robert Millan
2009-06-22 20:51             ` Pavel Roskin
2009-06-22 21:22               ` Robert Millan
2009-06-22 21:45                 ` Pavel Roskin
2009-06-22 22:31                   ` Robert Millan
2009-06-22 19:51       ` does module area require alignment? (Re: [PATCH] i386-qemu port) Pavel Roskin
2009-06-22 22:50         ` Vladimir 'phcoder' Serbinenko
2009-06-23  0:10           ` Pavel Roskin
2009-06-21 18:54 ` [PATCH] move grub_stop() " Robert Millan
2009-06-21 19:05   ` Pavel Roskin
2009-06-21 19:25     ` Robert Millan
2009-06-22  2:14       ` Pavel Roskin
2009-06-22 10:10         ` Robert Millan
2009-06-22 16:16           ` Pavel Roskin
2009-06-22 18:05             ` Robert Millan
2009-06-21 19:00 ` [PATCH] i386-qemu port Pavel Roskin
2009-06-21 19:30   ` Robert Millan
2009-06-22 12:45     ` Robert Millan
2009-06-21 20:34   ` Robert Millan
2009-06-21 20:40     ` Vladimir 'phcoder' Serbinenko
2009-06-21 19:19 ` [PATCH] rename kernel.elf to kernel.img (Re: [PATCH] i386-qemu port) Robert Millan
2009-06-22  2:20   ` Pavel Roskin
2009-06-22 10:27     ` Robert Millan
2009-06-21 19:52 ` [PATCH] swap real_to_prot() and prot_to_real() " Robert Millan
2009-06-22  1:56   ` Pavel Roskin
2009-06-22 10:45     ` Robert Millan
2009-06-21 20:22 ` [PATCH] i386-qemu port Robert Millan
2009-06-22  1:50   ` Pavel Roskin
2009-06-22 10:57     ` Robert Millan
2009-06-21 22:53 ` [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port) Robert Millan
2009-06-22  1:22   ` Pavel Roskin
2009-06-22  9:52     ` Robert Millan
2009-06-22 19:39       ` Pavel Roskin
2009-06-22 20:52         ` Robert Millan
2009-06-22 21:32           ` Robert Millan
2009-06-22 21:44             ` Pavel Roskin
2009-06-22 22:43               ` Robert Millan
2009-06-23  0:53                 ` Pavel Roskin
2009-06-23 11:02                   ` Robert Millan
2009-06-22 21:36           ` Pavel Roskin
2009-06-22 22:52             ` Robert Millan
2009-06-22 10:26     ` about Apple compiler (Re: [PATCH] access gdtdesc on segment 0 unconditionally (Re: [PATCH] i386-qemu port)) Robert Millan
2009-06-22 16:10       ` Pavel Roskin
2009-06-22 15:02 ` [PATCH] s/GRUB_MEMORY_MACHINE_LINK_ADDR/GRUB_KERNEL_MACHINE_LINK_ADDR/g (Re: [PATCH] i386-qemu port) Robert Millan
2009-06-22 19:00   ` Pavel Roskin
2009-06-22 23:07 ` clean patch for i386-qemu port " Robert Millan
2009-06-23  1:29   ` Pavel Roskin
2009-06-23 11:38     ` Robert Millan
2009-06-23 12:13       ` Robert Millan
2009-06-24  1:00         ` Robert Millan
2009-06-24 23:10           ` [PATCH] fix for loading modules from read-only memory area (Re: clean patch for i386-qemu port (Re: [PATCH] i386-qemu port)) Robert Millan
2009-06-25 19:53             ` Pavel Roskin
2009-06-25 20:31               ` Robert Millan
2009-06-25 20:51                 ` Pavel Roskin
2009-06-26 14:41                   ` Robert Millan
2009-06-26 16:44                     ` Pavel Roskin
2009-06-26 17:03                       ` Robert Millan
2009-06-26 17:16                         ` Pavel Roskin
2009-06-26 17:43                           ` Robert Millan
2009-06-26 19:52                             ` Pavel Roskin
2009-06-26 22:26                             ` Pavel Roskin
2009-06-26 23:57                               ` Robert Millan
2009-06-27  3:08                                 ` Pavel Roskin
2009-06-27 11:18                                   ` Robert Millan
2009-06-29  3:48                                     ` Pavel Roskin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.