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