2008-07-30 Robert Millan
* 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.
(grub_arch_modules_addr): Return the module address in high memory
(now that it isn't copied anymore).
* 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). Don't copy modules back to low memory.
* kern/main.c: Include `'.
(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 1754)
+++ disk/memdisk.c (working copy)
@@ -82,21 +82,30 @@
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)
+ {
+ char *memdisk_orig_addr;
+ memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
- memdisk_size = grub_arch_memdisk_size ();
- if (! memdisk_size)
- return;
+ grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
- memdisk_orig_addr = (char *) grub_arch_memdisk_addr ();
- grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
+ memdisk_size = header->size - sizeof (struct grub_module_header);
+ memdisk_addr = grub_malloc (memdisk_size);
- 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_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);
+ return 1;
+ }
- grub_disk_dev_register (&grub_memdisk_dev);
+ return 0;
+ }
+
+ grub_module_iterate (hook);
}
GRUB_MOD_FINI(memdisk)
Index: kern/device.c
===================================================================
--- kern/device.c (revision 1754)
+++ 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 1754)
+++ 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 */
@@ -211,7 +209,6 @@
call lzo1x_decompress
addl $12, %esp
- /* copy back the decompressed part */
movl %eax, %ecx
cld
#elif defined(ENABLE_LZMA)
@@ -221,19 +218,22 @@
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
call _LzmaDecodeA
+ /* _LzmaDecodeA clears DF, so no need to run cld */
popl %ecx
popl %edi
popl %esi
#endif
+ /* copy back the decompressed part (except the modules) */
+ subl EXT_C(grub_total_module_size), %ecx
rep
movsb
+#if 0
/* copy modules before cleaning out the bss */
movl EXT_C(grub_total_module_size), %ecx
movl EXT_C(grub_kernel_image_size), %esi
@@ -246,6 +246,7 @@
std
rep
movsb
+#endif
/* clean out the bss */
movl $BSS_START_SYMBOL, %edi
Index: kern/i386/pc/init.c
===================================================================
--- kern/i386/pc/init.c (revision 1754)
+++ kern/i386/pc/init.c (working copy)
@@ -250,21 +250,6 @@
grub_addr_t
grub_arch_modules_addr (void)
{
- 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;
+ + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_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 1754)
+++ kern/main.c (working copy)
@@ -19,7 +19,6 @@
#include
#include
-#include
#include
#include
#include
@@ -28,9 +27,8 @@
#include
#include
-/* 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 +45,30 @@
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))
+ break;
+ }
+}
+
+/* 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;
}
- /* Add the region where modules reside into dynamic memory. */
- grub_mm_init_region ((void *) modinfo, modinfo->size);
+ grub_module_iterate (hook);
}
/* Write hook for the environment variables of root. Remove surrounding
Index: include/grub/kernel.h
===================================================================
--- include/grub/kernel.h (revision 1754)
+++ 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. */
+ grub_int8_t 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 1754)
+++ 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 1754)
+++ util/i386/pc/grub-mkimage.c (working copy)
@@ -146,19 +146,21 @@
kernel_size = grub_util_get_image_size (kernel_path);
total_module_size = sizeof (struct grub_module_info);
- for (p = path_list; p; p = p->next)
- 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 + sizeof (struct grub_module_header);
}
- kernel_img = xmalloc (kernel_size + total_module_size + memdisk_size);
+ for (p = path_list; p; p = p->next)
+ 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);
+
+ 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 +182,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 +192,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 +238,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);