This patch makes memdisk much less dependant on i386-pc specific structures
and therefore easier to port.

-- 
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."
2008-07-30  Robert Millan  <[EMAIL PROTECTED]>

	* disk/memdisk.c (memdisk_size): Don't initialize.
	(GRUB_MOD_INIT(memdisk)): Find memdisk using grub_module_iterate().

	* include/grub/i386/pc/kernel.h
	(GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): Remove macro.
	(GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Shift.
	(grub_memdisk_image_size, grub_arch_memdisk_addr)
	(grub_arch_memdisk_size): Remove.

	* include/grub/kernel.h (struct grub_module_header): Remove `offset'
	field (was only used to transfer a constant).  Add `type' field to
	support multiple module types.
	(grub_module_iterate): New function.

	* kern/device.c (grub_device_open): Do not hide error messages
	when grub_disk_open() fails.  Use grub_print_error() instead.

	* kern/i386/pc/init.c (grub_arch_modules_addr)
	(grub_arch_memdisk_size): Remove functions.

	* kern/i386/pc/startup.S (grub_memdisk_image_size): Remove variable.
	(codestart): Don't add grub_memdisk_image_size to %ecx in LZMA
	decompression routine (grub_total_module_size already includes that
	now).

	* kern/main.c (grub_load_modules): Split out (and use) ...
	(grub_module_iterate): ... this function, which iterates through
	module objects and runs a hook.
	Comment out grub_mm_init_region() call, as it would cause non-ELF
	modules to be overwritten.

	* util/i386/pc/grub-mkimage.c (generate_image): Instead of appending
	the memdisk image in its own region, make it part of the module list.

Index: disk/memdisk.c
===================================================================
--- disk/memdisk.c	(revision 1751)
+++ disk/memdisk.c	(working copy)
@@ -26,7 +26,7 @@
 #include <grub/machine/kernel.h>
 
 static char *memdisk_addr;
-static grub_off_t memdisk_size = 0;
+static grub_off_t memdisk_size;
 
 static int
 grub_memdisk_iterate (int (*hook) (const char *name))
@@ -82,21 +82,22 @@
 
 GRUB_MOD_INIT(memdisk)
 {
-  char *memdisk_orig_addr;
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      if (header->type == OBJ_TYPE_MEMDISK)
+	{
+	  memdisk_addr = (char *) header + sizeof (struct grub_module_header);
+	  memdisk_size = header->size - sizeof (struct grub_module_header);
+	  grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_addr);
+	  grub_disk_dev_register (&grub_memdisk_dev);
+	  return 1;
+	}
 
-  memdisk_size = grub_arch_memdisk_size ();
-  if (! memdisk_size)
-    return;
+      return 0;
+    }
 
-  memdisk_orig_addr = (char *) grub_arch_memdisk_addr ();
-  grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
-
-  memdisk_addr = grub_malloc (memdisk_size);
-
-  grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
-  grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
-
-  grub_disk_dev_register (&grub_memdisk_dev);
+  grub_module_iterate (hook);
 }
 
 GRUB_MOD_FINI(memdisk)
Index: kern/device.c
===================================================================
--- kern/device.c	(revision 1751)
+++ kern/device.c	(working copy)
@@ -50,7 +50,8 @@
   disk = grub_disk_open (name);
   if (! disk)
     {
-      grub_error (GRUB_ERR_BAD_DEVICE, "unknown device %s", name);
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
       goto fail;
     }
 
Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S	(revision 1751)
+++ kern/i386/pc/startup.S	(working copy)
@@ -96,8 +96,6 @@
 	.long	0xFFFFFFFF
 VARIABLE(grub_install_bsd_part)
 	.long	0xFFFFFFFF
-VARIABLE(grub_memdisk_image_size)
-	.long	0
 VARIABLE(grub_prefix)
 	/* to be filled by grub-mkimage */
 
@@ -221,7 +219,6 @@
 	pushl	%esi
 	movl	EXT_C(grub_kernel_image_size), %ecx
 	addl	EXT_C(grub_total_module_size), %ecx
-	addl	EXT_C(grub_memdisk_image_size), %ecx
 	subl	$GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
 	pushl	%ecx
 	leal	(%edi, %ecx), %ebx
Index: kern/i386/pc/init.c
===================================================================
--- kern/i386/pc/init.c	(revision 1751)
+++ kern/i386/pc/init.c	(working copy)
@@ -252,19 +252,3 @@
 {
   return grub_end_addr;
 }
-
-/* Return the start of the memdisk image.  */
-grub_addr_t
-grub_arch_memdisk_addr (void)
-{
-  return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
-    + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE)
-    + grub_total_module_size;
-}
-
-/* Return the size of the memdisk image.  */
-grub_off_t
-grub_arch_memdisk_size (void)
-{
-  return grub_memdisk_image_size;
-}
Index: kern/main.c
===================================================================
--- kern/main.c	(revision 1751)
+++ kern/main.c	(working copy)
@@ -28,9 +28,8 @@
 #include <grub/device.h>
 #include <grub/env.h>
 
-/* Load all modules in core.  */
-static void
-grub_load_modules (void)
+void
+grub_module_iterate (int (*hook) (struct grub_module_header *header))
 {
   struct grub_module_info *modinfo;
   struct grub_module_header *header;
@@ -47,13 +46,38 @@
        header < (struct grub_module_header *) (modbase + modinfo->size);
        header = (struct grub_module_header *) ((char *) header + header->size))
     {
-      if (! grub_dl_load_core ((char *) header + header->offset,
-			       (header->size - header->offset)))
+      if (hook (header))
+	return 1;
+    }
+
+  return 0;
+}
+
+/* Load all modules in core.  */
+static void
+grub_load_modules (void)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      /* Not an ELF module, skip.  */
+      if (header->type != OBJ_TYPE_ELF)
+        return 0;
+
+      if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
+			       (header->size - sizeof (struct grub_module_header))))
 	grub_fatal ("%s", grub_errmsg);
