2004-04-04 13:46:03 +00:00
|
|
|
|
/* grub-mkimage.c - make a bootable image */
|
2002-12-27 08:53:07 +00:00
|
|
|
|
/*
|
2004-04-04 13:46:03 +00:00
|
|
|
|
* GRUB -- GRand Unified Bootloader
|
2010-01-01 20:32:30 +00:00
|
|
|
|
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
2002-12-27 08:53:07 +00:00
|
|
|
|
*
|
2007-07-21 23:32:33 +00:00
|
|
|
|
* GRUB is free software: you can redistribute it and/or modify
|
2002-12-27 08:53:07 +00:00
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2007-07-21 23:32:33 +00:00
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
2002-12-27 08:53:07 +00:00
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
2007-07-21 23:32:33 +00:00
|
|
|
|
* GRUB is distributed in the hope that it will be useful,
|
2002-12-27 08:53:07 +00:00
|
|
|
|
* 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
|
2007-07-21 23:32:33 +00:00
|
|
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
2002-12-27 08:53:07 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
2004-04-04 13:46:03 +00:00
|
|
|
|
#include <grub/types.h>
|
2009-10-23 16:20:04 +00:00
|
|
|
|
#include <grub/elf.h>
|
2010-02-13 15:26:50 +00:00
|
|
|
|
#include <grub/aout.h>
|
2009-11-17 09:52:08 +00:00
|
|
|
|
#include <grub/i18n.h>
|
2004-04-04 13:46:03 +00:00
|
|
|
|
#include <grub/kernel.h>
|
|
|
|
|
#include <grub/disk.h>
|
2010-05-26 12:19:05 +00:00
|
|
|
|
#include <grub/emu/misc.h>
|
2004-04-04 13:46:03 +00:00
|
|
|
|
#include <grub/util/misc.h>
|
|
|
|
|
#include <grub/util/resolve.h>
|
2008-01-20 23:20:36 +00:00
|
|
|
|
#include <grub/misc.h>
|
2010-04-25 22:45:21 +00:00
|
|
|
|
#include <grub/offsets.h>
|
2011-01-15 20:58:21 +00:00
|
|
|
|
#include <grub/crypto.h>
|
2011-05-08 10:39:08 +00:00
|
|
|
|
#include <grub/dl.h>
|
2010-04-25 17:38:12 +00:00
|
|
|
|
#include <time.h>
|
2011-12-15 19:29:30 +00:00
|
|
|
|
#include <multiboot.h>
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
2010-01-03 22:34:03 +00:00
|
|
|
|
#include <assert.h>
|
2010-04-24 23:54:46 +00:00
|
|
|
|
#include <grub/efi/pe32.h>
|
2013-04-12 14:46:51 +00:00
|
|
|
|
#include <grub/uboot/image.h>
|
|
|
|
|
#include <grub/arm/reloc.h>
|
2013-04-09 17:19:19 +00:00
|
|
|
|
#include <grub/ia64/reloc.h>
|
2013-10-10 07:18:06 +00:00
|
|
|
|
#include <grub/osdep/hostfile.h>
|
2013-10-15 17:14:55 +00:00
|
|
|
|
#include <grub/util/install.h>
|
2013-11-16 19:21:16 +00:00
|
|
|
|
#include <grub/emu/config.h>
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
|
|
|
|
#define _GNU_SOURCE 1
|
2012-02-03 20:18:37 +00:00
|
|
|
|
#include <argp.h>
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2009-11-17 10:40:43 +00:00
|
|
|
|
#include "progname.h"
|
|
|
|
|
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
static struct argp_option options[] = {
|
2012-02-26 16:28:05 +00:00
|
|
|
|
{"directory", 'd', N_("DIR"), 0,
|
|
|
|
|
/* TRANSLATORS: platform here isn't identifier. It can be translated. */
|
|
|
|
|
N_("use images and modules under DIR [default=%s/<platform>]"), 0},
|
2012-02-08 18:26:01 +00:00
|
|
|
|
{"prefix", 'p', N_("DIR"), 0, N_("set prefix directory [default=%s]"), 0},
|
2012-02-26 16:28:05 +00:00
|
|
|
|
{"memdisk", 'm', N_("FILE"), 0,
|
2012-03-05 15:42:26 +00:00
|
|
|
|
/* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
|
|
|
|
|
"embed" is a verb (command description). "*/
|
2013-04-12 19:08:53 +00:00
|
|
|
|
N_("embed FILE as a memdisk image\n"
|
2013-12-21 00:41:16 +00:00
|
|
|
|
"Implies `-p (memdisk)/boot/grub' and overrides any prefix supplied previously,"
|
|
|
|
|
" but the prefix itself can be overridden by later options"), 0},
|
2012-03-05 15:42:26 +00:00
|
|
|
|
/* TRANSLATORS: "embed" is a verb (command description). "*/
|
2012-02-08 18:26:01 +00:00
|
|
|
|
{"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
|
2013-01-11 20:32:42 +00:00
|
|
|
|
/* TRANSLATORS: "embed" is a verb (command description). "*/
|
|
|
|
|
{"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
|
2012-02-08 18:26:01 +00:00
|
|
|
|
/* TRANSLATORS: NOTE is a name of segment. */
|
|
|
|
|
{"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
|
2012-02-03 20:18:37 +00:00
|
|
|
|
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
|
2012-02-05 10:07:33 +00:00
|
|
|
|
{"format", 'O', N_("FORMAT"), 0, 0, 0},
|
2013-04-14 17:24:05 +00:00
|
|
|
|
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
2012-02-05 10:07:33 +00:00
|
|
|
|
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
2012-02-03 20:18:37 +00:00
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }
|
|
|
|
|
};
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
static char *
|
|
|
|
|
help_filter (int key, const char *text, void *input __attribute__ ((unused)))
|
2002-12-27 08:53:07 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
switch (key)
|
2010-04-25 22:45:21 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'd':
|
2013-11-16 19:21:16 +00:00
|
|
|
|
return xasprintf (text, grub_util_get_pkglibdir ());
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'p':
|
|
|
|
|
return xasprintf (text, DEFAULT_DIRECTORY);
|
|
|
|
|
case 'O':
|
|
|
|
|
{
|
2013-10-15 17:14:55 +00:00
|
|
|
|
char *formats = grub_install_get_image_targets_string (), *ret;
|
2012-03-06 13:08:48 +00:00
|
|
|
|
ret = xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
|
2012-02-05 10:07:33 +00:00
|
|
|
|
_("available formats:"), formats);
|
2012-02-03 20:18:37 +00:00
|
|
|
|
free (formats);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return (char *) text;
|
2010-04-25 22:45:21 +00:00
|
|
|
|
}
|
2002-12-27 08:53:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
struct arguments
|
2002-12-27 08:53:07 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
size_t nmodules;
|
|
|
|
|
size_t modules_max;
|
|
|
|
|
char **modules;
|
|
|
|
|
char *output;
|
|
|
|
|
char *dir;
|
|
|
|
|
char *prefix;
|
|
|
|
|
char *memdisk;
|
2013-01-11 20:32:42 +00:00
|
|
|
|
char **pubkeys;
|
|
|
|
|
size_t npubkeys;
|
2012-02-03 20:18:37 +00:00
|
|
|
|
char *font;
|
|
|
|
|
char *config;
|
|
|
|
|
int note;
|
2013-10-15 17:14:55 +00:00
|
|
|
|
const struct grub_install_image_target_desc *image_target;
|
2012-02-03 20:18:37 +00:00
|
|
|
|
grub_compression_t comp;
|
|
|
|
|
};
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
static error_t
|
|
|
|
|
argp_parser (int key, char *arg, struct argp_state *state)
|
|
|
|
|
{
|
|
|
|
|
/* Get the input argument from argp_parse, which we
|
|
|
|
|
know is a pointer to our arguments structure. */
|
|
|
|
|
struct arguments *arguments = state->input;
|
2010-02-13 14:57:42 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
switch (key)
|
2002-12-27 08:53:07 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'o':
|
|
|
|
|
if (arguments->output)
|
|
|
|
|
free (arguments->output);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments->output = xstrdup (arg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'O':
|
|
|
|
|
{
|
2013-10-15 17:14:55 +00:00
|
|
|
|
arguments->image_target = grub_install_get_image_target (arg);
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (!arguments->image_target)
|
2002-12-27 08:53:07 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
printf (_("unknown target format %s\n"), arg);
|
|
|
|
|
argp_usage (state);
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'd':
|
|
|
|
|
if (arguments->dir)
|
|
|
|
|
free (arguments->dir);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments->dir = xstrdup (arg);
|
|
|
|
|
break;
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'n':
|
|
|
|
|
arguments->note = 1;
|
|
|
|
|
break;
|
2010-04-25 20:26:29 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'm':
|
|
|
|
|
if (arguments->memdisk)
|
|
|
|
|
free (arguments->memdisk);
|
2008-01-20 23:20:36 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments->memdisk = xstrdup (arg);
|
2009-06-10 21:04:23 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (arguments->prefix)
|
|
|
|
|
free (arguments->prefix);
|
2008-06-15 18:21:16 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments->prefix = xstrdup ("(memdisk)/boot/grub");
|
|
|
|
|
break;
|
2008-01-20 23:20:36 +00:00
|
|
|
|
|
2013-01-11 20:32:42 +00:00
|
|
|
|
case 'k':
|
|
|
|
|
arguments->pubkeys = xrealloc (arguments->pubkeys,
|
|
|
|
|
sizeof (arguments->pubkeys[0])
|
|
|
|
|
* (arguments->npubkeys + 1));
|
|
|
|
|
arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
|
|
|
|
|
break;
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'c':
|
|
|
|
|
if (arguments->config)
|
|
|
|
|
free (arguments->config);
|
2009-05-16 12:12:12 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments->config = xstrdup (arg);
|
|
|
|
|
break;
|
2009-05-16 12:12:12 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
case 'C':
|
|
|
|
|
if (grub_strcmp (arg, "xz") == 0)
|
|
|
|
|
{
|
2010-09-21 19:35:46 +00:00
|
|
|
|
#ifdef HAVE_LIBLZMA
|
2013-10-15 17:14:55 +00:00
|
|
|
|
arguments->comp = GRUB_COMPRESSION_XZ;
|
2010-09-21 19:35:46 +00:00
|
|
|
|
#else
|
2012-02-10 12:56:18 +00:00
|
|
|
|
grub_util_error ("%s",
|
|
|
|
|
_("grub-mkimage is compiled without XZ support"));
|
2010-09-21 19:35:46 +00:00
|
|
|
|
#endif
|
2012-02-03 20:18:37 +00:00
|
|
|
|
}
|
|
|
|
|
else if (grub_strcmp (arg, "none") == 0)
|
2013-10-15 17:14:55 +00:00
|
|
|
|
arguments->comp = GRUB_COMPRESSION_NONE;
|
2012-02-09 13:43:21 +00:00
|
|
|
|
else if (grub_strcmp (arg, "auto") == 0)
|
2013-10-15 17:14:55 +00:00
|
|
|
|
arguments->comp = GRUB_COMPRESSION_AUTO;
|
2012-02-03 20:18:37 +00:00
|
|
|
|
else
|
|
|
|
|
grub_util_error (_("Unknown compression format %s"), arg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'p':
|
|
|
|
|
if (arguments->prefix)
|
|
|
|
|
free (arguments->prefix);
|
|
|
|
|
|
|
|
|
|
arguments->prefix = xstrdup (arg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'v':
|
|
|
|
|
verbosity++;
|
|
|
|
|
break;
|
|
|
|
|
case ARGP_KEY_ARG:
|
|
|
|
|
assert (arguments->nmodules < arguments->modules_max);
|
|
|
|
|
arguments->modules[arguments->nmodules++] = xstrdup(arg);
|
|
|
|
|
break;
|
2010-09-21 18:30:28 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
default:
|
|
|
|
|
return ARGP_ERR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
static struct argp argp = {
|
|
|
|
|
options, argp_parser, N_("[OPTION]... [MODULES]"),
|
|
|
|
|
N_("Make a bootable image of GRUB."),
|
|
|
|
|
NULL, help_filter, NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
FILE *fp = stdout;
|
|
|
|
|
struct arguments arguments;
|
2007-06-21 21:01:11 +00:00
|
|
|
|
|
2013-10-13 18:03:42 +00:00
|
|
|
|
grub_util_host_init (&argc, &argv);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
memset (&arguments, 0, sizeof (struct arguments));
|
2013-10-15 17:14:55 +00:00
|
|
|
|
arguments.comp = GRUB_COMPRESSION_AUTO;
|
2012-02-03 20:18:37 +00:00
|
|
|
|
arguments.modules_max = argc + 1;
|
|
|
|
|
arguments.modules = xmalloc ((arguments.modules_max + 1)
|
|
|
|
|
* sizeof (arguments.modules[0]));
|
|
|
|
|
memset (arguments.modules, 0, (arguments.modules_max + 1)
|
|
|
|
|
* sizeof (arguments.modules[0]));
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
|
|
|
|
|
exit(1);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (!arguments.image_target)
|
2010-04-25 22:45:21 +00:00
|
|
|
|
{
|
2012-02-03 20:18:37 +00:00
|
|
|
|
char *program = xstrdup(program_name);
|
2012-02-05 10:07:33 +00:00
|
|
|
|
printf ("%s\n", _("Target format not specified (use the -O option)."));
|
2012-02-03 20:18:37 +00:00
|
|
|
|
argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
|
|
|
|
|
free (program);
|
|
|
|
|
exit(1);
|
2010-04-25 22:45:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (arguments.output)
|
2002-12-27 08:53:07 +00:00
|
|
|
|
{
|
2013-10-13 18:36:28 +00:00
|
|
|
|
fp = grub_util_fopen (arguments.output, "wb");
|
2002-12-27 08:53:07 +00:00
|
|
|
|
if (! fp)
|
2012-02-05 10:07:33 +00:00
|
|
|
|
grub_util_error (_("cannot open `%s': %s"), arguments.output,
|
|
|
|
|
strerror (errno));
|
2002-12-27 08:53:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (!arguments.dir)
|
2010-04-26 08:56:12 +00:00
|
|
|
|
{
|
2013-10-15 17:14:55 +00:00
|
|
|
|
const char *dn = grub_util_get_target_dirname (arguments.image_target);
|
2013-11-16 19:21:16 +00:00
|
|
|
|
const char *pkglibdir = grub_util_get_pkglibdir ();
|
|
|
|
|
char *ptr;
|
|
|
|
|
arguments.dir = xmalloc (grub_strlen (pkglibdir) + grub_strlen (dn) + 2);
|
|
|
|
|
ptr = grub_stpcpy (arguments.dir, pkglibdir);
|
|
|
|
|
*ptr++ = '/';
|
|
|
|
|
strcpy (ptr, dn);
|
2010-04-26 08:56:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-15 17:14:55 +00:00
|
|
|
|
grub_install_generate_image (arguments.dir,
|
|
|
|
|
arguments.prefix ? : DEFAULT_DIRECTORY, fp,
|
|
|
|
|
arguments.output, arguments.modules,
|
|
|
|
|
arguments.memdisk, arguments.pubkeys,
|
|
|
|
|
arguments.npubkeys, arguments.config,
|
|
|
|
|
arguments.image_target, arguments.note,
|
|
|
|
|
arguments.comp);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2013-11-27 13:13:50 +00:00
|
|
|
|
grub_util_file_sync (fp);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
fclose (fp);
|
|
|
|
|
|
2012-02-03 20:18:37 +00:00
|
|
|
|
if (arguments.dir)
|
|
|
|
|
free (arguments.dir);
|
2002-12-27 08:53:07 +00:00
|
|
|
|
|
2013-01-20 23:16:34 +00:00
|
|
|
|
if (arguments.output)
|
|
|
|
|
free (arguments.output);
|
|
|
|
|
|
2002-12-27 08:53:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|