On Wed, Jul 30, 2008 at 08:51:57PM +0200, Robert Millan wrote: > > This patch makes memdisk much less dependant on i386-pc specific structures > and therefore easier to port.
Here we go again, after some suggestions from Bean on IRC. It does now stop copiing the module section to low memory. Instead, we just make sure memdisk grabs its own copy of the data (as is done with ELF modules), and use the module section at GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR for the whole dance. Ah, and it saves 40 bytes in kernel, and 48 bytes in memdisk :-) -- 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. (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/mm.h>'. (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 <grub/kernel.h> #include <grub/misc.h> -#include <grub/mm.h> #include <grub/symbol.h> #include <grub/dl.h> #include <grub/term.h> @@ -28,9 +27,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 +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);
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel