Add ability to generate newc additions on runtime.
This commit is contained in:
parent
0ec45a682c
commit
92750e4c60
10 changed files with 366 additions and 201 deletions
|
@ -1,3 +1,7 @@
|
|||
2013-03-22 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Add ability to generate newc additions on runtime.
|
||||
|
||||
2013-03-22 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/i386/coreboot/cbls.c: Fix typos and wrong
|
||||
|
|
|
@ -1406,6 +1406,7 @@ module = {
|
|||
module = {
|
||||
name = linux16;
|
||||
common = loader/i386/pc/linux.c;
|
||||
common = loader/linux.c;
|
||||
common = lib/cmdline.c;
|
||||
enable = x86;
|
||||
};
|
||||
|
@ -1454,6 +1455,7 @@ module = {
|
|||
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
||||
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
||||
ia64_efi = loader/ia64/efi/linux.c;
|
||||
common = loader/linux.c;
|
||||
common = lib/cmdline.c;
|
||||
enable = noemu;
|
||||
};
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <grub/i386/relocator.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -1055,14 +1056,11 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
grub_size_t size = 0;
|
||||
grub_addr_t addr_min, addr_max;
|
||||
grub_addr_t addr;
|
||||
grub_err_t err;
|
||||
int i;
|
||||
int nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
|
@ -1076,19 +1074,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
goto fail;
|
||||
}
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
size = grub_get_initrd_size (&initrd_ctx);
|
||||
|
||||
initrd_pages = (page_align (size) >> 12);
|
||||
|
||||
|
@ -1138,21 +1127,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
initrd_mem_target = get_physical_target_address (ch);
|
||||
}
|
||||
|
||||
ptr = initrd_mem;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
|
||||
goto fail;
|
||||
|
||||
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
|
||||
(unsigned) addr, (unsigned) size);
|
||||
|
@ -1162,9 +1138,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
linux_params.root_dev = 0x0100; /* XXX */
|
||||
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <grub/video.h>
|
||||
#include <grub/i386/floppy.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -381,15 +382,13 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
grub_size_t size = 0;
|
||||
grub_addr_t addr_max, addr_min;
|
||||
struct linux_kernel_header *lh;
|
||||
grub_uint8_t *initrd_chunk;
|
||||
grub_addr_t initrd_addr;
|
||||
grub_err_t err;
|
||||
int i, nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
|
@ -437,19 +436,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
|
||||
addr_min = GRUB_LINUX_BZIMAGE_ADDR + grub_linux16_prot_size;
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
size = grub_get_initrd_size (&initrd_ctx);
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
|
@ -463,30 +453,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
initrd_addr = get_physical_target_address (ch);
|
||||
}
|
||||
|
||||
ptr = initrd_chunk;
|
||||
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, initrd_chunk))
|
||||
goto fail;
|
||||
|
||||
lh->ramdisk_image = initrd_addr;
|
||||
lh->ramdisk_size = size;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <grub/elf.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -567,10 +568,7 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
int i;
|
||||
int nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
|
@ -584,22 +582,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
goto fail;
|
||||
}
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
initrd_size = 0;
|
||||
initrd_size = grub_get_initrd_size (&initrd_ctx);
|
||||
grub_dprintf ("linux", "Loading initrd\n");
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
initrd_size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
grub_dprintf ("linux", "File %d: %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
initrd_pages = (page_align (initrd_size) >> 12);
|
||||
initrd_mem = grub_efi_allocate_pages (0, initrd_pages);
|
||||
|
@ -612,25 +599,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n",
|
||||
(grub_uint64_t) initrd_mem, initrd_size);
|
||||
|
||||
ptr = initrd_mem;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
|
||||
goto fail;
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
|
294
grub-core/loader/linux.c
Normal file
294
grub-core/loader/linux.c
Normal file
|
@ -0,0 +1,294 @@
|
|||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/linux.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
struct newc_head
|
||||
{
|
||||
char magic[6];
|
||||
char ino[8];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char nlink[8];
|
||||
char mtime[8];
|
||||
char filesize[8];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char namesize[8];
|
||||
char check[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct grub_linux_initrd_component
|
||||
{
|
||||
grub_file_t file;
|
||||
char *newc_name;
|
||||
grub_off_t size;
|
||||
};
|
||||
|
||||
struct dir
|
||||
{
|
||||
char *name;
|
||||
struct dir *next;
|
||||
struct dir *child;
|
||||
};
|
||||
|
||||
static char
|
||||
hex (grub_uint8_t val)
|
||||
{
|
||||
if (val < 10)
|
||||
return '0' + val;
|
||||
return 'a' + val - 10;
|
||||
}
|
||||
|
||||
static void
|
||||
set_field (char *var, grub_uint32_t val)
|
||||
{
|
||||
int i;
|
||||
char *ptr = var;
|
||||
for (i = 28; i >= 0; i -= 4)
|
||||
*ptr++ = hex((val >> i) & 0xf);
|
||||
}
|
||||
|
||||
static grub_uint8_t *
|
||||
make_header (grub_uint8_t *ptr,
|
||||
const char *name, grub_size_t len,
|
||||
grub_uint32_t mode,
|
||||
grub_off_t fsize)
|
||||
{
|
||||
struct newc_head *head = (struct newc_head *) ptr;
|
||||
grub_uint8_t *optr;
|
||||
grub_size_t oh = 0;
|
||||
grub_memcpy (head->magic, "070701", 6);
|
||||
set_field (head->ino, 0);
|
||||
set_field (head->mode, mode);
|
||||
set_field (head->uid, 0);
|
||||
set_field (head->gid, 0);
|
||||
set_field (head->nlink, 1);
|
||||
set_field (head->mtime, 0);
|
||||
set_field (head->filesize, fsize);
|
||||
set_field (head->devmajor, 0);
|
||||
set_field (head->devminor, 0);
|
||||
set_field (head->rdevmajor, 0);
|
||||
set_field (head->rdevminor, 0);
|
||||
set_field (head->namesize, len);
|
||||
set_field (head->check, 0);
|
||||
optr = ptr;
|
||||
ptr += sizeof (struct newc_head);
|
||||
grub_memcpy (ptr, name, len);
|
||||
ptr += len;
|
||||
oh = ALIGN_UP_OVERHEAD (ptr - optr, 4);
|
||||
grub_memset (ptr, 0, oh);
|
||||
ptr += oh;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
free_dir (struct dir *root)
|
||||
{
|
||||
if (!root)
|
||||
return;
|
||||
free_dir (root->next);
|
||||
free_dir (root->child);
|
||||
grub_free (root->name);
|
||||
grub_free (root);
|
||||
}
|
||||
|
||||
static grub_size_t
|
||||
insert_dir (const char *name, struct dir **root,
|
||||
grub_uint8_t *ptr)
|
||||
{
|
||||
struct dir *cur, **head = root;
|
||||
const char *cb, *ce = name;
|
||||
grub_size_t size = 0;
|
||||
while (1)
|
||||
{
|
||||
for (cb = ce; *cb == '/'; cb++);
|
||||
for (ce = cb; *ce && *ce != '/'; ce++);
|
||||
if (!*ce)
|
||||
break;
|
||||
|
||||
for (cur = *root; cur; cur = cur->next)
|
||||
if (grub_memcmp (cur->name, cb, ce - cb)
|
||||
&& cur->name[ce - cb] == 0)
|
||||
break;
|
||||
if (!cur)
|
||||
{
|
||||
struct dir *n;
|
||||
n = grub_zalloc (sizeof (*n));
|
||||
if (!n)
|
||||
return 0;
|
||||
n->next = *head;
|
||||
n->name = grub_strndup (cb, ce - cb);
|
||||
if (ptr)
|
||||
{
|
||||
grub_printf ("Creating directory %s, %s\n", name, ce);
|
||||
ptr = make_header (ptr, name, ce - name,
|
||||
040777, 0);
|
||||
}
|
||||
size += ALIGN_UP ((ce - (char *) name)
|
||||
+ sizeof (struct newc_head), 4);
|
||||
*head = n;
|
||||
cur = n;
|
||||
}
|
||||
root = &cur->next;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_initrd_init (int argc, char *argv[],
|
||||
struct grub_linux_initrd_context *initrd_ctx)
|
||||
{
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
|
||||
initrd_ctx->nfiles = 0;
|
||||
initrd_ctx->components = 0;
|
||||
|
||||
initrd_ctx->components = grub_zalloc (argc
|
||||
* sizeof (initrd_ctx->components[0]));
|
||||
if (!initrd_ctx->components)
|
||||
return grub_errno;
|
||||
|
||||
initrd_ctx->size = 0;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
const char *fname = argv[i];
|
||||
if (grub_memcmp (argv[i], "newc:", 5) == 0)
|
||||
{
|
||||
const char *ptr, *eptr;
|
||||
ptr = argv[i] + 5;
|
||||
while (*ptr == '/')
|
||||
ptr++;
|
||||
eptr = grub_strchr (ptr, ':');
|
||||
if (eptr)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
|
||||
if (!initrd_ctx->components[i].newc_name)
|
||||
{
|
||||
grub_initrd_close (initrd_ctx);
|
||||
return grub_errno;
|
||||
}
|
||||
initrd_ctx->size
|
||||
+= ALIGN_UP (sizeof (struct newc_head)
|
||||
+ grub_strlen (initrd_ctx->components[i].newc_name),
|
||||
4);
|
||||
initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
|
||||
&root, 0);
|
||||
newc = 1;
|
||||
fname = eptr + 1;
|
||||
}
|
||||
}
|
||||
else if (newc)
|
||||
{
|
||||
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
||||
+ sizeof ("TRAILER!!!") - 1, 4);
|
||||
free_dir (root);
|
||||
root = 0;
|
||||
newc = 0;
|
||||
}
|
||||
grub_file_filter_disable_compression ();
|
||||
initrd_ctx->components[i].file = grub_file_open (fname);
|
||||
if (!initrd_ctx->components[i].file)
|
||||
{
|
||||
grub_initrd_close (initrd_ctx);
|
||||
return grub_errno;
|
||||
}
|
||||
initrd_ctx->nfiles++;
|
||||
initrd_ctx->components[i].size
|
||||
= grub_file_size (initrd_ctx->components[i].file);
|
||||
initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
|
||||
}
|
||||
|
||||
if (newc)
|
||||
{
|
||||
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
|
||||
+ sizeof ("TRAILER!!!") - 1, 4);
|
||||
free_dir (root);
|
||||
root = 0;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_size_t
|
||||
grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx)
|
||||
{
|
||||
return initrd_ctx->size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
|
||||
{
|
||||
int i;
|
||||
if (!initrd_ctx->components)
|
||||
return;
|
||||
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||
{
|
||||
grub_free (initrd_ctx->components[i].newc_name);
|
||||
grub_file_close (initrd_ctx->components[i].file);
|
||||
}
|
||||
grub_free (initrd_ctx->components);
|
||||
initrd_ctx->components = 0;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||
char *argv[], void *target)
|
||||
{
|
||||
grub_uint8_t *ptr = target;
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
|
||||
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize;
|
||||
|
||||
if (initrd_ctx->components[i].newc_name)
|
||||
{
|
||||
ptr += insert_dir (initrd_ctx->components[i].newc_name,
|
||||
&root, ptr);
|
||||
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
|
||||
grub_strlen (initrd_ctx->components[i].newc_name),
|
||||
0100777,
|
||||
initrd_ctx->components[i].size);
|
||||
newc = 1;
|
||||
}
|
||||
else if (newc)
|
||||
{
|
||||
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1,
|
||||
0, 0);
|
||||
free_dir (root);
|
||||
root = 0;
|
||||
newc = 0;
|
||||
}
|
||||
|
||||
cursize = initrd_ctx->components[i].size;
|
||||
if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize)
|
||||
!= cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
grub_initrd_close (initrd_ctx);
|
||||
return grub_errno;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (newc)
|
||||
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
|
||||
free_dir (root);
|
||||
root = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
#include <grub/memory.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -410,14 +411,11 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
grub_size_t size = 0;
|
||||
void *initrd_src;
|
||||
grub_addr_t initrd_dest;
|
||||
grub_err_t err;
|
||||
int i;
|
||||
int nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
@ -428,19 +426,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
if (initrd_loaded)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued.");
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
size = grub_get_initrd_size (&initrd_ctx);
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
|
@ -458,21 +447,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
initrd_dest = get_physical_target_address (ch) | 0x80000000;
|
||||
}
|
||||
|
||||
ptr = initrd_src;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, initrd_src))
|
||||
goto fail;
|
||||
|
||||
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||
{
|
||||
|
@ -504,9 +480,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
initrd_loaded = 1;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <grub/memory.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -315,13 +316,10 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
grub_size_t size = 0;
|
||||
grub_addr_t first_addr;
|
||||
grub_addr_t addr;
|
||||
int i;
|
||||
int nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
|
@ -335,19 +333,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
goto fail;
|
||||
}
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
size = grub_get_initrd_size (&initrd_ctx);
|
||||
|
||||
first_addr = linux_addr + linux_size;
|
||||
|
||||
|
@ -359,30 +348,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
|
||||
grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
|
||||
|
||||
ptr = (void *) addr;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
grub_ieee1275_release (addr, size);
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
|
||||
goto fail;
|
||||
|
||||
initrd_addr = addr;
|
||||
initrd_size = size;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -368,14 +369,11 @@ static grub_err_t
|
|||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
grub_size_t size = 0;
|
||||
grub_addr_t paddr;
|
||||
grub_addr_t addr;
|
||||
int ret;
|
||||
int i;
|
||||
int nfiles = 0;
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linux_initrd_context initrd_ctx;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
|
@ -389,19 +387,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
goto fail;
|
||||
}
|
||||
|
||||
files = grub_zalloc (argc * sizeof (files[0]));
|
||||
if (!files)
|
||||
if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
grub_file_filter_disable_compression ();
|
||||
files[i] = grub_file_open (argv[i]);
|
||||
if (! files[i])
|
||||
goto fail;
|
||||
nfiles++;
|
||||
size += ALIGN_UP(grub_file_size (files[i]), 4);
|
||||
}
|
||||
size = grub_get_initrd_size (&initrd_ctx);
|
||||
|
||||
addr = 0x60000000;
|
||||
|
||||
|
@ -423,30 +412,15 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
|
||||
addr, paddr, size);
|
||||
|
||||
ptr = (void *) addr;
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
ptr += cursize;
|
||||
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
|
||||
goto fail;
|
||||
|
||||
initrd_addr = addr;
|
||||
initrd_paddr = paddr;
|
||||
initrd_size = size;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < nfiles; i++)
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
grub_initrd_close (&initrd_ctx);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
|
24
include/grub/linux.h
Normal file
24
include/grub/linux.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <grub/file.h>
|
||||
|
||||
struct grub_linux_initrd_component;
|
||||
|
||||
struct grub_linux_initrd_context
|
||||
{
|
||||
int nfiles;
|
||||
struct grub_linux_initrd_component *components;
|
||||
grub_size_t size;
|
||||
};
|
||||
|
||||
grub_err_t
|
||||
grub_initrd_init (int argc, char *argv[],
|
||||
struct grub_linux_initrd_context *ctx);
|
||||
|
||||
grub_size_t
|
||||
grub_get_initrd_size (struct grub_linux_initrd_context *ctx);
|
||||
|
||||
void
|
||||
grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx);
|
||||
|
||||
grub_err_t
|
||||
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||
char *argv[], void *target);
|
Loading…
Reference in a new issue