* conf/i386-pc.rmk (kernel_img_HEADERS): Add `machine/kernel.h'.
(pkglib_MODULES): Add `memdisk.mod'.
(memdisk_mod_SOURCES): New variable.
(memdisk_mod_CFLAGS): Likewise.
(memdisk_mod_LDFLAGS): Likewise.
* disk/memdisk.c: New file.
* include/grub/disk.h (grub_disk_dev_id): Add
`GRUB_DISK_DEVICE_MEMDISK_ID'.
* include/grub/i386/pc/kernel.h
(GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): New macro.
(GRUB_KERNEL_MACHINE_PREFIX): Increment by 4.
(grub_kernel_image_size): New variable declaration.
(grub_total_module_size): Likewise.
(grub_memdisk_image_size): Likewise.
* include/grub/i386/pc/memory.h
(GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR): New macro.
* include/grub/kernel.h: Include `<grub/symbol.h>'.
(grub_arch_memdisk_addr): New variable declaration.
(grub_arch_memdisk_size): Likewise.
* kern/i386/pc/init.c (grub_arch_memdisk_addr): New function.
(grub_arch_memdisk_size): Likewise.
* kern/i386/pc/startup.S (grub_memdisk_image_size): New variable.
(codestart): Replace hardcoded `0x100000' with
`GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR' macro.
* util/i386/pc/grub-mkimage.c: Include `<grub/misc.h>'.
(generate_image): Add `memdisk_path' parameter. When `memdisk_path' is
not NULL, append the contents of the file it refers to, at the end of
the compressed kernel image. Initialize `grub_memdisk_image_size'
variable (at `GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE' offset).
(options): Add "memdisk"|'m' option.
(main): Parse --memdisk|-m option, and pass user-provided path as
parameter to generate_image().
+2008-01-21 Robert Millan <rmh@aybabtu.com>
+
+ * conf/i386-pc.rmk (kernel_img_HEADERS): Add `machine/kernel.h'.
+ (pkglib_MODULES): Add `memdisk.mod'.
+ (memdisk_mod_SOURCES): New variable.
+ (memdisk_mod_CFLAGS): Likewise.
+ (memdisk_mod_LDFLAGS): Likewise.
+
+ * disk/memdisk.c: New file.
+
+ * include/grub/disk.h (grub_disk_dev_id): Add
+ `GRUB_DISK_DEVICE_MEMDISK_ID'.
+
+ * include/grub/i386/pc/kernel.h
+ (GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): New macro.
+ (GRUB_KERNEL_MACHINE_PREFIX): Increment by 4.
+ (grub_kernel_image_size): New variable declaration.
+ (grub_total_module_size): Likewise.
+ (grub_memdisk_image_size): Likewise.
+
+ * include/grub/i386/pc/memory.h
+ (GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR): New macro.
+
+ * include/grub/kernel.h: Include `<grub/symbol.h>'.
+ (grub_arch_memdisk_addr): New variable declaration.
+ (grub_arch_memdisk_size): Likewise.
+
+ * kern/i386/pc/init.c (grub_arch_memdisk_addr): New function.
+ (grub_arch_memdisk_size): Likewise.
+
+ * kern/i386/pc/startup.S (grub_memdisk_image_size): New variable.
+ (codestart): Replace hardcoded `0x100000' with
+ `GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR' macro.
+
+ * util/i386/pc/grub-mkimage.c: Include `<grub/misc.h>'.
+ (generate_image): Add `memdisk_path' parameter. When `memdisk_path' is
+ not NULL, append the contents of the file it refers to, at the end of
+ the compressed kernel image. Initialize `grub_memdisk_image_size'
+ variable (at `GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE' offset).
+ (options): Add "memdisk"|'m' option.
+ (main): Parse --memdisk|-m option, and pass user-provided path as
+ parameter to generate_image().
+
2008-01-20 Robert Millan <rmh@aybabtu.com>
* kern/sparc64/ieee1275/openfw.c (grub_devalias_iterate): Copy debug
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)
_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
+ ata.mod vga.mod memdisk.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
vga_mod_CFLAGS = $(COMMON_CFLAGS)
vga_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
+ -rm -f $@
+ $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+ $(STRIP) --strip-unneeded -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
+ $(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
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c 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 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)
+
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
include $(srcdir)/conf/common.mk
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)
_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
+ ata.mod vga.mod memdisk.mod
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.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
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+
+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_arch_memdisk_size () / GRUB_DISK_SECTOR_SIZE;
+ disk->id = (int) 'mdsk';
+ disk->has_partitions = 0;
+
+ 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 __attribute((unused)), 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 __attribute((unused)), 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)
+{
+ if (! grub_arch_memdisk_size ())
+ return;
+ memdisk_addr = grub_arch_memdisk_addr ();
+ grub_disk_dev_register (&grub_memdisk_dev);
+}
+
+GRUB_MOD_FINI(memdisk)
+{
+ if (! grub_arch_memdisk_size ())
+ return;
+ grub_disk_dev_unregister (&grub_memdisk_dev);
+}
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;
/* 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
#include <grub/types.h>
+/* The size of kernel image. */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel. */
+extern grub_int32_t grub_total_module_size;
+
/* The DOS partition number of the installed partition. */
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[];
#define GRUB_MEMORY_MACHINE_RESERVED_END \
(GRUB_MEMORY_MACHINE_PROT_STACK + 0x10)
+/* The area where GRUB is decompressed at early startup. */
+#define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR 0x100000
+
/* The address of a partition table passed to another boot loader. */
#define GRUB_MEMORY_MACHINE_PART_TABLE_ADDR 0x7be
#define GRUB_KERNEL_HEADER 1
#include <grub/types.h>
+#include <grub/symbol.h>
/* The module header. */
struct grub_module_header
};
extern grub_addr_t grub_arch_modules_addr (void);
+extern grub_addr_t EXPORT_FUNC(grub_arch_memdisk_addr) (void);
+extern grub_off_t EXPORT_FUNC(grub_arch_memdisk_size) (void);
/* The start point of the C code. */
void grub_main (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;
+}
.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 */
call EXT_C(grub_gate_a20)
/* decompress the compressed part and put the result at 1MB */
- movl $0x100000, %esi
+ movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %esi
movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %edi
pushl %esi
#include <grub/disk.h>
#include <grub/util/misc.h>
#include <grub/util/resolve.h>
+#include <grub/misc.h>
#include <stdio.h>
#include <unistd.h>
}
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;
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)
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);
= 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);
{
{"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'},
\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\
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;
dir = xstrdup (optarg);
break;
+ case 'm':
+ if (memdisk)
+ free (memdisk);
+
+ memdisk = xstrdup (optarg);
+ break;
+
case 'h':
usage (0);
break;
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);