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