From 3bd0a12acabe1913342f47fa2d3b6cfc88bd2fe5 Mon Sep 17 00:00:00 2001 From: robertmh Date: Sat, 2 Aug 2008 12:17:44 +0000 Subject: [PATCH] 2008-08-02 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. * 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. * util/i386/efi/grub-mkimage.c (make_mods_section): Initialize `header.type' instead of `header.offset'. * 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. --- ChangeLog | 52 ++++++++++++++++++++++++++++++ conf/i386-coreboot.mk | 59 ++++++++++++++++++++++++++++++++++- conf/i386-coreboot.rmk | 7 ++++- conf/i386-ieee1275.mk | 59 ++++++++++++++++++++++++++++++++++- conf/i386-ieee1275.rmk | 7 ++++- conf/powerpc-ieee1275.mk | 59 ++++++++++++++++++++++++++++++++++- conf/powerpc-ieee1275.rmk | 7 ++++- disk/memdisk.c | 29 +++++++++++------ include/grub/i386/pc/kernel.h | 13 ++------ include/grub/kernel.h | 14 +++++++-- kern/device.c | 3 +- kern/i386/pc/init.c | 17 +--------- kern/i386/pc/startup.S | 9 +++--- kern/main.c | 31 +++++++++++++----- util/elf/grub-mkimage.c | 50 ++++++++++++++++++++++++----- util/i386/efi/grub-mkimage.c | 2 +- util/i386/pc/grub-mkimage.c | 29 ++++++++++------- 17 files changed, 368 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8e55a957..eb9bdd22d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2008-08-02 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. + * 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. + * util/i386/efi/grub-mkimage.c (make_mods_section): Initialize + `header.type' instead of `header.offset'. + + * 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. + 2008-08-02 Robert Millan * loader/i386/pc/multiboot.c (playground, forward_relocator) diff --git a/conf/i386-coreboot.mk b/conf/i386-coreboot.mk index 41fc37b3d..efd9e4df8 100644 --- a/conf/i386-coreboot.mk +++ b/conf/i386-coreboot.mk @@ -555,7 +555,7 @@ grub_emu_LDFLAGS = $(LIBCURSES) # 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 @@ -1458,4 +1458,61 @@ partmap-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genpartmapli ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 5b110d9cc..a6a997340 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -94,7 +94,7 @@ grub_emu_LDFLAGS = $(LIBCURSES) # 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_SOURCES = disk/ata.c 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 diff --git a/conf/i386-ieee1275.mk b/conf/i386-ieee1275.mk index 591408433..0c0f6220e 100644 --- a/conf/i386-ieee1275.mk +++ b/conf/i386-ieee1275.mk @@ -589,7 +589,7 @@ grub-install: util/ieee1275/grub-install.in $(util/ieee1275/grub-install.in_DEPE # 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 \ @@ -1586,4 +1586,61 @@ partmap-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/na nand_mod_CFLAGS = $(COMMON_CFLAGS) nand_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 03827ae7c..03b4173f3 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -102,7 +102,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in # 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_SOURCES = disk/ieee1275/nand.c 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 diff --git a/conf/powerpc-ieee1275.mk b/conf/powerpc-ieee1275.mk index f9bdfe36e..cb9351d68 100644 --- a/conf/powerpc-ieee1275.mk +++ b/conf/powerpc-ieee1275.mk @@ -583,7 +583,8 @@ pkglib_MODULES = halt.mod \ reboot.mod \ suspend.mod \ _multiboot.mod \ - multiboot.mod + multiboot.mod \ + memdisk.mod # For _linux.mod. _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c @@ -1352,6 +1353,62 @@ partmap-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loade multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) include $(srcdir)/conf/common.mk diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 6ade1ab63..9d7a6727d 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -110,7 +110,8 @@ pkglib_MODULES = halt.mod \ 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_SOURCES = loader/multiboot_loader_normal.c 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 diff --git a/disk/memdisk.c b/disk/memdisk.c index d7f0670d1..978eae553 100644 --- a/disk/memdisk.c +++ b/disk/memdisk.c @@ -82,21 +82,30 @@ static struct grub_disk_dev grub_memdisk_dev = 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) diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index a00117bd7..b6650bc89 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -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 @@ extern grub_int32_t grub_install_dos_part; /* 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 @@ extern grub_int32_t grub_root_drive; /* 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 */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 9cbbdaf22..0401c3aa2 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -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 @@ struct grub_module_info 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); diff --git a/kern/device.c b/kern/device.c index 1b5a77c00..0b44f381a 100644 --- a/kern/device.c +++ b/kern/device.c @@ -50,7 +50,8 @@ grub_device_open (const char *name) 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; } diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index e47cbfd86..6386686bd 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -249,22 +249,7 @@ grub_machine_fini (void) /* Return the end of the core image. */ 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; -} - -/* Return the size of the memdisk image. */ -grub_off_t -grub_arch_memdisk_size (void) -{ - return grub_memdisk_image_size; + + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); } diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 75c46adee..aa582ac49 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -96,8 +96,6 @@ VARIABLE(grub_install_dos_part) .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 @@ codestart: call lzo1x_decompress addl $12, %esp - /* copy back the decompressed part */ movl %eax, %ecx cld #elif defined(ENABLE_LZMA) @@ -221,19 +218,22 @@ codestart: 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 @@ codestart: std rep movsb +#endif /* clean out the bss */ movl $BSS_START_SYMBOL, %edi diff --git a/kern/main.c b/kern/main.c index 5b59d41f4..acf6911dd 100644 --- a/kern/main.c +++ b/kern/main.c @@ -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 @@ grub_load_modules (void) 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 diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index a27567a36..d53737c7f 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -97,19 +97,26 @@ load_note (Elf32_Phdr *phdr, FILE *out) void load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, - char *mods[], FILE *out) + char *mods[], FILE *out, char *memdisk_path) { char *module_img; struct grub_util_path_list *path_list; struct grub_util_path_list *p; struct grub_module_info *modinfo; - size_t offset; - size_t total_module_size; + size_t offset, total_module_size, memdisk_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); offset = sizeof (struct grub_module_info); total_module_size = sizeof (struct grub_module_info); + + 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); + } + for (p = path_list; p; p = p->next) { total_module_size += (grub_util_get_image_size (p->name) @@ -135,7 +142,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, mod_size = grub_util_get_image_size (p->name); header = (struct grub_module_header *) (module_img + offset); - header->offset = grub_host_to_target32 (sizeof (*header)); + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); header->size = grub_host_to_target32 (mod_size + sizeof (*header)); grub_util_load_image (p->name, module_img + offset + sizeof (*header)); @@ -143,6 +150,20 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, offset += sizeof (*header) + mod_size; } + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (module_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, module_img + offset); + offset += memdisk_size; + } + + /* Write the module data to the new segment. */ grub_util_write_image_at (module_img, total_module_size, grub_host_to_target32 (phdr->p_offset), out); @@ -158,7 +179,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, } void -add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[]) +add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path) { Elf32_Ehdr ehdr; Elf32_Phdr *phdrs = NULL; @@ -247,7 +268,7 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[]) phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), GRUB_TARGET_SIZEOF_LONG)); - load_modules (modbase, phdr, dir, mods, out); + load_modules (modbase, phdr, dir, mods, out, memdisk_path); } if (chrp) @@ -289,6 +310,7 @@ static struct option options[] = { {"directory", required_argument, 0, 'd'}, {"prefix", required_argument, 0, 'p'}, + {"memdisk", required_argument, 0, 'm'}, {"output", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {"note", no_argument, 0, 'n'}, @@ -310,6 +332,7 @@ Make a bootable image of GRUB.\n\ \n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ -p, --prefix=DIR set grub_prefix directory\n\ +-m, --memdisk=FILE embed FILE as a memdisk image\n\ -o, --output=FILE output a generated image to FILE\n\ -h, --help display this message and exit\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ @@ -329,13 +352,14 @@ main (int argc, char *argv[]) char *output = NULL; char *dir = NULL; char *prefix = NULL; + char *memdisk = NULL; int chrp = 0; progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:p:o:hVvn", options, 0); + int c = getopt_long (argc, argv, "d:p:m:o:hVvn", options, 0); if (c == -1) break; @@ -350,6 +374,16 @@ main (int argc, char *argv[]) if (prefix) free (prefix); prefix = xstrdup (optarg); + break; + case 'm': + if (memdisk) + free (memdisk); + memdisk = xstrdup (optarg); + + if (prefix) + free (prefix); + prefix = xstrdup ("(memdisk)/boot/grub"); + break; case 'h': usage (0); @@ -381,7 +415,7 @@ main (int argc, char *argv[]) if (! fp) grub_util_error ("cannot open %s", output); - add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind); + add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk); fclose (fp); diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c index db2653119..eac119b47 100644 --- a/util/i386/efi/grub-mkimage.c +++ b/util/i386/efi/grub-mkimage.c @@ -716,7 +716,7 @@ make_mods_section (FILE *out, Elf_Addr current_address, grub_util_info ("adding module %s", p->name); mod_size = grub_util_get_image_size (p->name); - 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)); mod_image = grub_util_read_image (p->name); diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c index 1c27284ee..4625b6ddb 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/i386/pc/grub-mkimage.c @@ -146,19 +146,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me kernel_size = grub_util_get_image_size (kernel_path); total_module_size = sizeof (struct grub_module_info); + + 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); + } + 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); - } - - kernel_img = xmalloc (kernel_size + total_module_size + memdisk_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 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me 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 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me 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 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me = 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);