From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH] improve boot time with standalone images
Date: Sun, 22 Dec 2013 21:26:55 +0100 [thread overview]
Message-ID: <52B74B0F.702@gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 557 bytes --]
Hello, all. While testing on raspberry pi using standalone image I've
noticed that all file operations were sluggish. The culprit was tar that
we use as a filesystem for memdisk which requires complete scan to find
one file. On most systems it's a minor time penalty but on raspberry pi
it almost halved boot time. I propose a specialised compact and fast
uncompressed read-only filesystem by storing filenames in sorted array
and using binary search. It's a pretty big change but I feel like it's
worth to be put into 2.02.
Does anybody disagree?
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: greffs.diff --]
[-- Type: text/x-diff; name="greffs.diff", Size: 20316 bytes --]
diff --git a/Makefile.util.def b/Makefile.util.def
index 27c48e5..d9f7e64 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -119,6 +119,7 @@ library = {
common = grub-core/fs/sfs.c;
common = grub-core/fs/squash4.c;
common = grub-core/fs/tar.c;
+ common = grub-core/fs/greffs.c;
common = grub-core/fs/udf.c;
common = grub-core/fs/ufs2.c;
common = grub-core/fs/ufs.c;
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index e5e558c..da3a599 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1400,6 +1400,11 @@ module = {
};
module = {
+ name = greffs;
+ common = fs/greffs.c;
+};
+
+module = {
name = udf;
common = fs/udf.c;
};
diff --git a/grub-core/fs/greffs.c b/grub-core/fs/greffs.c
new file mode 100644
index 0000000..2cc4efb
--- /dev/null
+++ b/grub-core/fs/greffs.c
@@ -0,0 +1,314 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/archelp.h>
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/i18n.h>
+#include <grub/greffs.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+struct grub_greffs_data
+{
+ grub_uint32_t dofs;
+};
+
+static grub_err_t
+get_string (grub_disk_t disk,
+ const struct grub_greffs_header *head,
+ grub_uint32_t fn,
+ char **buf, grub_size_t *size)
+{
+ grub_uint32_t desc[2];
+ grub_size_t read_size;
+
+ if (grub_disk_read (disk, 0,
+ grub_cpu_to_le32 (head->string_ptrs_offset)
+ + fn * sizeof (desc[0]), sizeof (desc), &desc))
+ return grub_errno;
+ read_size = desc[1] - desc[0];
+ if (*size < read_size + 1)
+ {
+ grub_free (*buf);
+ *size = (read_size + 4) * 2;
+ *buf = grub_malloc (*size);
+ if (!*buf)
+ {
+ *size = 0;
+ return grub_errno;
+ }
+ }
+ if (grub_disk_read (disk, 0, desc[0], read_size, *buf))
+ return grub_errno;
+ (*buf)[read_size] = '\0';
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+find_file (grub_disk_t disk,
+ struct grub_greffs_header *head,
+ const char *name_in, grub_uint32_t *f, int exact)
+{
+ grub_uint32_t num_files, cur_file = 0;
+ int i;
+ char *buf = NULL;
+ grub_size_t buf_size = 0;
+ grub_err_t err;
+
+ num_files = grub_le_to_cpu32 (head->nfiles);
+
+ for (i = 31; i >= 0; i--)
+ {
+ int cmp;
+ if ((cur_file | (1 << i)) > num_files)
+ continue;
+ err = get_string (disk, head, (cur_file | (1 << i)) - 1, &buf, &buf_size);
+ if (err)
+ {
+ grub_free (buf);
+ return err;
+ }
+ cmp = grub_strcmp (buf, name_in);
+ if (cmp <= 0)
+ cur_file |= (1 << i);
+ if (cmp == 0)
+ {
+ grub_free (buf);
+ *f = cur_file - 1;
+ return GRUB_ERR_NONE;
+ }
+ }
+
+ grub_free (buf);
+ if (!exact)
+ {
+ *f = cur_file;
+ return GRUB_ERR_NONE;
+ }
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
+ name_in);
+}
+
+static char *
+canonicalize (const char *name_in, int make_dir)
+{
+ const char *iptr;
+ char *out, *optr;
+ out = grub_malloc (grub_strlen (name_in) + 2);
+ if (!out)
+ return NULL;
+ for (iptr = name_in, optr = out; *iptr; )
+ {
+ while (*iptr == '/')
+ iptr++;
+ if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
+ {
+ iptr += 2;
+ continue;
+ }
+ if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
+ {
+ iptr += 3;
+ if (optr == out)
+ continue;
+ for (optr -= 2; optr >= out && *optr != '/'; optr--);
+ optr++;
+ continue;
+ }
+ while (*iptr && *iptr != '/')
+ *optr++ = *iptr++;
+ if (*iptr)
+ *optr++ = *iptr++;
+ else if (make_dir && optr != out)
+ *optr++ = '/';
+ }
+ *optr = 0;
+ return out;
+}
+
+static grub_err_t
+grub_greffs_dir (grub_device_t device, const char *path_in,
+ grub_fs_dir_hook_t hook, void *hook_data)
+{
+ grub_err_t err;
+ grub_uint32_t cur_file, num_files;
+ char *buf = 0;
+ grub_size_t buf_size = 0;
+ char *can;
+ grub_size_t len;
+ struct grub_greffs_header head;
+
+ if (grub_disk_read (device->disk, 0, 0, sizeof (head), &head))
+ return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
+
+ if (grub_memcmp (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic)) != 0)
+ return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
+
+ can = canonicalize (path_in, 1);
+ if (!can)
+ return grub_errno;
+
+ if (can[0] == '\0')
+ cur_file = 0;
+ else
+ {
+ err = find_file (device->disk, &head, can, &cur_file, 0);
+ if (err)
+ goto fail;
+ }
+
+ num_files = grub_le_to_cpu32 (head.nfiles);
+
+ len = grub_strlen (can);
+
+ while (cur_file < num_files)
+ {
+ char *p, *n;
+ struct grub_dirhook_info info;
+
+ err = get_string (device->disk, &head, cur_file, &buf, &buf_size);
+ if (err)
+ goto fail;
+ if (grub_memcmp (can, buf, len) != 0)
+ break;
+ grub_memset (&info, 0, sizeof (info));
+
+ n = buf + len;
+ while (*n == '/')
+ n++;
+
+ p = grub_strchr (n, '/');
+ if (p)
+ *p = 0;
+ info.dir = (p != NULL);
+ if (hook (n, &info, hook_data))
+ goto fail;
+ if (!p)
+ cur_file++;
+ else
+ {
+ *p = '/' + 1;
+ p[1] = '\0';
+ err = find_file (device->disk, &head, buf, &cur_file, 0);
+ if (err)
+ goto fail;
+ }
+ }
+
+ fail:
+ grub_free (buf);
+ grub_free (can);
+ return grub_errno;
+}
+
+
+static grub_err_t
+grub_greffs_open (grub_file_t file, const char *name_in)
+{
+ struct grub_greffs_header head;
+ struct grub_greffs_data *data;
+ struct grub_greffs_inode inode;
+ grub_err_t err;
+ grub_uint32_t cur_file;
+ char *can;
+
+ if (grub_disk_read (file->device->disk, 0, 0, sizeof (head), &head))
+ return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
+
+ if (grub_memcmp (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic)) != 0)
+ return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
+
+ can = canonicalize (name_in, 0);
+ if (!can)
+ return grub_errno;
+
+ err = find_file (file->device->disk, &head, can, &cur_file, 1);
+ grub_free (can);
+ if (err)
+ return err;
+
+ data = grub_malloc (sizeof (*data));
+ if (!data)
+ return grub_errno;
+ if (grub_disk_read (file->device->disk,
+ 0, grub_le_to_cpu32 (head.inodes_offset)
+ + sizeof (inode) * cur_file, sizeof (inode), &inode))
+ return grub_error (GRUB_ERR_BAD_FS, "not a greffs filesystem");
+
+ data->dofs = grub_cpu_to_le32 (inode.start);
+ file->size = grub_cpu_to_le32 (inode.size);
+
+ file->data = data;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_greffs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+ struct grub_greffs_data *data;
+ grub_ssize_t ret;
+
+ data = file->data;
+
+ file->device->disk->read_hook = file->read_hook;
+ file->device->disk->read_hook_data = file->read_hook_data;
+ ret = (grub_disk_read (file->device->disk, 0, data->dofs + file->offset,
+ len, buf)) ? -1 : (grub_ssize_t) len;
+ file->device->disk->read_hook = 0;
+
+ return ret;
+}
+
+static grub_err_t
+grub_greffs_close (grub_file_t file)
+{
+ struct grub_greffs_data *data;
+
+ data = file->data;
+ grub_free (data);
+
+ return grub_errno;
+}
+
+static struct grub_fs grub_greffs_fs = {
+ .name = "greffs",
+ .dir = grub_greffs_dir,
+ .open = grub_greffs_open,
+ .read = grub_greffs_read,
+ .close = grub_greffs_close,
+#ifdef GRUB_UTIL
+ .reserved_first_sector = 0,
+ .blocklist_install = 0,
+#endif
+};
+
+GRUB_MOD_INIT (greffs)
+{
+ grub_fs_register (&grub_greffs_fs);
+}
+
+GRUB_MOD_FINI (greffs)
+{
+ grub_fs_unregister (&grub_greffs_fs);
+}
diff --git a/include/grub/greffs.h b/include/grub/greffs.h
new file mode 100644
index 0000000..6d54bae
--- /dev/null
+++ b/include/grub/greffs.h
@@ -0,0 +1,55 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 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/>.
+ */
+
+#ifndef GRUB_GREFFS_HEADER
+#define GRUB_GREFFS_HEADER 1
+
+#include <grub/types.h>
+
+/*
+ Layout:
+ header
+ grub_uint32_t[] pointers to names
+ inodes
+ names
+ contents.
+ Everything is little-endian.
+ */
+
+struct grub_greffs_header
+{
+ char magic[4];
+#define GRUB_GREFFS_MAGIC "gref"
+ grub_uint32_t nfiles;
+ /* must be divisible by 4. */
+ grub_uint32_t inodes_offset;
+ /* must be divisible by 4. */
+ grub_uint32_t string_ptrs_offset;
+};
+
+struct grub_greffs_inode
+{
+ grub_uint32_t start;
+ grub_uint32_t size;
+ grub_uint32_t mtime;
+ /* Currently always 0. If we ever need symlinks,
+ it could be added. */
+ grub_uint32_t type;
+};
+
+#endif
diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
index 8e2a2b8..c7dd054 100644
--- a/util/grub-mkstandalone.c
+++ b/util/grub-mkstandalone.c
@@ -21,6 +21,7 @@
#include <grub/util/install.h>
#include <grub/util/misc.h>
#include <grub/emu/config.h>
+#include <grub/greffs.h>
#include <string.h>
@@ -34,7 +35,6 @@ static char *output_image;
static char **files;
static int nfiles;
const struct grub_install_image_target_desc *format;
-static FILE *memdisk;
enum
{
@@ -116,91 +116,56 @@ struct argp argp = {
NULL, help_filter, NULL
};
-/* tar support */
-#define MAGIC "ustar"
-struct head
+struct file_desc
{
- char name[100];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char chksum[8];
- char typeflag;
- char linkname[100];
- char magic[6];
- char version[2];
- char uname[32];
- char gname[32];
- char devmajor[8];
- char devminor[8];
- char prefix[155];
- char pad[12];
-} GRUB_PACKED;
-
-static void
-write_zeros (unsigned rsz)
-{
- char buf[512];
-
- memset (buf, 0, 512);
- fwrite (buf, 1, rsz, memdisk);
-}
-
-static void
-write_pad (unsigned sz)
-{
- write_zeros ((~sz + 1) & 511);
-}
-
-static void
-set_tar_value (char *field, grub_uint32_t val,
- unsigned len)
-{
- unsigned i;
- for (i = 0; i < len - 1; i++)
- field[len - 2 - i] = '0' + ((val >> (3 * i)) & 7);
-}
+ char *name;
+ char *source;
+ grub_size_t size;
+ grub_size_t mtime;
+};
+static struct file_desc *file_descs;
+static size_t n_file_descs, alloc_file_descs;
-static void
-compute_checksum (struct head *hd)
+static inline void
+canonicalize (char *name)
{
- unsigned int chk = 0;
- unsigned char *ptr;
- memset (hd->chksum, ' ', 8);
- for (ptr = (unsigned char *) hd; ptr < (unsigned char *) (hd + 1); ptr++)
- chk += *ptr;
- set_tar_value (hd->chksum, chk, 8);
+ char *iptr, *optr;
+ for (iptr = name, optr = name; *iptr; )
+ {
+ while (*iptr == '/')
+ iptr++;
+ if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0))
+ {
+ iptr += 2;
+ continue;
+ }
+ if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0))
+ {
+ iptr += 3;
+ if (optr == name)
+ continue;
+ for (optr -= 2; optr >= name && *optr != '/'; optr--);
+ optr++;
+ continue;
+ }
+ while (*iptr && *iptr != '/')
+ *optr++ = *iptr++;
+ if (*iptr)
+ *optr++ = *iptr++;
+ }
+ *optr = 0;
}
static void
add_tar_file (const char *from,
const char *to)
{
- char *tcn;
- const char *iptr;
- char *optr;
- struct head hd;
grub_util_fd_t in;
- ssize_t r;
- grub_uint32_t mtime = 0;
- grub_uint32_t size;
-
- COMPILE_TIME_ASSERT (sizeof (hd) == 512);
+ size_t idx;
if (grub_util_is_special_file (from))
return;
- mtime = grub_util_get_mtime (from);
-
- optr = tcn = xmalloc (strlen (to) + 1);
- for (iptr = to; *iptr == '/'; iptr++);
- for (; *iptr; iptr++)
- if (!(iptr[0] == '/' && iptr[1] == '/'))
- *optr++ = *iptr;
- *optr = '\0';
-
if (grub_util_is_directory (from))
{
grub_util_fd_dir_t d;
@@ -221,69 +186,138 @@ add_tar_file (const char *from,
free (fp);
}
grub_util_fd_closedir (d);
- free (tcn);
return;
}
- if (optr - tcn > 99)
+ idx = n_file_descs++;
+ if (idx >= alloc_file_descs)
{
- memset (&hd, 0, sizeof (hd));
- memcpy (hd.name, tcn, 99);
- memcpy (hd.mode, "0000600", 7);
- memcpy (hd.uid, "0001750", 7);
- memcpy (hd.gid, "0001750", 7);
-
- set_tar_value (hd.size, optr - tcn, 12);
- set_tar_value (hd.mtime, mtime, 12);
- hd.typeflag = 'L';
- memcpy (hd.magic, "ustar ", 7);
- memcpy (hd.uname, "grub", 4);
- memcpy (hd.gname, "grub", 4);
-
- compute_checksum (&hd);
-
- fwrite (&hd, 1, sizeof (hd), memdisk);
- fwrite (tcn, 1, optr - tcn, memdisk);
-
- write_pad (optr - tcn);
+ alloc_file_descs = 2 * n_file_descs;
+ file_descs = xrealloc (file_descs, alloc_file_descs
+ * sizeof (file_descs[0]));
}
in = grub_util_fd_open (from, GRUB_UTIL_FD_O_RDONLY);
if (!GRUB_UTIL_FD_IS_VALID (in))
grub_util_error (_("cannot open `%s': %s"), from, grub_util_fd_strerror ());
- if (!grub_install_copy_buffer)
- grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
+ file_descs[idx].name = xstrdup (to);
+ file_descs[idx].source = xstrdup (from);
+ canonicalize (file_descs[idx].name);
+ file_descs[idx].mtime = grub_util_get_mtime (from);
+ file_descs[idx].size = grub_util_get_fd_size (in, from, NULL);
+
+ grub_util_fd_close (in);
+}
- size = grub_util_get_fd_size (in, from, NULL);
+static int
+filecmp (const void *p1, const void *p2)
+{
+ const struct file_desc *a = p1, *b = p2;
- memset (&hd, 0, sizeof (hd));
- memcpy (hd.name, tcn, optr - tcn < 99 ? optr - tcn : 99);
- memcpy (hd.mode, "0000600", 7);
- memcpy (hd.uid, "0001750", 7);
- memcpy (hd.gid, "0001750", 7);
+ /* Don't use strcmp, it's buggy on some systems. */
+ return grub_strcmp (a->name, b->name);
+}
- set_tar_value (hd.size, size, 12);
- set_tar_value (hd.mtime, mtime, 12);
- hd.typeflag = '0';
- memcpy (hd.magic, "ustar ", 7);
- memcpy (hd.uname, "grub", 4);
- memcpy (hd.gname, "grub", 4);
+static void
+write_memdisk (char *memdisk_img)
+{
+ FILE *memdisk;
+ struct grub_greffs_header head;
+ struct grub_greffs_inode inode;
+ size_t total_strlen = 0, i;
+ size_t name_pad = 0;
+ grub_uint32_t file_offset;
+
+ qsort (file_descs, n_file_descs, sizeof (file_descs[0]), filecmp);
+
+ for (i = 0; i < n_file_descs; i++)
+ total_strlen += grub_strlen (file_descs[i].name);
+ name_pad = ALIGN_UP (total_strlen, 4) - total_strlen;
+ total_strlen += name_pad;
+
+ grub_memcpy (head.magic, GRUB_GREFFS_MAGIC, sizeof (head.magic));
+ head.nfiles = grub_cpu_to_le32 (n_file_descs);
+ head.inodes_offset = grub_cpu_to_le32 (sizeof (head)
+ + sizeof (grub_uint32_t)
+ * (n_file_descs + 1));
+ head.string_ptrs_offset = grub_cpu_to_le32 (sizeof (head));
- compute_checksum (&hd);
+ memdisk = grub_util_fopen (memdisk_img, "wb");
+ if (!memdisk)
+ grub_util_error (_("Can't create file: %s"), strerror (errno));
- fwrite (&hd, 1, sizeof (hd), memdisk);
-
- while (1)
+ fwrite (&head, 1, sizeof (head), memdisk);
+
+ grub_uint32_t curname = sizeof (head) + sizeof (grub_uint32_t)
+ * (n_file_descs + 1) + sizeof (inode) * n_file_descs;
+ for (i = 0; i <= n_file_descs; i++)
{
- r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
- if (r <= 0)
- break;
- fwrite (grub_install_copy_buffer, 1, r, memdisk);
+ grub_uint32_t curname_le = grub_cpu_to_le32 (curname);
+ fwrite (&curname_le, 1, sizeof (curname_le), memdisk);
+ if (i != n_file_descs)
+ curname += grub_strlen (file_descs[i].name);
}
- grub_util_fd_close (in);
- write_pad (size);
+ file_offset = sizeof (head) + sizeof (grub_uint32_t)
+ * (n_file_descs + 1) + sizeof (inode) * n_file_descs + total_strlen;
+ for (i = 0; i < n_file_descs; i++)
+ {
+ inode.start = grub_cpu_to_le32 (file_offset);
+ inode.size = grub_cpu_to_le32 (file_descs[i].size);
+ inode.mtime = grub_cpu_to_le32 (file_descs[i].mtime);
+ inode.type = 0;
+ fwrite (&inode, 1, sizeof (inode), memdisk);
+ file_offset += file_descs[i].size;
+ }
+
+ for (i = 0; i < n_file_descs; i++)
+ fwrite (file_descs[i].name, 1, grub_strlen (file_descs[i].name), memdisk);
+
+ if (!grub_install_copy_buffer)
+ grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
+
+ grub_memset (grub_install_copy_buffer, 0, 4);
+ fwrite (grub_install_copy_buffer, 1, name_pad, memdisk);
+
+ for (i = 0; i < n_file_descs; i++)
+ {
+ grub_util_fd_t in;
+ size_t remaining = file_descs[i].size;
+ in = grub_util_fd_open (file_descs[i].source, GRUB_UTIL_FD_O_RDONLY);
+ if (!GRUB_UTIL_FD_IS_VALID (in))
+ grub_util_error (_("cannot open `%s': %s"),
+ file_descs[i].source, grub_util_fd_strerror ());
+
+ while (remaining)
+ {
+ size_t toread = remaining;
+ ssize_t r;
+ if (remaining > GRUB_INSTALL_COPY_BUFFER_SIZE)
+ toread = GRUB_INSTALL_COPY_BUFFER_SIZE;
+ r = grub_util_fd_read (in, grub_install_copy_buffer, toread);
+ if (r <= 0)
+ break;
+ fwrite (grub_install_copy_buffer, 1, r, memdisk);
+ if (r >= remaining)
+ remaining = 0;
+ else
+ remaining -= r;
+ }
+ grub_util_fd_close (in);
+
+ grub_memset (grub_install_copy_buffer, 0, GRUB_INSTALL_COPY_BUFFER_SIZE);
+ while (remaining)
+ {
+ size_t toread = remaining;
+ if (remaining > GRUB_INSTALL_COPY_BUFFER_SIZE)
+ toread = GRUB_INSTALL_COPY_BUFFER_SIZE;
+ fwrite (grub_install_copy_buffer, 1, toread, memdisk);
+ remaining -= toread;
+ }
+ }
+
+ fclose (memdisk);
}
int
@@ -319,8 +353,6 @@ main (int argc, char *argv[])
char *memdisk_img = grub_util_make_temporary_file ();
- memdisk = grub_util_fopen (memdisk_img, "wb");
-
add_tar_file (memdisk_dir, "");
for (i = 0; i < nfiles; i++)
{
@@ -341,14 +373,12 @@ main (int argc, char *argv[])
to++;
add_tar_file (from, to);
}
- write_zeros (512);
-
- fclose (memdisk);
+ write_memdisk (memdisk_img);
grub_util_unlink_recursive (memdisk_dir);
grub_install_push_module ("memdisk");
- grub_install_push_module ("tar");
+ grub_install_push_module ("greffs");
grub_install_make_image_wrap (grub_install_source_directory,
"(memdisk)/boot/grub", output_image,
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]
next reply other threads:[~2013-12-22 20:27 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-22 20:26 Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2013-12-23 4:06 ` [PATCH] improve boot time with standalone images Vladimir 'φ-coder/phcoder' Serbinenko
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=52B74B0F.702@gmail.com \
--to=phcoder@gmail.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.