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().
This commit is contained in:
robertmh 2008-01-20 23:20:36 +00:00
parent 3d7f54c94d
commit 55a581dc06
11 changed files with 272 additions and 16 deletions

View File

@ -1,3 +1,46 @@
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

View File

@ -180,7 +180,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
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)
@ -915,7 +915,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
_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
@ -2424,4 +2424,56 @@ fs-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c genfslist.sh
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

View File

@ -39,7 +39,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
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 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
_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
@ -264,4 +264,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

94
disk/memdisk.c Normal file
View File

@ -0,0 +1,94 @@
/* 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);
}

View File

@ -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;

View File

@ -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,12 +50,21 @@
#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[];

View File

@ -48,6 +48,9 @@
#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

View File

@ -20,6 +20,7 @@
#define GRUB_KERNEL_HEADER 1
#include <grub/types.h>
#include <grub/symbol.h>
/* The module header. */
struct grub_module_header
@ -44,6 +45,8 @@ struct grub_module_info
};
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);

View File

@ -248,3 +248,19 @@ 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;
}

View File

@ -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 */
@ -196,7 +198,7 @@ codestart:
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

View File

@ -25,6 +25,7 @@
#include <grub/disk.h>
#include <grub/util/misc.h>
#include <grub/util/resolve.h>
#include <grub/misc.h>
#include <stdio.h>
#include <unistd.h>
@ -75,11 +76,11 @@ compress_kernel (char *kernel_img, size_t kernel_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 *prefix, FILE *out, char *mods[])
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 *prefix, FILE *out, char *mods[])
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);
offset += sizeof (*header) + mod_size;
grub_util_load_image (p->name, kernel_img + offset);
offset += mod_size;
}
compress_kernel (kernel_img, kernel_size + total_module_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 + 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 *prefix, FILE *out, char *mods[])
= 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);