diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 4b509139c..51e8a5715 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -86,11 +86,16 @@ grub_machine_fini (int flags) +#define OPT_MEMDISK 257 + static struct argp_option options[] = { {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"device-map", 'm', N_("FILE"), 0, /* TRANSLATORS: There are many devices in device map. */ N_("use FILE as the device map [default=%s]"), 0}, + {"memdisk", OPT_MEMDISK, N_("FILE"), 0, + /* TRANSLATORS: There are many devices in device map. */ + N_("use FILE as memdisk"), 0}, {"directory", 'd', N_("DIR"), 0, N_("use GRUB files in the directory DIR [default=%s]"), 0}, {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, @@ -119,6 +124,7 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused))) struct arguments { const char *dev_map; + const char *mem_disk; int hold; }; @@ -131,6 +137,9 @@ argp_parser (int key, char *arg, struct argp_state *state) switch (key) { + case OPT_MEMDISK: + arguments->mem_disk = arg; + break; case 'r': free (root_dev); root_dev = xstrdup (arg); @@ -180,9 +189,13 @@ main (int argc, char *argv[]) struct arguments arguments = { .dev_map = DEFAULT_DEVICE_MAP, - .hold = 0 + .hold = 0, + .mem_disk = 0, }; volatile int hold = 0; + size_t total_module_size = sizeof (struct grub_module_info), memdisk_size = 0; + struct grub_module_info *modinfo; + char *mods; grub_util_host_init (&argc, &argv); @@ -194,6 +207,33 @@ main (int argc, char *argv[]) exit(1); } + if (arguments.mem_disk) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (arguments.mem_disk), 512); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + mods = xmalloc (total_module_size); + modinfo = grub_memset (mods, 0, total_module_size); + mods = (char *) (modinfo + 1); + + modinfo->magic = GRUB_MODULE_MAGIC; + modinfo->offset = sizeof (struct grub_module_info); + modinfo->size = total_module_size; + + if (arguments.mem_disk) + { + struct grub_module_header *header = (struct grub_module_header *) mods; + header->type = OBJ_TYPE_MEMDISK; + header->size = memdisk_size + sizeof (*header); + mods += sizeof (*header); + + grub_util_load_image (arguments.mem_disk, mods); + mods += memdisk_size; + } + + grub_modbase = (grub_addr_t) modinfo; + hold = arguments.hold; /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ if (hold && verbosity > 0) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 31a1f294d..884c823d8 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -449,7 +449,8 @@ if [ x$boot = xnet ]; then [ -z "$files" ] || copy_extra_files "$netdir" $files timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim elif [ x$boot = xemu ]; then - grubdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" + rootdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" + grubdir="$rootdir/boot/grub" mkdir -p "$grubdir/fonts" mkdir -p "$grubdir/themes" mkdir -p "$grubdir/locale" @@ -462,8 +463,12 @@ elif [ x$boot = xemu ]; then done cp "${cfgfile}" "$grubdir/grub.cfg" cp "${source}" "$grubdir/testcase.cfg" - @builddir@/grub-core/grub-emu -m "$device_map" -d "$grubdir" | tr -d "\r" | do_trim - rm -rf "$grubdir" + [ -z "$files" ] || copy_extra_files "$rootdir" $files + roottar="$(mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" + (cd "$rootdir"; tar cf "$roottar" .) + @builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | do_trim + test -n "$debug" || rm -rf "$rootdir" + test -n "$debug" || rm -f "$roottar" else timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | do_trim fi