diff -x '*.mk' -Nurp grub2/conf/i386-pc.rmk grub2.memdisk/conf/i386-pc.rmk
--- grub2/conf/i386-pc.rmk 2007-12-21 12:41:23.000000000 +0100
+++ grub2.memdisk/conf/i386-pc.rmk 2007-12-21 21:47:57.000000000 +0100
@@ -39,7 +39,7 @@ kernel_img_HEADERS = arg.h boot.h cache.
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h machine/vga.h machine/vbe.h
+ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h machine/kernel.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,8200 $(COMMON_CFLAGS)
@@ -136,7 +136,7 @@ pkgdata_MODULES = biosdisk.mod _chain.mo
_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \
vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod ata.mod \
- vga.mod
+ vga.mod memdisk.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -263,4 +263,9 @@ vga_mod_SOURCES = term/i386/pc/vga.c
vga_mod_CFLAGS = $(COMMON_CFLAGS)
vga_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 -x '*.mk' -Nurp grub2/disk/memdisk.c grub2.memdisk/disk/memdisk.c
--- grub2/disk/memdisk.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2.memdisk/disk/memdisk.c 2007-12-21 21:43:25.000000000 +0100
@@ -0,0 +1,92 @@
+/* memdisk.c - Access embedded memory disk. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+static grub_addr_t memdisk_addr;
+
+static int
+grub_memdisk_iterate (int (*hook) (const char *name))
+{
+ return hook ("memdisk");
+}
+
+static grub_err_t
+grub_memdisk_open (const char *name, grub_disk_t disk)
+{
+ if (grub_strcmp (name, "memdisk"))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
+
+ disk->total_sectors = grub_memdisk_image_size / GRUB_DISK_SECTOR_SIZE;
+ disk->id = (int) 'mdsk';
+
+ disk->has_partitions = 0;
+ disk->data = NULL;
+
+ return GRUB_ERR_NONE;
+}
+
+static void
+grub_memdisk_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_memdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
+{
+ grub_memcpy (buf, memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS);
+ return 0;
+}
+
+static grub_err_t
+grub_memdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, const char *buf)
+{
+ grub_memcpy (memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf, size << GRUB_DISK_SECTOR_BITS);
+ return 0;
+}
+
+static struct grub_disk_dev grub_memdisk_dev =
+ {
+ .name = "memdisk",
+ .id = GRUB_DISK_DEVICE_MEMDISK_ID,
+ .iterate = grub_memdisk_iterate,
+ .open = grub_memdisk_open,
+ .close = grub_memdisk_close,
+ .read = grub_memdisk_read,
+ .write = grub_memdisk_write,
+ .next = 0
+ };
+
+GRUB_MOD_INIT(memdisk)
+{
+ memdisk_addr = 0x100000 + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE) + grub_total_module_size;
+ grub_disk_dev_register (&grub_memdisk_dev);
+}
+
+GRUB_MOD_FINI(memdisk)
+{
+ grub_disk_dev_unregister (&grub_memdisk_dev);
+}
diff -x '*.mk' -Nurp grub2/include/grub/disk.h grub2.memdisk/include/grub/disk.h
--- grub2/include/grub/disk.h 2007-11-05 17:15:26.000000000 +0100
+++ grub2.memdisk/include/grub/disk.h 2007-12-21 17:47:06.000000000 +0100
@@ -35,7 +35,8 @@ enum grub_disk_dev_id
GRUB_DISK_DEVICE_RAID_ID,
GRUB_DISK_DEVICE_LVM_ID,
GRUB_DISK_DEVICE_HOST_ID,
- GRUB_DISK_DEVICE_ATA_ID
+ GRUB_DISK_DEVICE_ATA_ID,
+ GRUB_DISK_DEVICE_MEMDISK_ID,
};
struct grub_disk;
diff -x '*.mk' -Nurp grub2/include/grub/i386/pc/kernel.h grub2.memdisk/include/grub/i386/pc/kernel.h
--- grub2/include/grub/i386/pc/kernel.h 2007-07-22 01:32:23.000000000 +0200
+++ grub2.memdisk/include/grub/i386/pc/kernel.h 2007-12-21 18:22:26.000000000 +0100
@@ -34,8 +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 0x1c
+#define GRUB_KERNEL_MACHINE_PREFIX 0x20
/* End of the data section. */
#define GRUB_KERNEL_MACHINE_DATA_END 0x50
@@ -47,6 +50,10 @@
#include
+extern grub_int32_t EXPORT_VAR(grub_kernel_image_size);
+extern grub_int32_t EXPORT_VAR(grub_total_module_size);
+extern grub_int32_t EXPORT_VAR(grub_memdisk_image_size);
+
/* The DOS partition number of the installed partition. */
extern grub_int32_t grub_install_dos_part;
diff -x '*.mk' -Nurp grub2/kern/i386/pc/startup.S grub2.memdisk/kern/i386/pc/startup.S
--- grub2/kern/i386/pc/startup.S 2007-10-22 22:14:45.000000000 +0200
+++ grub2.memdisk/kern/i386/pc/startup.S 2007-12-21 17:53:01.000000000 +0100
@@ -95,6 +95,8 @@ 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 */
diff -x '*.mk' -Nurp grub2/util/i386/pc/grub-mkimage.c grub2.memdisk/util/i386/pc/grub-mkimage.c
--- grub2/util/i386/pc/grub-mkimage.c 2007-07-22 01:32:32.000000000 +0200
+++ grub2.memdisk/util/i386/pc/grub-mkimage.c 2007-12-21 21:46:35.000000000 +0100
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
@@ -75,11 +76,11 @@ compress_kernel (char *kernel_img, size_
}
static void
-generate_image (const char *dir, char *prefix, FILE *out, char *mods[])
+generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path)
{
grub_addr_t module_addr = 0;
char *kernel_img, *boot_img, *core_img;
- size_t kernel_size, boot_size, total_module_size, core_size;
+ size_t kernel_size, boot_size, total_module_size, core_size, memdisk_size = 0;
char *kernel_path, *boot_path;
unsigned num;
size_t offset;
@@ -98,7 +99,13 @@ generate_image (const char *dir, char *p
grub_util_info ("the total module size is 0x%x", total_module_size);
- kernel_img = xmalloc (kernel_size + 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);
grub_util_load_image (kernel_path, kernel_img);
if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
@@ -122,13 +129,19 @@ generate_image (const char *dir, char *p
header = (struct grub_module_header *) (kernel_img + offset);
header->offset = grub_cpu_to_le32 (sizeof (*header));
header->size = grub_cpu_to_le32 (mod_size + sizeof (*header));
-
- grub_util_load_image (p->name, kernel_img + offset + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (p->name, kernel_img + offset);
+ offset += mod_size;
+ }
- offset += sizeof (*header) + mod_size;
+ if (memdisk_path)
+ {
+ grub_util_load_image (memdisk_path, kernel_img + offset);
+ offset += memdisk_size;
}
- compress_kernel (kernel_img, kernel_size + total_module_size,
+ compress_kernel (kernel_img, kernel_size + total_module_size + memdisk_size,
&core_img, &core_size);
grub_util_info ("the core size is 0x%x", core_size);
@@ -163,6 +176,8 @@ generate_image (const char *dir, char *p
= 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);
@@ -186,6 +201,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'},
{"version", no_argument, 0, 'V'},
@@ -206,6 +222,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 [default=%s]\n\
+ -m, --memdisk=FILE embed FILE as a memdisk image\n\
-o, --output=FILE output a generated image to FILE [default=stdout]\n\
-h, --help display this message and exit\n\
-V, --version print version information and exit\n\
@@ -223,13 +240,14 @@ main (int argc, char *argv[])
char *output = NULL;
char *dir = NULL;
char *prefix = NULL;
+ char *memdisk = NULL;
FILE *fp = stdout;
progname = "grub-mkimage";
while (1)
{
- int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0);
+ int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0);
if (c == -1)
break;
@@ -250,6 +268,13 @@ main (int argc, char *argv[])
dir = xstrdup (optarg);
break;
+ case 'm':
+ if (memdisk)
+ free (memdisk);
+
+ memdisk = xstrdup (optarg);
+ break;
+
case 'h':
usage (0);
break;
@@ -282,7 +307,7 @@ main (int argc, char *argv[])
grub_util_error ("cannot open %s", output);
}
- generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind);
+ generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk);
fclose (fp);