From: Robert Millan <rmh@aybabtu.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: embedding filesystems in core image (Re: moving ata initialisation to a command)
Date: Fri, 21 Dec 2007 21:54:31 +0100 [thread overview]
Message-ID: <20071221205431.GA31264@thorin> (raw)
In-Reply-To: <20071221180405.GA14997@thorin>
[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]
On Fri, Dec 21, 2007 at 07:04:05PM +0100, Robert Millan wrote:
> > >
> > > I'd prefer to support embedding filesystems in core.img instead. This
> > > solves the problem for every situation instead of just PC boot media
> > > (e.g. LinuxBIOS ELF payload image).
> >
> > Agreed, I would like to see such feature. Also for stuff like
> > diskless boot.
> >
> > What I had in mind was the following. We could perhaps make it
> > possible to add all files using grub-mkimage, not only modules. When
> > you add modules, those will be loaded automatically. All other files
> > will be ignored.
> >
> > Another filesystem module has to be written. It scans over these
> > files and will make them available. This can be simple and elegant.
> > I do not like the idea of adding a diskimage or so. Are you
> > interested in working on this?
>
> Well, I already have an almost-working implementation. I guess I'll have to
> defend it then! :-P
>
> Really, it's clean and elegant. Very simple and flexible. Once I get the
> address detection right, that is..
Please have a look at the attached patch. This allows adding an arbitrary
number of files. No extra filesystem module is needed, since any of the
supported filesystems can be used with this feature:
genisoimage -o filesystem_image -r stuff
grub-mkimage -o core.img -m filesystem_image
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call, if you are unable to speak?
(as seen on /.)
[-- Attachment #2: memdisk.diff --]
[-- Type: text/x-diff, Size: 10896 bytes --]
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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/machine/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_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 <grub/types.h>
+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 <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_
}
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);
next prev parent reply other threads:[~2007-12-21 20:54 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-16 15:30 moving ata initialisation to a command Robert Millan
2007-12-16 15:58 ` Christian Franke
2007-12-16 16:06 ` Vesa Jääskeläinen
2007-12-16 16:19 ` Robert Millan
2007-12-17 15:52 ` Marco Gerards
2007-12-17 16:01 ` Marco Gerards
2007-12-17 18:26 ` Pavel Roskin
2007-12-17 19:01 ` Marco Gerards
2007-12-20 17:38 ` Robert Millan
2007-12-20 17:36 ` Robert Millan
2007-12-21 16:47 ` Marco Gerards
2007-12-21 18:04 ` Robert Millan
2007-12-21 20:54 ` Robert Millan [this message]
2007-12-22 4:28 ` embedding filesystems in core image (Re: moving ata initialisation to a command) Bean
2007-12-22 11:24 ` Robert Millan
2007-12-22 12:27 ` Yoshinori K. Okuji
2007-12-22 12:18 ` Robert Millan
2007-12-22 12:24 ` Yoshinori K. Okuji
2007-12-23 18:44 ` Robert Millan
2008-01-16 20:10 ` Marco Gerards
2008-01-20 23:21 ` Robert Millan
2007-12-24 8:29 ` Bean
2007-12-24 13:09 ` Robert Millan
2007-12-24 13:27 ` Bean
2007-12-24 16:24 ` Robert Millan
2007-12-24 16:44 ` Bean
2008-01-02 19:56 ` Robert Millan
2007-12-26 8:00 ` embedding data in ELF " Robert Millan
2008-01-02 18:21 ` Pavel Roskin
2007-12-26 7:57 ` avoid firmware in grub-mkrescue " Robert Millan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071221205431.GA31264@thorin \
--to=rmh@aybabtu.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.