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. * 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 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 #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 +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);