]>
Commit | Line | Data |
---|---|---|
cd46aa6c VS |
1 | /* |
2 | * Make GRUB rescue image | |
3 | * | |
4 | * GRUB -- GRand Unified Bootloader | |
5 | * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. | |
6 | * | |
7 | * GRUB is free software: you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation, either version 3 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * GRUB is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
20 | ||
21 | #include <config.h> | |
22 | ||
23 | #include <grub/util/install.h> | |
24 | #include <grub/util/misc.h> | |
25 | #include <grub/emu/exec.h> | |
26 | #include <grub/emu/config.h> | |
b8765fa0 | 27 | #include <grub/emu/hostdisk.h> |
cd46aa6c VS |
28 | #include <argp.h> |
29 | ||
30 | #include <sys/types.h> | |
31 | #include <sys/wait.h> | |
32 | ||
33 | #include <string.h> | |
34 | #include <time.h> | |
35 | ||
36 | static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX]; | |
37 | static char *rom_directory; | |
38 | static char *label_font; | |
39 | static char *label_color; | |
40 | static char *label_bgcolor; | |
41 | static char *product_name; | |
42 | static char *product_version; | |
43 | static int xorriso_tail_argc; | |
44 | static int xorriso_tail_arg_alloc; | |
45 | static char **xorriso_tail_argv; | |
46 | static char *output_image; | |
47 | static char *xorriso; | |
48 | static char *boot_grub; | |
49 | static int xorriso_argc; | |
50 | static int xorriso_arg_alloc; | |
51 | static char **xorriso_argv; | |
52 | static char *iso_uuid; | |
53 | static char *iso9660_dir; | |
54 | ||
55 | static void | |
56 | xorriso_push (const char *val) | |
57 | { | |
58 | if (xorriso_arg_alloc <= xorriso_argc + 1) | |
59 | { | |
60 | xorriso_arg_alloc = 2 * (4 + xorriso_argc); | |
61 | xorriso_argv = xrealloc (xorriso_argv, | |
62 | sizeof (xorriso_argv[0]) | |
63 | * xorriso_arg_alloc); | |
64 | } | |
65 | xorriso_argv[xorriso_argc++] = xstrdup (val); | |
66 | } | |
67 | ||
68 | static void | |
69 | xorriso_link (const char *from, const char *to) | |
70 | { | |
71 | char *tof = grub_util_path_concat (2, iso9660_dir, to); | |
72 | char *val = xasprintf ("%s=%s", from, tof); | |
73 | xorriso_push (val); | |
74 | free (val); | |
75 | free (tof); | |
76 | } | |
77 | ||
78 | enum | |
79 | { | |
80 | OPTION_OUTPUT = 'o', | |
81 | OPTION_ROM_DIRECTORY = 0x301, | |
82 | OPTION_XORRISO, | |
83 | OPTION_GLUE_EFI, | |
84 | OPTION_RENDER_LABEL, | |
85 | OPTION_LABEL_FONT, | |
86 | OPTION_LABEL_COLOR, | |
87 | OPTION_LABEL_BGCOLOR, | |
88 | OPTION_PRODUCT_NAME, | |
89 | OPTION_PRODUCT_VERSION, | |
90 | OPTION_SPARC_BOOT, | |
91 | OPTION_ARCS_BOOT | |
92 | }; | |
93 | ||
94 | static struct argp_option options[] = { | |
95 | GRUB_INSTALL_OPTIONS, | |
96 | {"output", 'o', N_("FILE"), | |
97 | 0, N_("save output in FILE [required]"), 2}, | |
98 | {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"), | |
99 | 0, N_("save ROM images in DIR [optional]"), 2}, | |
100 | {"xorriso", OPTION_XORRISO, N_("FILE"), | |
101 | /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */ | |
102 | 0, N_("use FILE as xorriso [optional]"), 2}, | |
103 | {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2}, | |
104 | {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2}, | |
105 | {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, | |
106 | {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, | |
107 | {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, | |
108 | {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2}, | |
109 | {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, | |
110 | {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2}, | |
111 | {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2}, | |
112 | {0, 0, 0, 0, 0, 0} | |
113 | }; | |
114 | ||
ae558c2c VS |
115 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" |
116 | ||
cd46aa6c VS |
117 | static char * |
118 | help_filter (int key, const char *text, void *input __attribute__ ((unused))) | |
119 | { | |
120 | switch (key) | |
121 | { | |
3bf2db89 AB |
122 | case ARGP_KEY_HELP_PRE_DOC: |
123 | /* TRANSLATORS: it generates one single image which is bootable through any method. */ | |
124 | return strdup (_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")); | |
cd46aa6c | 125 | case ARGP_KEY_HELP_POST_DOC: |
3bf2db89 AB |
126 | { |
127 | char *p1, *out; | |
128 | ||
129 | p1 = xasprintf (_("Generates a bootable CD/USB/floppy image. Arguments other than options to this program" | |
130 | " are passed to xorriso, and indicate source files, source directories, or any of the " | |
131 | "mkisofs options listed by the output of `%s'."), "xorriso -as mkisofs -help"); | |
132 | out = xasprintf ("%s\n\n%s\n\n%s", p1, | |
133 | _("Option -- switches to native xorriso command mode."), | |
134 | _("Mail xorriso support requests to <bug-xorriso@gnu.org>.")); | |
135 | free (p1); | |
136 | return out; | |
137 | } | |
cd46aa6c VS |
138 | default: |
139 | return grub_install_help_filter (key, text, input); | |
140 | } | |
141 | } | |
142 | ||
ae558c2c VS |
143 | #pragma GCC diagnostic error "-Wformat-nonliteral" |
144 | ||
cd46aa6c VS |
145 | enum { |
146 | SYS_AREA_AUTO, | |
147 | SYS_AREA_COMMON, | |
148 | SYS_AREA_SPARC, | |
149 | SYS_AREA_ARCS | |
150 | } system_area = SYS_AREA_AUTO; | |
151 | ||
152 | static error_t | |
153 | argp_parser (int key, char *arg, struct argp_state *state) | |
154 | { | |
155 | if (grub_install_parse (key, arg)) | |
156 | return 0; | |
157 | switch (key) | |
158 | { | |
159 | case OPTION_OUTPUT: | |
160 | free (output_image); | |
161 | output_image = xstrdup (arg); | |
162 | return 0; | |
163 | case OPTION_ROM_DIRECTORY: | |
164 | free (rom_directory); | |
165 | rom_directory = xstrdup (arg); | |
166 | return 0; | |
167 | ||
168 | /* | |
169 | FIXME: | |
170 | # Intentionally undocumented | |
171 | --grub-mkimage-extra) | |
172 | mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;; | |
173 | --grub-mkimage-extra=*) | |
174 | mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; | |
175 | */ | |
176 | case OPTION_SPARC_BOOT: | |
177 | system_area = SYS_AREA_SPARC; | |
178 | return 0; | |
179 | case OPTION_ARCS_BOOT: | |
180 | system_area = SYS_AREA_ARCS; | |
181 | return 0; | |
182 | case OPTION_PRODUCT_NAME: | |
183 | free (product_name); | |
184 | product_name = xstrdup (arg); | |
185 | return 0; | |
186 | case OPTION_PRODUCT_VERSION: | |
187 | free (product_version); | |
188 | product_version = xstrdup (arg); | |
189 | return 0; | |
190 | /* Accept and ignore for compatibility. */ | |
191 | case OPTION_GLUE_EFI: | |
192 | case OPTION_RENDER_LABEL: | |
193 | return 0; | |
194 | case OPTION_LABEL_FONT: | |
195 | free (label_font); | |
196 | label_font = xstrdup (arg); | |
197 | return 0; | |
198 | ||
199 | case OPTION_LABEL_COLOR: | |
200 | free (label_color); | |
201 | label_color = xstrdup (arg); | |
202 | return 0; | |
203 | ||
204 | case OPTION_LABEL_BGCOLOR: | |
205 | free (label_bgcolor); | |
206 | label_bgcolor = xstrdup (arg); | |
207 | return 0; | |
208 | ||
209 | case OPTION_XORRISO: | |
210 | free (xorriso); | |
211 | xorriso = xstrdup (arg); | |
212 | return 0; | |
213 | ||
214 | case ARGP_KEY_ARG: | |
215 | if (xorriso_tail_arg_alloc <= xorriso_tail_argc) | |
216 | { | |
217 | xorriso_tail_arg_alloc = 2 * (4 + xorriso_tail_argc); | |
218 | xorriso_tail_argv = xrealloc (xorriso_tail_argv, | |
219 | sizeof (xorriso_tail_argv[0]) | |
220 | * xorriso_tail_arg_alloc); | |
221 | } | |
222 | xorriso_tail_argv[xorriso_tail_argc++] = xstrdup (arg); | |
223 | return 0; | |
224 | default: | |
225 | return ARGP_ERR_UNKNOWN; | |
226 | } | |
227 | } | |
228 | ||
229 | struct argp argp = { | |
230 | options, argp_parser, N_("[OPTION] SOURCE..."), | |
3bf2db89 | 231 | NULL, NULL, help_filter, NULL |
cd46aa6c VS |
232 | }; |
233 | ||
234 | static void | |
235 | write_part (FILE *f, const char *srcdir) | |
236 | { | |
237 | FILE *in; | |
238 | char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); | |
239 | char buf[260]; | |
240 | in = grub_util_fopen (inname, "rb"); | |
241 | if (!in) | |
242 | return; | |
243 | while (fgets (buf, 256, in)) | |
244 | { | |
245 | char *ptr; | |
246 | for (ptr = buf + strlen (buf) - 1; | |
247 | ptr >= buf && (*ptr == '\n' || *ptr == '\r'); | |
248 | ptr--); | |
249 | ptr[1] = '\0'; | |
250 | fprintf (f, "insmod %s\n", buf); | |
251 | } | |
252 | fclose (in); | |
253 | } | |
254 | ||
255 | static void | |
256 | make_image_abs (enum grub_install_plat plat, | |
257 | const char *mkimage_target, | |
f23bc651 | 258 | const char *output) |
cd46aa6c VS |
259 | { |
260 | char *load_cfg; | |
261 | FILE *load_cfg_f; | |
262 | ||
263 | if (!source_dirs[plat]) | |
264 | return; | |
265 | ||
266 | grub_util_info (N_("enabling %s support ..."), | |
267 | mkimage_target); | |
268 | ||
269 | load_cfg = grub_util_make_temporary_file (); | |
270 | ||
271 | load_cfg_f = grub_util_fopen (load_cfg, "wb"); | |
272 | fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid); | |
273 | fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n"); | |
274 | ||
275 | write_part (load_cfg_f, source_dirs[plat]); | |
276 | fclose (load_cfg_f); | |
277 | ||
278 | grub_install_push_module ("search"); | |
279 | grub_install_push_module ("iso9660"); | |
280 | grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output, | |
281 | 0, load_cfg, | |
f23bc651 | 282 | mkimage_target, 0); |
cd46aa6c VS |
283 | grub_install_pop_module (); |
284 | grub_install_pop_module (); | |
285 | grub_util_unlink (load_cfg); | |
286 | } | |
287 | ||
288 | static void | |
289 | make_image (enum grub_install_plat plat, | |
290 | const char *mkimage_target, | |
f23bc651 | 291 | const char *output_sub) |
cd46aa6c VS |
292 | { |
293 | char *out = grub_util_path_concat (2, boot_grub, output_sub); | |
f23bc651 | 294 | make_image_abs (plat, mkimage_target, out); |
cd46aa6c VS |
295 | free (out); |
296 | } | |
297 | ||
298 | static void | |
299 | make_image_fwdisk_abs (enum grub_install_plat plat, | |
300 | const char *mkimage_target, | |
301 | const char *output) | |
302 | { | |
4336b5d8 VS |
303 | char *load_cfg; |
304 | FILE *load_cfg_f; | |
305 | ||
cd46aa6c VS |
306 | if (!source_dirs[plat]) |
307 | return; | |
308 | ||
4336b5d8 VS |
309 | grub_util_info (N_("enabling %s support ..."), |
310 | mkimage_target); | |
311 | ||
312 | load_cfg = grub_util_make_temporary_file (); | |
313 | ||
314 | load_cfg_f = grub_util_fopen (load_cfg, "wb"); | |
315 | write_part (load_cfg_f, source_dirs[plat]); | |
316 | fclose (load_cfg_f); | |
317 | ||
cd46aa6c VS |
318 | grub_install_push_module ("iso9660"); |
319 | grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, | |
f23bc651 | 320 | 0, load_cfg, mkimage_target, 0); |
cd46aa6c VS |
321 | grub_install_pop_module (); |
322 | } | |
323 | ||
324 | static int | |
325 | check_xorriso (const char *val) | |
326 | { | |
327 | const char *argv[5]; | |
328 | int fd; | |
329 | pid_t pid; | |
330 | FILE *mdadm; | |
331 | char *buf = NULL; | |
332 | size_t len = 0; | |
333 | int ret = 0; | |
334 | ||
335 | argv[0] = xorriso; | |
336 | argv[1] = "-as"; | |
337 | argv[2] = "mkisofs"; | |
338 | argv[3] = "-help"; | |
339 | argv[4] = NULL; | |
340 | ||
341 | pid = grub_util_exec_pipe_stderr (argv, &fd); | |
342 | ||
343 | if (!pid) | |
344 | return 0; | |
345 | ||
346 | /* Parent. Read mdadm's output. */ | |
347 | mdadm = fdopen (fd, "r"); | |
348 | if (! mdadm) | |
349 | return 0; | |
350 | ||
351 | while (getline (&buf, &len, mdadm) > 0) | |
352 | { | |
353 | if (grub_strstr (buf, val)) | |
354 | ret = 1; | |
355 | } | |
356 | ||
357 | close (fd); | |
358 | waitpid (pid, NULL, 0); | |
359 | free (buf); | |
360 | return ret; | |
361 | } | |
362 | ||
363 | static void | |
364 | make_image_fwdisk (enum grub_install_plat plat, | |
365 | const char *mkimage_target, | |
366 | const char *output_sub) | |
367 | { | |
368 | char *out = grub_util_path_concat (2, boot_grub, output_sub); | |
369 | make_image_fwdisk_abs (plat, mkimage_target, out); | |
370 | free (out); | |
371 | } | |
372 | ||
373 | int | |
374 | main (int argc, char *argv[]) | |
375 | { | |
376 | char *romdir; | |
377 | char *sysarea_img = NULL; | |
378 | const char *pkgdatadir; | |
379 | ||
380 | grub_util_host_init (&argc, &argv); | |
5c7206e4 | 381 | grub_util_disable_fd_syncs (); |
cd46aa6c VS |
382 | |
383 | pkgdatadir = grub_util_get_pkgdatadir (); | |
384 | ||
385 | product_name = xstrdup (PACKAGE_NAME); | |
386 | product_version = xstrdup (PACKAGE_VERSION); | |
387 | xorriso = xstrdup ("xorriso"); | |
388 | label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); | |
389 | ||
390 | argp_parse (&argp, argc, argv, 0, 0, 0); | |
391 | ||
392 | if (!output_image) | |
393 | grub_util_error ("%s", _("output file must be specified")); | |
394 | ||
b8765fa0 VS |
395 | grub_init_all (); |
396 | grub_hostfs_init (); | |
397 | grub_host_init (); | |
398 | ||
cd46aa6c VS |
399 | xorriso_push (xorriso); |
400 | xorriso_push ("-as"); | |
401 | xorriso_push ("mkisofs"); | |
402 | xorriso_push ("-graft-points"); | |
403 | ||
404 | iso9660_dir = grub_util_make_temporary_dir (); | |
a1f00cc5 | 405 | grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir); |
cd46aa6c VS |
406 | boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); |
407 | grub_install_mkdir_p (boot_grub); | |
408 | romdir = grub_util_path_concat (2, boot_grub, "roms"); | |
409 | grub_util_mkdir (romdir); | |
410 | ||
411 | if (!grub_install_source_directory) | |
412 | { | |
c6a823e2 | 413 | const char *pkglibdir = grub_util_get_pkglibdir (); |
cd46aa6c VS |
414 | enum grub_install_plat plat; |
415 | ||
416 | for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) | |
417 | { | |
c6a823e2 | 418 | char *platdir = grub_util_path_concat (2, pkglibdir, |
cd46aa6c VS |
419 | grub_install_get_platform_name (plat)); |
420 | ||
421 | if (!grub_util_is_directory (platdir)) | |
422 | { | |
423 | free (platdir); | |
424 | continue; | |
425 | } | |
426 | source_dirs[plat] = platdir; | |
427 | grub_install_copy_files (platdir, | |
428 | boot_grub, plat); | |
429 | } | |
430 | } | |
431 | else | |
432 | { | |
433 | enum grub_install_plat plat; | |
434 | plat = grub_install_get_target (grub_install_source_directory); | |
435 | grub_install_copy_files (grub_install_source_directory, | |
436 | boot_grub, plat); | |
437 | source_dirs[plat] = xstrdup (grub_install_source_directory); | |
438 | } | |
439 | if (system_area == SYS_AREA_AUTO || grub_install_source_directory) | |
440 | { | |
441 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC] | |
442 | || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] | |
443 | || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
808e97c4 VS |
444 | || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] |
445 | || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] | |
446 | || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] | |
cd46aa6c VS |
447 | || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) |
448 | system_area = SYS_AREA_COMMON; | |
449 | else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) | |
450 | system_area = SYS_AREA_SPARC; | |
451 | else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) | |
452 | system_area = SYS_AREA_ARCS; | |
453 | } | |
454 | ||
455 | /* obtain date-based UUID. */ | |
456 | { | |
457 | time_t tim; | |
458 | struct tm *tmm; | |
459 | tim = time (NULL); | |
460 | tmm = gmtime (&tim); | |
461 | iso_uuid = xmalloc (55); | |
462 | grub_snprintf (iso_uuid, 50, | |
463 | "%04d-%02d-%02d-%02d-%02d-%02d-00", | |
464 | tmm->tm_year + 1900, | |
465 | tmm->tm_mon + 1, | |
466 | tmm->tm_mday, | |
467 | tmm->tm_hour, | |
468 | tmm->tm_min, | |
469 | tmm->tm_sec); | |
470 | } | |
471 | { | |
472 | char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40); | |
473 | char *optr; | |
474 | const char *iptr; | |
475 | optr = grub_stpcpy (uuid_out, "--modification-date="); | |
476 | for (iptr = iso_uuid; *iptr; iptr++) | |
477 | if (*iptr != '-') | |
478 | *optr++ = *iptr; | |
479 | *optr = '\0'; | |
480 | xorriso_push (uuid_out); | |
481 | free (uuid_out); | |
482 | } | |
483 | ||
484 | /* build BIOS core.img. */ | |
485 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]) | |
486 | { | |
487 | char *load_cfg; | |
488 | FILE *load_cfg_f; | |
489 | char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img"); | |
490 | load_cfg = grub_util_make_temporary_file (); | |
491 | ||
492 | grub_util_info (N_("enabling %s support ..."), "BIOS"); | |
493 | load_cfg_f = grub_util_fopen (load_cfg, "wb"); | |
494 | write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]); | |
495 | fclose (load_cfg_f); | |
496 | ||
497 | grub_install_push_module ("biosdisk"); | |
498 | grub_install_push_module ("iso9660"); | |
499 | grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], | |
500 | "/boot/grub", output, | |
501 | 0, load_cfg, | |
f23bc651 | 502 | "i386-pc-eltorito", 0); |
cd46aa6c VS |
503 | |
504 | xorriso_push ("-b"); | |
505 | xorriso_push ("boot/grub/i386-pc/eltorito.img"); | |
506 | xorriso_push ("-no-emul-boot"); | |
507 | xorriso_push ("-boot-load-size"); | |
508 | xorriso_push ("4"); | |
509 | xorriso_push ("-boot-info-table"); | |
510 | if (system_area == SYS_AREA_COMMON) | |
511 | { | |
512 | if (check_xorriso ("grub2-boot-info")) | |
513 | { | |
514 | char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], | |
515 | "boot_hybrid.img"); | |
516 | xorriso_push ("--grub2-boot-info"); | |
517 | xorriso_push ("--grub2-mbr"); | |
518 | xorriso_push (boot_hybrid); | |
519 | } | |
520 | else | |
521 | { | |
522 | FILE *sa, *bi; | |
523 | size_t sz; | |
524 | char buf[512]; | |
525 | char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], | |
526 | "boot.img"); | |
527 | grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later.")); | |
528 | sysarea_img = grub_util_make_temporary_file (); | |
529 | sa = grub_util_fopen (sysarea_img, "wb"); | |
530 | if (!sa) | |
531 | grub_util_error (_("cannot open `%s': %s"), sysarea_img, | |
532 | strerror (errno)); | |
6cc89597 | 533 | bi = grub_util_fopen (bin, "rb"); |
cd46aa6c VS |
534 | if (!bi) |
535 | grub_util_error (_("cannot open `%s': %s"), bin, | |
536 | strerror (errno)); | |
422e6e88 VS |
537 | if (fread (buf, 1, 512, bi) != 512) |
538 | grub_util_error (_("cannot read `%s': %s"), bin, | |
539 | strerror (errno)); | |
cd46aa6c VS |
540 | fclose (bi); |
541 | fwrite (buf, 1, 512, sa); | |
542 | ||
6cc89597 VS |
543 | grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], |
544 | "/boot/grub", sa, sysarea_img, | |
545 | 0, load_cfg, | |
546 | "i386-pc", 0); | |
cd46aa6c VS |
547 | sz = ftello (sa); |
548 | fflush (sa); | |
5c7206e4 | 549 | grub_util_fd_sync (fileno (sa)); |
cd46aa6c VS |
550 | fclose (sa); |
551 | ||
552 | if (sz > 32768) | |
553 | { | |
554 | grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later.")); | |
555 | } | |
556 | else | |
557 | { | |
558 | xorriso_push ("-G"); | |
559 | xorriso_push (sysarea_img); | |
560 | } | |
561 | } | |
562 | } | |
563 | grub_install_pop_module (); | |
564 | grub_install_pop_module (); | |
565 | } | |
566 | ||
567 | /** build multiboot core.img */ | |
568 | grub_install_push_module ("pata"); | |
569 | grub_install_push_module ("ahci"); | |
570 | grub_install_push_module ("at_keyboard"); | |
f23bc651 | 571 | make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf"); |
cd46aa6c VS |
572 | grub_install_pop_module (); |
573 | grub_install_pop_module (); | |
574 | grub_install_pop_module (); | |
575 | ||
576 | make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf"); | |
577 | ||
578 | char *core_services = NULL; | |
579 | ||
580 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
581 | || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] | |
582 | || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) | |
583 | { | |
584 | char *mach_ker, *sv, *label, *label_text; | |
585 | FILE *f; | |
586 | core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices"); | |
587 | grub_install_mkdir_p (core_services); | |
588 | ||
589 | mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel"); | |
590 | f = grub_util_fopen (mach_ker, "wb"); | |
591 | fclose (f); | |
592 | free (mach_ker); | |
593 | ||
594 | sv = grub_util_path_concat (2, core_services, "SystemVersion.plist"); | |
595 | f = grub_util_fopen (sv, "wb"); | |
596 | fprintf (f, "<plist version=\"1.0\">\n" | |
597 | "<dict>\n" | |
598 | " <key>ProductBuildVersion</key>\n" | |
599 | " <string></string>\n" | |
600 | " <key>ProductName</key>\n" | |
601 | " <string>%s</string>\n" | |
602 | " <key>ProductVersion</key>\n" | |
603 | " <string>%s</string>\n" | |
604 | "</dict>\n" | |
605 | "</plist>\n", product_name, product_version); | |
606 | fclose (f); | |
607 | free (sv); | |
608 | label = grub_util_path_concat (2, core_services, ".disk_label"); | |
609 | char *label_string = xasprintf ("%s %s", product_name, product_version); | |
610 | grub_util_render_label (label_font, label_bgcolor ? : "white", | |
611 | label_color ? : "black", label_string, label); | |
612 | free (label); | |
613 | label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); | |
614 | f = grub_util_fopen (label_text, "wb"); | |
6aa6077b | 615 | fprintf (f, "%s\n", label_string); |
cd46aa6c VS |
616 | fclose (f); |
617 | free (label_string); | |
618 | free (label_text); | |
619 | if (system_area == SYS_AREA_COMMON) | |
620 | { | |
621 | xorriso_push ("-hfsplus"); | |
622 | xorriso_push ("-apm-block-size"); | |
623 | xorriso_push ("2048"); | |
624 | xorriso_push ("-hfsplus-file-creator-type"); | |
625 | xorriso_push ("chrp"); | |
626 | xorriso_push ("tbxj"); | |
627 | xorriso_push ("/System/Library/CoreServices/.disk_label"); | |
628 | ||
629 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
630 | || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) | |
631 | { | |
632 | xorriso_push ("-hfs-bless-by"); | |
633 | xorriso_push ("i"); | |
634 | xorriso_push ("/System/Library/CoreServices/boot.efi"); | |
635 | } | |
636 | } | |
637 | } | |
638 | ||
639 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
640 | || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] | |
641 | || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] | |
808e97c4 VS |
642 | || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] |
643 | || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]) | |
cd46aa6c VS |
644 | { |
645 | char *efidir = grub_util_make_temporary_dir (); | |
646 | char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); | |
647 | char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot"); | |
648 | char *imgname, *img32, *img64, *img_mac = NULL; | |
649 | char *efiimgfat; | |
650 | grub_install_mkdir_p (efidir_efi_boot); | |
651 | ||
652 | imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi"); | |
653 | make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); | |
654 | free (imgname); | |
655 | ||
0776112c | 656 | grub_install_push_module ("part_apple"); |
cd46aa6c VS |
657 | img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); |
658 | make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); | |
0776112c | 659 | grub_install_pop_module (); |
cd46aa6c | 660 | |
0776112c | 661 | grub_install_push_module ("part_apple"); |
cd46aa6c VS |
662 | img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); |
663 | make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); | |
0776112c | 664 | grub_install_pop_module (); |
cd46aa6c VS |
665 | |
666 | imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); | |
667 | make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); | |
668 | free (imgname); | |
669 | ||
e7cfa8d5 | 670 | imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi"); |
808e97c4 VS |
671 | make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", |
672 | imgname); | |
673 | free (imgname); | |
674 | ||
cd46aa6c VS |
675 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) |
676 | { | |
677 | imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); | |
678 | /* For old macs. Suggested by Peter Jones. */ | |
679 | grub_install_copy_file (img32, imgname, 1); | |
680 | } | |
681 | ||
682 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
683 | || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) | |
684 | img_mac = grub_util_path_concat (2, core_services, "boot.efi"); | |
685 | ||
686 | if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] | |
687 | && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) | |
688 | grub_util_glue_efi (img32, img64, img_mac); | |
689 | else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) | |
690 | grub_install_copy_file (img64, img_mac, 1); | |
691 | else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) | |
692 | grub_install_copy_file (img32, img_mac, 1); | |
693 | ||
694 | free (img_mac); | |
695 | free (img32); | |
696 | free (img64); | |
697 | free (efidir_efi_boot); | |
698 | ||
699 | efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img"); | |
700 | grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i", | |
701 | efiimgfat, "::", NULL }); | |
702 | grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL }); | |
703 | xorriso_push ("--efi-boot"); | |
704 | xorriso_push ("efi.img"); | |
705 | xorriso_push ("-efi-boot-part"); | |
706 | xorriso_push ("--efi-boot-image"); | |
707 | ||
708 | grub_util_unlink_recursive (efidir); | |
709 | free (efiimgfat); | |
710 | free (efidir_efi); | |
711 | free (efidir); | |
712 | } | |
713 | ||
0776112c | 714 | grub_install_push_module ("part_apple"); |
cd46aa6c | 715 | make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf"); |
0776112c | 716 | grub_install_pop_module (); |
cd46aa6c VS |
717 | |
718 | if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) | |
719 | { | |
720 | char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], | |
721 | "grub.chrp"); | |
722 | char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], | |
66c00cb1 | 723 | "bootinfo.txt"); |
cd46aa6c VS |
724 | char *bootx = grub_util_path_concat (2, core_services, "BootX"); |
725 | char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp"); | |
726 | char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt"); | |
727 | grub_install_copy_file (grub_chrp, bootx, 1); | |
728 | grub_install_mkdir_p (ppc_chrp); | |
729 | grub_install_copy_file (bisrc, bitgt, 1); | |
730 | xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf"); | |
731 | xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf"); | |
732 | /* FIXME: add PreP */ | |
733 | if (system_area == SYS_AREA_COMMON) | |
734 | { | |
735 | xorriso_push ("-hfsplus-file-creator-type"); | |
736 | xorriso_push ("chrp"); | |
737 | xorriso_push ("tbxi"); | |
738 | xorriso_push ("/System/Library/CoreServices/BootX"); | |
739 | xorriso_push ("-hfs-bless-by"); | |
740 | xorriso_push ("p"); | |
741 | xorriso_push ("/System/Library/CoreServices"); | |
742 | } | |
743 | xorriso_push ("-sysid"); | |
744 | xorriso_push ("PPC"); | |
745 | } | |
746 | ||
747 | make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, | |
748 | "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img"); | |
749 | ||
750 | if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] | |
751 | && system_area == SYS_AREA_SPARC) | |
752 | { | |
753 | char *cdboot; | |
754 | FILE *in, *out; | |
755 | char buf[512]; | |
756 | sysarea_img = grub_util_make_temporary_file (); | |
757 | cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275], | |
758 | "cdboot.img"); | |
759 | in = grub_util_fopen (cdboot, "rb"); | |
422e6e88 VS |
760 | if (!in) |
761 | grub_util_error (_("cannot open `%s': %s"), cdboot, | |
762 | strerror (errno)); | |
cd46aa6c | 763 | out = grub_util_fopen (sysarea_img, "wb"); |
422e6e88 VS |
764 | if (!out) |
765 | grub_util_error (_("cannot open `%s': %s"), sysarea_img, | |
766 | strerror (errno)); | |
cd46aa6c VS |
767 | memset (buf, 0, 512); |
768 | fwrite (buf, 1, 512, out); | |
422e6e88 VS |
769 | if (fread (buf, 1, 512, in) != 512) |
770 | grub_util_error (_("cannot read `%s': %s"), cdboot, | |
771 | strerror (errno)); | |
cd46aa6c VS |
772 | fwrite (buf, 1, 512, out); |
773 | fclose (in); | |
774 | fclose (out); | |
775 | xorriso_push ("-G"); | |
776 | xorriso_push (sysarea_img); | |
777 | xorriso_push ("-B"); | |
778 | xorriso_push (","); | |
779 | xorriso_push ("--grub2-sparc-core"); | |
780 | xorriso_push ("/boot/grub/sparc64-ieee1275/core.img"); | |
781 | } | |
782 | ||
783 | make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img"); | |
784 | ||
785 | if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) | |
786 | { | |
787 | xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img"); | |
788 | xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img"); | |
789 | xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img"); | |
790 | } | |
791 | if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS) | |
792 | { | |
793 | xorriso_push ("-mips-boot"); | |
794 | xorriso_push ("/boot/grub/mips-arc/sashARCS"); | |
795 | xorriso_push ("-mips-boot"); | |
796 | xorriso_push ("/boot/grub/mips-arc/sash"); | |
797 | xorriso_push ("-mips-boot"); | |
798 | xorriso_push ("/boot/grub/mips-arc/grub"); | |
799 | } | |
800 | ||
801 | make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe"); | |
802 | ||
803 | grub_install_push_module ("pata"); | |
f23bc651 | 804 | make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf"); |
cd46aa6c | 805 | |
f23bc651 | 806 | make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf"); |
cd46aa6c | 807 | |
f23bc651 VS |
808 | make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin"); |
809 | make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin"); | |
cd46aa6c | 810 | |
f23bc651 | 811 | make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf"); |
cd46aa6c VS |
812 | |
813 | grub_install_push_module ("at_keyboard"); | |
814 | ||
f23bc651 | 815 | make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img"); |
cd46aa6c VS |
816 | |
817 | grub_install_push_module ("ahci"); | |
818 | ||
f23bc651 | 819 | make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf"); |
cd46aa6c VS |
820 | grub_install_pop_module (); |
821 | grub_install_pop_module (); | |
822 | grub_install_pop_module (); | |
823 | ||
824 | if (rom_directory) | |
825 | { | |
826 | const struct | |
827 | { | |
828 | enum grub_install_plat plat; | |
829 | const char *from, *to; | |
830 | } roms[] = | |
831 | { | |
832 | {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"}, | |
833 | {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"}, | |
834 | {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"}, | |
835 | {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"}, | |
836 | {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"}, | |
837 | {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"}, | |
838 | {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"}, | |
839 | }; | |
840 | grub_size_t i; | |
841 | for (i = 0; i < ARRAY_SIZE (roms); i++) | |
842 | { | |
843 | char *from = grub_util_path_concat (2, boot_grub, roms[i].from); | |
844 | char *to = grub_util_path_concat (2, rom_directory, roms[i].to); | |
845 | grub_install_copy_file (from, to, 0); | |
846 | } | |
847 | } | |
848 | ||
849 | xorriso_push ("--protective-msdos-label"); | |
850 | xorriso_push ("-o"); | |
851 | xorriso_push (output_image); | |
852 | xorriso_push ("-r"); | |
853 | xorriso_push (iso9660_dir); | |
854 | xorriso_push ("--sort-weight"); | |
855 | xorriso_push ("0"); | |
856 | xorriso_push ("/"); | |
857 | xorriso_push ("--sort-weight"); | |
858 | xorriso_push ("1"); | |
859 | xorriso_push ("/boot"); | |
860 | int i; | |
861 | for (i = 0; i < xorriso_tail_argc; i++) | |
862 | xorriso_push (xorriso_tail_argv[i]); | |
863 | ||
864 | xorriso_argv[xorriso_argc] = NULL; | |
865 | ||
866 | grub_util_exec ((const char *const *)xorriso_argv); | |
867 | ||
868 | grub_util_unlink_recursive (iso9660_dir); | |
869 | ||
870 | if (sysarea_img) | |
871 | grub_util_unlink (sysarea_img); | |
872 | ||
873 | free (core_services); | |
874 | free (romdir); | |
875 | return 0; | |
876 | } |