+
+      return 0;
     }
 
+  grub_module_iterate (hook);
+
+/* FIXME: This would destroy memdisk.  */
+#if 0
   /* Add the region where modules reside into dynamic memory.  */
   grub_mm_init_region ((void *) modinfo, modinfo->size);
+#endif
 }
 
 /* Write hook for the environment variables of root. Remove surrounding
Index: include/grub/kernel.h
===================================================================
--- include/grub/kernel.h	(revision 1751)
+++ include/grub/kernel.h	(working copy)
@@ -25,9 +25,15 @@
 /* The module header.  */
 struct grub_module_header
 {
-  /* The offset of object code.  */
-  grub_target_off_t offset;
-  /* The size of object code plus this header.  */
+  /* The type of object.  */
+  int type;
+  enum
+  {
+    OBJ_TYPE_ELF,
+    OBJ_TYPE_MEMDISK,
+  }  grub_module_header_types;
+
+  /* The size of object (including this header).  */
   grub_target_size_t size;
 };
 
@@ -49,6 +55,8 @@
 
 extern grub_addr_t grub_arch_modules_addr (void);
 
+extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *));
+
 /* The start point of the C code.  */
 void grub_main (void);
 
Index: include/grub/i386/pc/kernel.h
===================================================================
--- include/grub/i386/pc/kernel.h	(revision 1753)
+++ include/grub/i386/pc/kernel.h	(working copy)
@@ -34,14 +34,11 @@
 /* The offset of GRUB_INSTALL_BSD_PART.  */
 #define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART	0x18
 
-/* The offset of GRUB_MEMDISK_IMAGE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE	0x1c
-
 /* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX		0x20
+#define GRUB_KERNEL_MACHINE_PREFIX		0x1c
 
 /* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END		0x60
+#define GRUB_KERNEL_MACHINE_DATA_END		0x5c
 
 /* The size of the first region which won't be compressed.  */
 #if defined(ENABLE_LZO)
@@ -67,9 +64,6 @@
 /* The BSD partition number of the installed partition.  */
 extern grub_int32_t grub_install_bsd_part;
 
-/* The size of memory disk image, if present.  */
-extern grub_int32_t grub_memdisk_image_size;
-
 /* The prefix which points to the directory where GRUB modules and its
    configuration file are located.  */
 extern char grub_prefix[];
@@ -83,9 +77,6 @@
 /* The end address of the kernel.  */
 extern grub_addr_t grub_end_addr;
 
-extern grub_addr_t EXPORT_FUNC(grub_arch_memdisk_addr) (void);
-extern grub_off_t EXPORT_FUNC(grub_arch_memdisk_size) (void);
-
 #endif /* ! ASM_FILE */
 
 #endif /* ! KERNEL_MACHINE_HEADER */
Index: util/i386/pc/grub-mkimage.c
===================================================================
--- util/i386/pc/grub-mkimage.c	(revision 1751)
+++ util/i386/pc/grub-mkimage.c	(working copy)
@@ -150,15 +150,16 @@
     total_module_size += (grub_util_get_image_size (p->name)
 			  + sizeof (struct grub_module_header));
 
-  grub_util_info ("the total module size is 0x%x", total_module_size);
-
   if (memdisk_path)
     {
       memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
       grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
+      total_module_size += memdisk_size;
     }
 
-  kernel_img = xmalloc (kernel_size + total_module_size + memdisk_size);
+  grub_util_info ("the total module size is 0x%x", total_module_size);
+
+  kernel_img = xmalloc (kernel_size + total_module_size);
   grub_util_load_image (kernel_path, kernel_img);
 
   if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
@@ -180,7 +181,7 @@
       mod_size = grub_util_get_image_size (p->name);
       
       header = (struct grub_module_header *) (kernel_img + offset);
-      header->offset = grub_cpu_to_le32 (sizeof (*header));
+      header->type = grub_cpu_to_le32 (OBJ_TYPE_ELF);
       header->size = grub_cpu_to_le32 (mod_size + sizeof (*header));
       offset += sizeof (*header);
 
@@ -190,11 +191,18 @@
 
   if (memdisk_path)
     {
+      struct grub_module_header *header;
+      
+      header = (struct grub_module_header *) (kernel_img + offset);
+      header->type = grub_cpu_to_le32 (OBJ_TYPE_MEMDISK);
+      header->size = grub_cpu_to_le32 (memdisk_size + sizeof (*header));
+      offset += sizeof (*header);
+
       grub_util_load_image (memdisk_path, kernel_img + offset);
       offset += memdisk_size;
     }
 
-  compress_kernel (kernel_img, kernel_size + total_module_size + memdisk_size,
+  compress_kernel (kernel_img, kernel_size + total_module_size,
 		   &core_img, &core_size);
 
   grub_util_info ("the core size is 0x%x", core_size);
@@ -229,8 +237,6 @@
     = grub_cpu_to_le32 (total_module_size);
   *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
     = grub_cpu_to_le32 (kernel_size);
-  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE))
-    = grub_cpu_to_le32 (memdisk_size);
   *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
     = grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to