=== modified file 'ChangeLog'
--- old/ChangeLog 2010-09-15 23:05:16 +0000
+++ new/ChangeLog 2010-09-15 23:43:38 +0000
@@ -1,5 +1,20 @@
2010-09-16 Szymon Janc
+ New module xzmemdisk.mod.
+ Support for XZ compressed memory disk in grub-mkimage.
+
+ * grub-core/disk/xzmemdisk.c: New file.
+ * grub-core/Makefile.core.def (xzmemdisk): New module.
+ * include/grub/disk.h (grub_disk_dev_id): Add
+ GRUB_DISK_DEVICE_XZMEMDISK_ID.
+ * include/grub/kernel.h (OBJ_TYPE_XZMEMDISK): New enum value.
+ * util/grub-mkimage.c: (generate_image): New parameter (int xz) to mark
+ memory disk as XZ compressed. Callers updated.
+ * util/grub-mkimage.c: New options (-M, --xzmemdisk) to include XZ
+ compressed memdisk into image.
+
+2010-09-16 Szymon Janc
+
Move some xz generic code from grub-core/io/xzio.c to
grub-core/lib/xzembed/xz_misc.{h|c}. It will be used in xzmemdisk.
=== modified file 'grub-core/Makefile.core.def'
--- old/grub-core/Makefile.core.def 2010-09-15 23:05:16 +0000
+++ new/grub-core/Makefile.core.def 2010-09-15 23:43:38 +0000
@@ -759,6 +759,16 @@
};
module = {
+ name = xzmemdisk;
+ common = disk/xzmemdisk.c;
+ common = lib/xzembed/xz_dec_bcj.c;
+ common = lib/xzembed/xz_dec_lzma2.c;
+ common = lib/xzembed/xz_dec_stream.c;
+ common = lib/xzembed/xz_misc.c;
+ cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
+};
+
+module = {
name = ata;
common = disk/ata.c;
enable = pci;
=== added file 'grub-core/disk/xzmemdisk.c'
--- old/grub-core/disk/xzmemdisk.c 1970-01-01 00:00:00 +0000
+++ new/grub-core/disk/xzmemdisk.c 2010-09-15 23:43:38 +0000
@@ -0,0 +1,187 @@
+/* xzmemdisk.c - Access embedded xz compressed memory disk. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 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
+
+#include "xz.h"
+#include "xz_stream.h"
+#include "xz_misc.h"
+
+static grub_uint8_t *xzmemdisk_addr = 0;
+static grub_off_t xzmemdisk_size = 0;
+
+static int
+grub_xzmemdisk_iterate (int (*hook) (const char *name))
+{
+ return hook ("xzmemdisk");
+}
+
+static grub_err_t
+grub_xzmemdisk_open (const char *name, grub_disk_t disk)
+{
+ if (grub_strcmp (name, "xzmemdisk"))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a xzmemdisk");
+
+ disk->total_sectors = xzmemdisk_size / GRUB_DISK_SECTOR_SIZE;
+ disk->id = (unsigned long) "xzmd";
+
+ return GRUB_ERR_NONE;
+}
+
+static void
+grub_xzmemdisk_close (grub_disk_t disk __attribute ((unused)))
+{
+}
+
+static grub_err_t
+grub_xzmemdisk_read (grub_disk_t disk __attribute ((unused)),
+ grub_disk_addr_t sector, grub_size_t size, char *buf)
+{
+ grub_memcpy (buf, xzmemdisk_addr + (sector << GRUB_DISK_SECTOR_BITS),
+ size << GRUB_DISK_SECTOR_BITS);
+ return 0;
+}
+
+static grub_err_t
+grub_xzmemdisk_write (grub_disk_t disk __attribute ((unused)),
+ grub_disk_addr_t sector, grub_size_t size,
+ const char *buf)
+{
+ grub_memcpy (xzmemdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf,
+ size << GRUB_DISK_SECTOR_BITS);
+ return 0;
+}
+
+static struct grub_disk_dev grub_xzmemdisk_dev = {
+ .name = "xzmemdisk",
+ .id = GRUB_DISK_DEVICE_XZMEMDISK_ID,
+ .iterate = grub_xzmemdisk_iterate,
+ .open = grub_xzmemdisk_open,
+ .close = grub_xzmemdisk_close,
+ .read = grub_xzmemdisk_read,
+ .write = grub_xzmemdisk_write,
+ .next = 0
+};
+
+GRUB_MOD_INIT (xzmemdisk)
+{
+ auto int hook (struct grub_module_header *);
+ int hook (struct grub_module_header *header)
+ {
+ if (header->type == OBJ_TYPE_XZMEMDISK)
+ {
+ grub_uint8_t *xzmemdisk_orig_addr;
+ xzmemdisk_orig_addr =
+ (grub_uint8_t *) header + sizeof (struct grub_module_header);
+ grub_dprintf ("xzmemdisk", "Found xzmemdisk image at %p\n",
+ xzmemdisk_orig_addr);
+ xzmemdisk_size = header->size - sizeof (struct grub_module_header);
+
+ /* Remove 512 bytes alignment padding (trailing nulls),
+ * xz file size is always multiple of 4 bytes. */
+ grub_uint32_t pad;
+ pad = *(grub_uint32_t *) (xzmemdisk_orig_addr + xzmemdisk_size - 4);
+ while (pad == 0)
+ {
+ xzmemdisk_size -= 4;
+ pad =
+ *(grub_uint32_t *) (xzmemdisk_orig_addr + xzmemdisk_size - 4);
+ }
+
+ /* Get backward size. */
+ grub_uint32_t backsize;
+ backsize =
+ xz_test_footer (xzmemdisk_orig_addr + xzmemdisk_size -
+ XZ_STREAM_FOOTER_SIZE, XZ_STREAM_FOOTER_SIZE);
+
+ if (backsize == 0)
+ return 0;
+
+ grub_uint64_t uncompressed_size;
+ if (!xz_test_index (xzmemdisk_orig_addr + xzmemdisk_size -
+ XZ_STREAM_FOOTER_SIZE - backsize, backsize, &uncompressed_size))
+ return 0;
+
+ struct xz_buf buf;
+ buf.in = xzmemdisk_orig_addr;
+ buf.in_pos = 0;
+ buf.in_size = xzmemdisk_size;
+
+ /* round up size to GRUB_DISK_SECTOR_SIZE */
+ xzmemdisk_size = uncompressed_size;
+ while (xzmemdisk_size % GRUB_DISK_SECTOR_SIZE)
+ xzmemdisk_size++;
+
+ xzmemdisk_addr = grub_malloc (xzmemdisk_size);
+ if (!xzmemdisk_addr)
+ {
+ grub_dprintf ("xzmemdisk",
+ "Cannot allocate memory for decompression");
+ return 0;
+ }
+
+ buf.out = xzmemdisk_addr;
+ buf.out_pos = 0;
+ buf.out_size = xzmemdisk_size;
+
+ grub_dprintf ("xzmemdisk",
+ "Decompressing xzmemdisk image to dynamic memory\n");
+ enum xz_ret xzret;
+ struct xz_dec *dec;
+ dec = xz_dec_init (0);
+ if (!dec)
+ {
+ grub_dprintf ("xzmemdisk", "Cannot initialize decompressor");
+ grub_free (xzmemdisk_addr);
+ return 0;
+ }
+
+ xzret = xz_dec_run (dec, &buf);
+ xz_dec_end (dec);
+
+ if (xzret != XZ_STREAM_END)
+ {
+ grub_dprintf ("xzmemdisk",
+ "Decompression failed with error code %u\n", xzret);
+ grub_free (xzmemdisk_addr);
+ return 0;
+ }
+
+ grub_disk_dev_register (&grub_xzmemdisk_dev);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ grub_module_iterate (hook);
+}
+
+GRUB_MOD_FINI (xzmemdisk)
+{
+ if (!xzmemdisk_size)
+ return;
+ grub_free (xzmemdisk_addr);
+ grub_disk_dev_unregister (&grub_xzmemdisk_dev);
+}
=== modified file 'include/grub/disk.h'
--- old/include/grub/disk.h 2010-09-13 21:59:22 +0000
+++ new/include/grub/disk.h 2010-09-15 23:43:38 +0000
@@ -37,6 +37,7 @@
GRUB_DISK_DEVICE_HOST_ID,
GRUB_DISK_DEVICE_ATA_ID,
GRUB_DISK_DEVICE_MEMDISK_ID,
+ GRUB_DISK_DEVICE_XZMEMDISK_ID,
GRUB_DISK_DEVICE_NAND_ID,
GRUB_DISK_DEVICE_UUID_ID,
GRUB_DISK_DEVICE_PXE_ID,
=== modified file 'include/grub/kernel.h'
--- old/include/grub/kernel.h 2010-08-30 18:23:04 +0000
+++ new/include/grub/kernel.h 2010-09-15 23:43:38 +0000
@@ -26,6 +26,7 @@
{
OBJ_TYPE_ELF,
OBJ_TYPE_MEMDISK,
+ OBJ_TYPE_XZMEMDISK,
OBJ_TYPE_CONFIG
};
=== modified file 'util/grub-mkimage.c'
--- old/util/grub-mkimage.c 2010-09-03 12:54:04 +0000
+++ new/util/grub-mkimage.c 2010-09-15 23:43:38 +0000
@@ -527,7 +527,7 @@
static void
generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
char *memdisk_path, char *config_path,
- struct image_target_desc *image_target, int note)
+ struct image_target_desc *image_target, int note, int xz)
{
char *kernel_img, *core_img;
size_t kernel_size, total_module_size, core_size, exec_size;
@@ -630,7 +630,7 @@
header = (struct grub_module_header *) (kernel_img + offset);
memset (header, 0, sizeof (struct grub_module_header));
- header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK);
+ header->type = grub_host_to_target32 (xz ? OBJ_TYPE_XZMEMDISK : OBJ_TYPE_MEMDISK);
header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
offset += sizeof (*header);
@@ -1213,6 +1213,7 @@
{"directory", required_argument, 0, 'd'},
{"prefix", required_argument, 0, 'p'},
{"memdisk", required_argument, 0, 'm'},
+ {"xzmemdisk", required_argument, 0, 'M'},
{"font", required_argument, 0, 'f'},
{"config", required_argument, 0, 'c'},
{"output", required_argument, 0, 'o'},
@@ -1255,6 +1256,7 @@
-d, --directory=DIR use images and modules under DIR [default=%s/@address@hidden
-p, --prefix=DIR set grub_prefix directory [default=%s]\n\
-m, --memdisk=FILE embed FILE as a memdisk image\n\
+ -M, --xzmemdisk=FILE embed FILE as a xz compressed memdisk image\n\
-c, --config=FILE embed FILE as boot config\n\
-n, --note add NOTE segment for CHRP Open Firmware\n\
-o, --output=FILE output a generated image to FILE [default=stdout]\n\
@@ -1281,6 +1283,7 @@
char *dir = NULL;
char *prefix = NULL;
char *memdisk = NULL;
+ int xz = 0;
char *font = NULL;
char *config = NULL;
FILE *fp = stdout;
@@ -1293,7 +1296,7 @@
while (1)
{
- int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0);
+ int c = getopt_long (argc, argv, "d:p:m:M:c:o:O:f:hVvn", options, 0);
if (c == -1)
break;
@@ -1331,6 +1334,8 @@
note = 1;
break;
+ case 'M':
+ xz = 1;
case 'm':
if (memdisk)
free (memdisk);
@@ -1340,7 +1345,7 @@
if (prefix)
free (prefix);
- prefix = xstrdup ("(memdisk)/boot/grub");
+ prefix = xstrdup (xz ? "(xzmemdisk)/boot/grub" : "(memdisk)/boot/grub");
break;
case 'c':
@@ -1408,7 +1413,7 @@
generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp,
argv + optind, memdisk, config,
- image_target, note);
+ image_target, note, xz);
fclose (fp);