1 /* grub-mkimage.c - make a bootable image */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/types.h>
23 #include <grub/aout.h>
24 #include <grub/i18n.h>
25 #include <grub/kernel.h>
26 #include <grub/disk.h>
27 #include <grub/emu/misc.h>
28 #include <grub/util/misc.h>
29 #include <grub/util/resolve.h>
30 #include <grub/misc.h>
31 #include <grub/offsets.h>
32 #include <grub/crypto.h>
35 #include <multiboot.h>
42 #include <grub/efi/pe32.h>
43 #include <grub/uboot/image.h>
44 #include <grub/arm/reloc.h>
45 #include <grub/ia64/reloc.h>
46 #include <grub/osdep/hostfile.h>
47 #include <grub/util/install.h>
48 #include <grub/emu/config.h>
52 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
53 #pragma GCC diagnostic ignored "-Wmissing-declarations"
55 #pragma GCC diagnostic error "-Wmissing-prototypes"
56 #pragma GCC diagnostic error "-Wmissing-declarations"
63 static struct argp_option options
[] = {
64 {"directory", 'd', N_("DIR"), 0,
65 /* TRANSLATORS: platform here isn't identifier. It can be translated. */
66 N_("use images and modules under DIR [default=%s/<platform>]"), 0},
67 {"prefix", 'p', N_("DIR"), 0, N_("set prefix directory"), 0},
68 {"memdisk", 'm', N_("FILE"), 0,
69 /* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
70 "embed" is a verb (command description). "*/
71 N_("embed FILE as a memdisk image\n"
72 "Implies `-p (memdisk)/boot/grub' and overrides any prefix supplied previously,"
73 " but the prefix itself can be overridden by later options"), 0},
74 /* TRANSLATORS: "embed" is a verb (command description). "*/
75 {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
76 /* TRANSLATORS: "embed" is a verb (command description). "*/
77 {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
78 /* TRANSLATORS: NOTE is a name of segment. */
79 {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
80 {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
81 {"format", 'O', N_("FORMAT"), 0, 0, 0},
82 {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
83 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
87 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
90 help_filter (int key
, const char *text
, void *input
__attribute__ ((unused
)))
95 return xasprintf (text
, grub_util_get_pkglibdir ());
98 char *formats
= grub_install_get_image_targets_string (), *ret
;
99 ret
= xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
100 _("available formats:"), formats
);
105 return (char *) text
;
109 #pragma GCC diagnostic error "-Wformat-nonliteral"
125 const struct grub_install_image_target_desc
*image_target
;
126 grub_compression_t comp
;
130 argp_parser (int key
, char *arg
, struct argp_state
*state
)
132 /* Get the input argument from argp_parse, which we
133 know is a pointer to our arguments structure. */
134 struct arguments
*arguments
= state
->input
;
139 if (arguments
->output
)
140 free (arguments
->output
);
142 arguments
->output
= xstrdup (arg
);
147 arguments
->image_target
= grub_install_get_image_target (arg
);
148 if (!arguments
->image_target
)
150 printf (_("unknown target format %s\n"), arg
);
158 free (arguments
->dir
);
160 arguments
->dir
= xstrdup (arg
);
168 if (arguments
->memdisk
)
169 free (arguments
->memdisk
);
171 arguments
->memdisk
= xstrdup (arg
);
173 if (arguments
->prefix
)
174 free (arguments
->prefix
);
176 arguments
->prefix
= xstrdup ("(memdisk)/boot/grub");
180 arguments
->pubkeys
= xrealloc (arguments
->pubkeys
,
181 sizeof (arguments
->pubkeys
[0])
182 * (arguments
->npubkeys
+ 1));
183 arguments
->pubkeys
[arguments
->npubkeys
++] = xstrdup (arg
);
187 if (arguments
->config
)
188 free (arguments
->config
);
190 arguments
->config
= xstrdup (arg
);
194 if (grub_strcmp (arg
, "xz") == 0)
197 arguments
->comp
= GRUB_COMPRESSION_XZ
;
199 grub_util_error ("%s",
200 _("grub-mkimage is compiled without XZ support"));
203 else if (grub_strcmp (arg
, "none") == 0)
204 arguments
->comp
= GRUB_COMPRESSION_NONE
;
205 else if (grub_strcmp (arg
, "auto") == 0)
206 arguments
->comp
= GRUB_COMPRESSION_AUTO
;
208 grub_util_error (_("Unknown compression format %s"), arg
);
212 if (arguments
->prefix
)
213 free (arguments
->prefix
);
215 arguments
->prefix
= xstrdup (arg
);
222 assert (arguments
->nmodules
< arguments
->modules_max
);
223 arguments
->modules
[arguments
->nmodules
++] = xstrdup(arg
);
227 return ARGP_ERR_UNKNOWN
;
232 static struct argp argp
= {
233 options
, argp_parser
, N_("[OPTION]... [MODULES]"),
234 N_("Make a bootable image of GRUB."),
235 NULL
, help_filter
, NULL
239 main (int argc
, char *argv
[])
242 struct arguments arguments
;
244 grub_util_host_init (&argc
, &argv
);
246 memset (&arguments
, 0, sizeof (struct arguments
));
247 arguments
.comp
= GRUB_COMPRESSION_AUTO
;
248 arguments
.modules_max
= argc
+ 1;
249 arguments
.modules
= xmalloc ((arguments
.modules_max
+ 1)
250 * sizeof (arguments
.modules
[0]));
251 memset (arguments
.modules
, 0, (arguments
.modules_max
+ 1)
252 * sizeof (arguments
.modules
[0]));
254 if (argp_parse (&argp
, argc
, argv
, 0, 0, &arguments
) != 0)
256 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
260 if (!arguments
.image_target
)
262 char *program
= xstrdup(program_name
);
263 printf ("%s\n", _("Target format not specified (use the -O option)."));
264 argp_help (&argp
, stderr
, ARGP_HELP_STD_USAGE
, program
);
269 if (!arguments
.prefix
)
271 char *program
= xstrdup(program_name
);
272 printf ("%s\n", _("Prefix not specified (use the -p option)."));
273 argp_help (&argp
, stderr
, ARGP_HELP_STD_USAGE
, program
);
278 if (arguments
.output
)
280 fp
= grub_util_fopen (arguments
.output
, "wb");
282 grub_util_error (_("cannot open `%s': %s"), arguments
.output
,
288 const char *dn
= grub_util_get_target_dirname (arguments
.image_target
);
289 const char *pkglibdir
= grub_util_get_pkglibdir ();
291 arguments
.dir
= xmalloc (grub_strlen (pkglibdir
) + grub_strlen (dn
) + 2);
292 ptr
= grub_stpcpy (arguments
.dir
, pkglibdir
);
297 grub_install_generate_image (arguments
.dir
, arguments
.prefix
, fp
,
298 arguments
.output
, arguments
.modules
,
299 arguments
.memdisk
, arguments
.pubkeys
,
300 arguments
.npubkeys
, arguments
.config
,
301 arguments
.image_target
, arguments
.note
,
304 grub_util_file_sync (fp
);
308 free (arguments
.dir
);
310 if (arguments
.output
)
311 free (arguments
.output
);