make memdisk portable
PATCH 1/1 make memdisk portable
This patch makes memdisk much less dependant on i386-pc specific structures and therefore easier to port.
Signature · 5 lines
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.
memdisk.c +15 -14
@@ -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; + autoint 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)
device.c +2 -1
@@ -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; }
i386/pc/startup.S +0 -3
@@ -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
i386/pc/init.c +0 -16
@@ -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; -}
main.c +29 -5
@@ -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 ) +{ + autoint 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
grub/kernel.h +11 -3
@@ -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 );
grub/i386/pc/kernel.h +2 -11
@@ -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 */
i386/pc/grub-mkimage.c +13 -7
@@ -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 );
Quoted 3 lines · Robert Millan
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 :-)
Signature · 5 lines
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.
memdisk.c +19 -10
@@ -82,21 +82,30 @@GRUB_MOD_INIT (memdisk) { -char *memdisk_orig_addr; + autoint 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)
device.c +2 -1
@@ -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; }
i386/pc/startup.S +5 -4
@@ -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
i386/pc/init.c +1 -16
@@ -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; -}
main.c +23 -8
@@ -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 ) +{ + autoint 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
grub/kernel.h +11 -3
@@ -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 );
grub/i386/pc/kernel.h +2 -11
@@ -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 */
i386/pc/grub-mkimage.c +17 -10
@@ -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 );
New patch. Also enable it for ELF platforms (coreboot, ieee1275).
Signature · 5 lines
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-31 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.
* util/elf/grub-mkimage.c (options): Add "memdisk"|'m' option. (main): Parse --memdisk|-m option, and pass user-provided path as parameter to generate_image().
(add_segments): Pass `memdisk_path' down to load_modules(). (load_modules): Embed memdisk image in module section when requested.
* conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add `memdisk.mod'. (memdisk_mod_SOURCES, memdisk_mod_CFLAGS) (memdisk_mod_LDFLAGS): New variables.
* conf/i386-coreboot.rmk: Likewise.
* conf/i386-ieee1275.rmk: Likewise.
i386-coreboot.rmk +6 -1
@@ -94,7 +94,7 @@ # Modules. pkglib_MODULES = _linux.mod linux.mod normal.mod \ _multiboot.mod multiboot.mod aout.mod \ - play.mod cpuid.mod serial.mod ata.mod + play.mod cpuid.mod serial.mod ata.mod memdisk.mod # For _linux.mod. _linux_mod_SOURCES = loader/i386/pc/linux.c
@@ -154,4 +154,9 @@ ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk
powerpc-ieee1275.rmk +6 -1
@@ -110,7 +110,8 @@ reboot.mod \ suspend.mod \ _multiboot.mod \ - multiboot.mod + multiboot.mod \ + memdisk.mod # For _linux.mod. _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -159,6 +160,10 @@ multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) include $(srcdir)/conf/common.mk
i386-ieee1275.rmk +6 -1
@@ -102,7 +102,7 @@ # Modules. pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod cpuid.mod \ multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \ - _linux.mod nand.mod + _linux.mod nand.mod memdisk.mod # For normal.mod. normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
@@ -171,4 +171,9 @@ nand_mod_CFLAGS = $(COMMON_CFLAGS) nand_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk
memdisk.c +19 -10
@@ -82,21 +82,30 @@GRUB_MOD_INIT (memdisk) { -char *memdisk_orig_addr; + autoint 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)
device.c +2 -1
@@ -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; }
i386/pc/startup.S +5 -4
@@ -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
i386/pc/init.c +1 -16
@@ -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; -}
main.c +23 -8
@@ -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 ) +{ + autoint 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
grub/kernel.h +11 -3
@@ -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 );
grub/i386/pc/kernel.h +2 -11
@@ -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 */
i386/pc/grub-mkimage.c +17 -10
@@ -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 );
elf/grub-mkimage.c +42 -8
126 lines not on this page · raw message
Committed.
Signature · 5 lines
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."