]> git.proxmox.com Git - grub2.git/blob - util/grub-install.c
Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig.
[grub2.git] / util / grub-install.c
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
4 *
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <config.h>
20 #include <grub/types.h>
21 #include <grub/emu/misc.h>
22 #include <grub/util/misc.h>
23 #include <grub/misc.h>
24 #include <grub/device.h>
25 #include <grub/disk.h>
26 #include <grub/file.h>
27 #include <grub/fs.h>
28 #include <grub/env.h>
29 #include <grub/term.h>
30 #include <grub/mm.h>
31 #include <grub/lib/hexdump.h>
32 #include <grub/crypto.h>
33 #include <grub/command.h>
34 #include <grub/i18n.h>
35 #include <grub/zfs/zfs.h>
36 #include <grub/util/install.h>
37 #include <grub/emu/getroot.h>
38 #include <grub/diskfilter.h>
39 #include <grub/cryptodisk.h>
40 #include <grub/legacy_parse.h>
41 #include <grub/gpt_partition.h>
42 #include <grub/emu/config.h>
43 #include <grub/util/ofpath.h>
44 #include <grub/hfsplus.h>
45
46 #include <string.h>
47
48 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
49 #pragma GCC diagnostic ignored "-Wmissing-declarations"
50 #include <argp.h>
51 #pragma GCC diagnostic error "-Wmissing-prototypes"
52 #pragma GCC diagnostic error "-Wmissing-declarations"
53
54 #include "progname.h"
55
56 static char *target;
57 static int removable = 0;
58 static int recheck = 0;
59 static int update_nvram = 1;
60 static char *install_device = NULL;
61 static char *debug_image = NULL;
62 static char *rootdir = NULL;
63 static char *bootdir = NULL;
64 static int allow_floppy = 0;
65 static int force_file_id = 0;
66 static char *disk_module = NULL;
67 static char *efidir = NULL;
68 static char *macppcdir = NULL;
69 static int force = 0;
70 static int have_abstractions = 0;
71 static int have_cryptodisk = 0;
72 static char * bootloader_id;
73 static int have_load_cfg = 0;
74 static FILE * load_cfg_f = NULL;
75 static char *load_cfg;
76 static int install_bootsector = 1;
77 static char *label_font;
78 static char *label_color;
79 static char *label_bgcolor;
80 static char *product_version;
81 static int add_rs_codes = 1;
82
83 enum
84 {
85 OPTION_BOOT_DIRECTORY = 0x301,
86 OPTION_ROOT_DIRECTORY,
87 OPTION_TARGET,
88 OPTION_SETUP,
89 OPTION_MKRELPATH,
90 OPTION_MKDEVICEMAP,
91 OPTION_PROBE,
92 OPTION_EDITENV,
93 OPTION_ALLOW_FLOPPY,
94 OPTION_RECHECK,
95 OPTION_FORCE,
96 OPTION_FORCE_FILE_ID,
97 OPTION_MODULE,
98 OPTION_NO_NVRAM,
99 OPTION_REMOVABLE,
100 OPTION_BOOTLOADER_ID,
101 OPTION_EFI_DIRECTORY,
102 OPTION_FONT,
103 OPTION_DEBUG,
104 OPTION_DEBUG_IMAGE,
105 OPTION_NO_FLOPPY,
106 OPTION_DISK_MODULE,
107 OPTION_NO_BOOTSECTOR,
108 OPTION_NO_RS_CODES,
109 OPTION_MACPPC_DIRECTORY,
110 OPTION_LABEL_FONT,
111 OPTION_LABEL_COLOR,
112 OPTION_LABEL_BGCOLOR,
113 OPTION_PRODUCT_VERSION
114 };
115
116 static int fs_probe = 1;
117
118 static error_t
119 argp_parser (int key, char *arg, struct argp_state *state)
120 {
121 if (grub_install_parse (key, arg))
122 return 0;
123 switch (key)
124 {
125 case OPTION_FORCE_FILE_ID:
126 force_file_id = 1;
127 return 0;
128 case 's':
129 fs_probe = 0;
130 return 0;
131
132 case OPTION_SETUP:
133 if (!grub_strstr (arg, "setup"))
134 install_bootsector = 0;
135 return 0;
136
137 case OPTION_PRODUCT_VERSION:
138 free (product_version);
139 product_version = xstrdup (arg);
140 return 0;
141 case OPTION_LABEL_FONT:
142 free (label_font);
143 label_font = xstrdup (arg);
144 return 0;
145
146 case OPTION_LABEL_COLOR:
147 free (label_color);
148 label_color = xstrdup (arg);
149 return 0;
150
151 case OPTION_LABEL_BGCOLOR:
152 free (label_bgcolor);
153 label_bgcolor = xstrdup (arg);
154 return 0;
155
156 /* Accept and ignore for compatibility. */
157 case OPTION_FONT:
158 case OPTION_MKRELPATH:
159 case OPTION_PROBE:
160 case OPTION_EDITENV:
161 case OPTION_MKDEVICEMAP:
162 case OPTION_NO_FLOPPY:
163 return 0;
164 case OPTION_ROOT_DIRECTORY:
165 /* Accept for compatibility. */
166 free (rootdir);
167 rootdir = xstrdup (arg);
168 return 0;
169
170 case OPTION_BOOT_DIRECTORY:
171 free (bootdir);
172 bootdir = xstrdup (arg);
173 return 0;
174
175 case OPTION_MACPPC_DIRECTORY:
176 free (macppcdir);
177 macppcdir = xstrdup (arg);
178 return 0;
179
180 case OPTION_EFI_DIRECTORY:
181 free (efidir);
182 efidir = xstrdup (arg);
183 return 0;
184
185 case OPTION_DISK_MODULE:
186 free (disk_module);
187 disk_module = xstrdup (arg);
188 return 0;
189
190 case OPTION_TARGET:
191 free (target);
192 target = xstrdup (arg);
193 return 0;
194
195 case OPTION_DEBUG_IMAGE:
196 free (debug_image);
197 debug_image = xstrdup (arg);
198 return 0;
199
200 case OPTION_NO_NVRAM:
201 update_nvram = 0;
202 return 0;
203
204 case OPTION_FORCE:
205 force = 1;
206 return 0;
207
208 case OPTION_RECHECK:
209 recheck = 1;
210 return 0;
211
212 case OPTION_REMOVABLE:
213 removable = 1;
214 return 0;
215
216 case OPTION_ALLOW_FLOPPY:
217 allow_floppy = 1;
218 return 0;
219
220 case OPTION_NO_BOOTSECTOR:
221 install_bootsector = 0;
222 return 0;
223
224 case OPTION_NO_RS_CODES:
225 add_rs_codes = 0;
226 return 0;
227
228 case OPTION_DEBUG:
229 verbosity++;
230 return 0;
231
232 case OPTION_BOOTLOADER_ID:
233 free (bootloader_id);
234 bootloader_id = xstrdup (arg);
235 return 0;
236
237 case ARGP_KEY_ARG:
238 if (install_device)
239 grub_util_error ("%s", _("More than one install device?"));
240 install_device = xstrdup (arg);
241 return 0;
242
243 default:
244 return ARGP_ERR_UNKNOWN;
245 }
246 }
247
248
249 static struct argp_option options[] = {
250 GRUB_INSTALL_OPTIONS,
251 {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"),
252 0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2},
253 {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"),
254 OPTION_HIDDEN, 0, 2},
255 {"font", OPTION_FONT, N_("FILE"),
256 OPTION_HIDDEN, 0, 2},
257 {"target", OPTION_TARGET, N_("TARGET"),
258 /* TRANSLATORS: "TARGET" as in "target platform". */
259 0, N_("install GRUB for TARGET platform [default=%s]; available targets: %s"), 2},
260 {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2},
261 {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2},
262 {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2},
263 {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2},
264 {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2},
265 {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0,
266 /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
267 effect but that it will make the resulting install unbootable from HDD. */
268 N_("make the drive also bootable as floppy (default for fdX devices)."
269 " May break on some BIOSes."), 2},
270 {"recheck", OPTION_RECHECK, 0, 0,
271 N_("delete device map if it already exists"), 2},
272 {"force", OPTION_FORCE, 0, 0,
273 N_("install even if problems are detected"), 2},
274 {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0,
275 N_("use identifier file even if UUID is available"), 2},
276 {"disk-module", OPTION_MODULE, N_("MODULE"), 0,
277 N_("disk module to use (biosdisk or native). "
278 "This option is only available on BIOS target."), 2},
279 {"no-nvram", OPTION_NO_NVRAM, 0, 0,
280 N_("don't update the `boot-device'/`Boot*' NVRAM variables. "
281 "This option is only available on EFI and IEEE1275 targets."), 2},
282 {"skip-fs-probe",'s',0, 0,
283 N_("do not probe for filesystems in DEVICE"), 0},
284 {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
285 N_("do not install bootsector"), 0},
286 {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0,
287 N_("Do not apply any reed-solomon codes when embedding core.img. "
288 "This option is only available on x86 BIOS targets."), 0},
289
290 {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
291 {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
292 {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
293 {"removable", OPTION_REMOVABLE, 0, 0,
294 N_("the installation device is removable. "
295 "This option is only available on EFI."), 2},
296 {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
297 N_("the ID of bootloader. This option is only available on EFI and Macs."), 2},
298 {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
299 N_("use DIR as the EFI System Partition root."), 2},
300 {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0,
301 N_("use DIR for PPC MAC install."), 2},
302 {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
303 {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
304 {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
305 {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
306 {0, 0, 0, 0, 0, 0}
307 };
308
309 static const char *
310 get_default_platform (void)
311 {
312 #ifdef __powerpc__
313 return "powerpc-ieee1275";
314 #elif defined (__sparc__) || defined (__sparc64__)
315 return "sparc64-ieee1275";
316 #elif defined (__MIPSEL__)
317 return "mipsel-loongson";
318 #elif defined (__MIPSEB__)
319 return "mips-arc";
320 #elif defined (__ia64__)
321 return "ia64-efi";
322 #elif defined (__arm__)
323 return "arm-uboot";
324 #elif defined (__aarch64__)
325 return "arm64-efi";
326 #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
327 return grub_install_get_default_x86_platform ();
328 #else
329 return NULL;
330 #endif
331 }
332
333 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
334
335 static char *
336 help_filter (int key, const char *text, void *input __attribute__ ((unused)))
337 {
338 switch (key)
339 {
340 case OPTION_BOOT_DIRECTORY:
341 return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
342 case OPTION_TARGET:
343 {
344 char *plats = grub_install_get_platforms_string ();
345 char *ret;
346 ret = xasprintf (text, get_default_platform (), plats);
347 free (plats);
348 return ret;
349 }
350 case ARGP_KEY_HELP_POST_DOC:
351 return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
352 default:
353 return grub_install_help_filter (key, text, input);
354 }
355 }
356
357 #pragma GCC diagnostic error "-Wformat-nonliteral"
358
359 /* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
360 install to. */
361 struct argp argp = {
362 options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"),
363 N_("Install GRUB on your drive.")"\v"
364 N_("INSTALL_DEVICE must be system device filename.\n"
365 "%s copies GRUB images into %s. On some platforms, it"
366 " may also install GRUB into the boot sector."),
367 NULL, help_filter, NULL
368 };
369
370 static int
371 probe_raid_level (grub_disk_t disk)
372 {
373 /* disk might be NULL in the case of a LVM physical volume with no LVM
374 signature. Ignore such cases here. */
375 if (!disk)
376 return -1;
377
378 if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
379 return -1;
380
381 if (disk->name[0] != 'm' || disk->name[1] != 'd')
382 return -1;
383
384 if (!((struct grub_diskfilter_lv *) disk->data)->segments)
385 return -1;
386 return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
387 }
388
389 static void
390 push_partmap_module (const char *map, void *data __attribute__ ((unused)))
391 {
392 char buf[50];
393
394 if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0)
395 {
396 grub_install_push_module ("part_bsd");
397 return;
398 }
399
400 snprintf (buf, sizeof (buf), "part_%s", map);
401 grub_install_push_module (buf);
402 }
403
404 static void
405 push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused)))
406 {
407 grub_install_push_module (mod);
408 }
409
410 static void
411 probe_mods (grub_disk_t disk)
412 {
413 grub_partition_t part;
414 grub_disk_memberlist_t list = NULL, tmp;
415 int raid_level;
416
417 if (disk->partition == NULL)
418 grub_util_info ("no partition map found for %s", disk->name);
419
420 for (part = disk->partition; part; part = part->parent)
421 push_partmap_module (part->partmap->name, NULL);
422
423 if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
424 {
425 grub_diskfilter_get_partmap (disk, push_partmap_module, NULL);
426 have_abstractions = 1;
427 }
428
429 if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
430 && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 ||
431 grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0))
432 grub_install_push_module ("lvm");
433
434 if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
435 && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
436 grub_install_push_module ("ldm");
437
438 if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
439 {
440 grub_util_cryptodisk_get_abstraction (disk,
441 push_cryptodisk_module, NULL);
442 have_abstractions = 1;
443 have_cryptodisk = 1;
444 }
445
446 raid_level = probe_raid_level (disk);
447 if (raid_level >= 0)
448 {
449 grub_install_push_module ("diskfilter");
450 if (disk->dev->raidname)
451 grub_install_push_module (disk->dev->raidname (disk));
452 }
453 if (raid_level == 5)
454 grub_install_push_module ("raid5rec");
455 if (raid_level == 6)
456 grub_install_push_module ("raid6rec");
457
458 /* In case of LVM/RAID, check the member devices as well. */
459 if (disk->dev->memberlist)
460 list = disk->dev->memberlist (disk);
461 while (list)
462 {
463 probe_mods (list->disk);
464 tmp = list->next;
465 free (list);
466 list = tmp;
467 }
468 }
469
470 static int
471 have_bootdev (enum grub_install_plat pl)
472 {
473 switch (pl)
474 {
475 case GRUB_INSTALL_PLATFORM_I386_PC:
476 case GRUB_INSTALL_PLATFORM_I386_EFI:
477 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
478 case GRUB_INSTALL_PLATFORM_IA64_EFI:
479 case GRUB_INSTALL_PLATFORM_ARM_EFI:
480 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
481 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
482 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
483 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
484 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
485 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
486 return 1;
487
488 case GRUB_INSTALL_PLATFORM_I386_QEMU:
489 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
490 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
491 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
492 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
493
494 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
495 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
496
497 case GRUB_INSTALL_PLATFORM_I386_XEN:
498 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
499 return 0;
500
501 /* pacify warning. */
502 case GRUB_INSTALL_PLATFORM_MAX:
503 return 0;
504 }
505 return 0;
506 }
507
508 static void
509 probe_cryptodisk_uuid (grub_disk_t disk)
510 {
511 grub_disk_memberlist_t list = NULL, tmp;
512
513 /* In case of LVM/RAID, check the member devices as well. */
514 if (disk->dev->memberlist)
515 {
516 list = disk->dev->memberlist (disk);
517 }
518 while (list)
519 {
520 probe_cryptodisk_uuid (list->disk);
521 tmp = list->next;
522 free (list);
523 list = tmp;
524 }
525 if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
526 {
527 const char *uuid = grub_util_cryptodisk_get_uuid (disk);
528 if (!load_cfg_f)
529 load_cfg_f = grub_util_fopen (load_cfg, "wb");
530 have_load_cfg = 1;
531
532 fprintf (load_cfg_f, "cryptomount -u %s\n",
533 uuid);
534 }
535 }
536
537 static int
538 is_same_disk (const char *a, const char *b)
539 {
540 while (1)
541 {
542 if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0'))
543 return 1;
544 if (*a != *b)
545 return 0;
546 if (*a == '\\')
547 {
548 if (a[1] != b[1])
549 return 0;
550 a += 2;
551 b += 2;
552 continue;
553 }
554 a++;
555 b++;
556 }
557 }
558
559 static char *
560 get_rndstr (void)
561 {
562 grub_uint8_t rnd[15];
563 const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
564 char * ret = xmalloc (sz + 1);
565 size_t i;
566 if (grub_get_random (rnd, sizeof (rnd)))
567 grub_util_error ("%s", _("couldn't retrieve random data"));
568 for (i = 0; i < sz; i++)
569 {
570 grub_size_t b = i * 5;
571 grub_uint8_t r;
572 grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
573 grub_size_t f2;
574 if (f1 > 5)
575 f1 = 5;
576 f2 = 5 - f1;
577 r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
578 if (f2)
579 r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
580 if (r < 10)
581 ret[i] = '0' + r;
582 else
583 ret[i] = 'a' + (r - 10);
584 }
585 ret[sz] = '\0';
586 return ret;
587 }
588
589 static char *
590 escape (const char *in)
591 {
592 char *ptr;
593 char *ret;
594 int overhead = 0;
595
596 for (ptr = (char*)in; *ptr; ptr++)
597 if (*ptr == '\'')
598 overhead += 3;
599 ret = grub_malloc (ptr - in + overhead + 1);
600 if (!ret)
601 return NULL;
602
603 grub_strchrsub (ret, in, '\'', "'\\''");
604 return ret;
605 }
606
607 static struct grub_util_config config;
608
609 static void
610 device_map_check_duplicates (const char *dev_map)
611 {
612 FILE *fp;
613 char buf[1024]; /* XXX */
614 size_t alloced = 8;
615 size_t filled = 0;
616 char **d;
617 size_t i;
618
619 d = xmalloc (alloced * sizeof (d[0]));
620
621 if (dev_map[0] == '\0')
622 return;
623
624 fp = grub_util_fopen (dev_map, "r");
625 if (! fp)
626 return;
627
628 while (fgets (buf, sizeof (buf), fp))
629 {
630 char *p = buf;
631 char *e;
632
633 /* Skip leading spaces. */
634 while (*p && grub_isspace (*p))
635 p++;
636
637 /* If the first character is `#' or NUL, skip this line. */
638 if (*p == '\0' || *p == '#')
639 continue;
640
641 if (*p != '(')
642 continue;
643
644 p++;
645
646 e = p;
647 p = strchr (p, ')');
648 if (! p)
649 continue;
650
651 if (filled >= alloced)
652 {
653 alloced *= 2;
654 d = xrealloc (d, alloced * sizeof (d[0]));
655 }
656
657 *p = '\0';
658
659 d[filled++] = xstrdup (e);
660 }
661
662 fclose (fp);
663
664 qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp);
665
666 for (i = 0; i + 1 < filled; i++)
667 if (strcmp (d[i], d[i+1]) == 0)
668 {
669 grub_util_error (_("the drive %s is defined multiple times in the device map %s"),
670 d[i], dev_map);
671 }
672
673 for (i = 0; i < filled; i++)
674 free (d[i]);
675
676 free (d);
677 }
678
679 static grub_err_t
680 write_to_disk (grub_device_t dev, const char *fn)
681 {
682 char *core_img;
683 size_t core_size;
684 grub_err_t err;
685
686 core_size = grub_util_get_image_size (fn);
687
688 core_img = grub_util_read_image (fn);
689
690 grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name);
691 err = grub_disk_write (dev->disk, 0, 0,
692 core_size, core_img);
693 free (core_img);
694 return err;
695 }
696
697 static int
698 is_prep_partition (grub_device_t dev)
699 {
700 if (!dev->disk)
701 return 0;
702 if (!dev->disk->partition)
703 return 0;
704 if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
705 return (dev->disk->partition->msdostype == 0x41);
706
707 if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
708 {
709 struct grub_gpt_partentry gptdata;
710 grub_partition_t p = dev->disk->partition;
711 int ret = 0;
712 dev->disk->partition = dev->disk->partition->parent;
713
714 if (grub_disk_read (dev->disk, p->offset, p->index,
715 sizeof (gptdata), &gptdata) == 0)
716 {
717 const grub_gpt_part_type_t template = {
718 grub_cpu_to_le32_compile_time (0x9e1a2d38),
719 grub_cpu_to_le16_compile_time (0xc612),
720 grub_cpu_to_le16_compile_time (0x4316),
721 { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
722 };
723
724 ret = grub_memcmp (&template, &gptdata.type,
725 sizeof (template)) == 0;
726 }
727 dev->disk->partition = p;
728 return ret;
729 }
730
731 return 0;
732 }
733
734 static int
735 is_prep_empty (grub_device_t dev)
736 {
737 grub_disk_addr_t dsize, addr;
738 grub_uint32_t buffer[32768];
739
740 dsize = grub_disk_get_size (dev->disk);
741 for (addr = 0; addr < dsize;
742 addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
743 {
744 grub_size_t sz = sizeof (buffer);
745 grub_uint32_t *ptr;
746
747 if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
748 sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
749 grub_disk_read (dev->disk, addr, 0, sz, buffer);
750
751 if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0)
752 return 1;
753
754 for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
755 if (*ptr)
756 return 0;
757 }
758
759 return 1;
760 }
761
762 static void
763 bless (grub_device_t dev, const char *path, int x86)
764 {
765 struct stat st;
766 grub_err_t err;
767
768 grub_util_info ("blessing %s", path);
769
770 if (stat (path, &st) < 0)
771 grub_util_error (N_("cannot stat `%s': %s"),
772 path, strerror (errno));
773
774 err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
775 if (err)
776 grub_util_error ("%s", grub_errmsg);
777 grub_util_info ("blessed\n");
778 }
779
780 static void
781 fill_core_services (const char *core_services)
782 {
783 char *label;
784 FILE *f;
785 char *label_text;
786 char *label_string = xasprintf ("%s %s", bootloader_id, product_version);
787 char *sysv_plist;
788
789 label = grub_util_path_concat (2, core_services, ".disk_label");
790 grub_util_info ("rendering label %s", label_string);
791 grub_util_render_label (label_font, label_bgcolor ? : "white",
792 label_color ? : "black", label_string, label);
793 grub_util_info ("label rendered");
794 free (label);
795 label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
796 f = grub_util_fopen (label_text, "wb");
797 fprintf (f, "%s\n", label_string);
798 fclose (f);
799 free (label_string);
800 free (label_text);
801
802 sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist");
803 f = grub_util_fopen (sysv_plist, "wb");
804 fprintf (f,
805 "<plist version=\"1.0\">\n"
806 "<dict>\n"
807 " <key>ProductBuildVersion</key>\n"
808 " <string></string>\n"
809 " <key>ProductName</key>\n"
810 " <string>%s</string>\n"
811 " <key>ProductVersion</key>\n"
812 " <string>%s</string>\n"
813 "</dict>\n"
814 "</plist>\n", bootloader_id, product_version);
815 fclose (f);
816 free (sysv_plist);
817 }
818
819 int
820 main (int argc, char *argv[])
821 {
822 int is_efi = 0;
823 const char *efi_distributor = NULL;
824 const char *efi_file = NULL;
825 char **grub_devices;
826 grub_fs_t grub_fs;
827 grub_device_t grub_dev = NULL;
828 enum grub_install_plat platform;
829 char *grubdir, *device_map;
830 char **curdev, **curdrive;
831 char **grub_drives;
832 char *relative_grubdir;
833 char **efidir_device_names = NULL;
834 grub_device_t efidir_grub_dev = NULL;
835 char *efidir_grub_devname;
836 int efidir_is_mac = 0;
837 int is_prep = 0;
838 const char *pkgdatadir;
839
840 grub_util_host_init (&argc, &argv);
841 product_version = xstrdup (PACKAGE_VERSION);
842 pkgdatadir = grub_util_get_pkgdatadir ();
843 label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
844
845 argp_parse (&argp, argc, argv, 0, 0, 0);
846
847 if (verbosity > 1)
848 grub_env_set ("debug", "all");
849
850 grub_util_load_config (&config);
851
852 if (!bootloader_id && config.grub_distributor)
853 {
854 char *ptr;
855 bootloader_id = xstrdup (config.grub_distributor);
856 for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++)
857 if (*ptr >= 'A' && *ptr <= 'Z')
858 *ptr = *ptr - 'A' + 'a';
859 *ptr = '\0';
860 }
861 if (!bootloader_id || bootloader_id[0] == '\0')
862 {
863 free (bootloader_id);
864 bootloader_id = xstrdup ("grub");
865 }
866
867 if (!grub_install_source_directory)
868 {
869 if (!target)
870 {
871 const char * t;
872 t = get_default_platform ();
873 if (!t)
874 grub_util_error ("%s",
875 _("Unable to determine your platform."
876 " Use --target.")
877 );
878 target = xstrdup (t);
879 }
880 grub_install_source_directory
881 = grub_util_path_concat (2, grub_util_get_pkglibdir (), target);
882 }
883
884 platform = grub_install_get_target (grub_install_source_directory);
885
886 {
887 char *platname = grub_install_get_platform_name (platform);
888 fprintf (stderr, _("Installing for %s platform.\n"), platname);
889 free (platname);
890 }
891
892 switch (platform)
893 {
894 case GRUB_INSTALL_PLATFORM_I386_PC:
895 if (!disk_module)
896 disk_module = xstrdup ("biosdisk");
897 break;
898 case GRUB_INSTALL_PLATFORM_I386_EFI:
899 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
900 case GRUB_INSTALL_PLATFORM_ARM_EFI:
901 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
902 case GRUB_INSTALL_PLATFORM_IA64_EFI:
903 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
904 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
905 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
906 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
907 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
908 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
909 case GRUB_INSTALL_PLATFORM_I386_XEN:
910 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
911 break;
912
913 case GRUB_INSTALL_PLATFORM_I386_QEMU:
914 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
915 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
916 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
917 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
918 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
919 disk_module = xstrdup ("native");
920 break;
921
922 /* pacify warning. */
923 case GRUB_INSTALL_PLATFORM_MAX:
924 break;
925 }
926
927 switch (platform)
928 {
929 case GRUB_INSTALL_PLATFORM_I386_PC:
930 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
931 if (!install_device)
932 grub_util_error ("%s", _("install device isn't specified"));
933 break;
934 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
935 if (install_device)
936 is_prep = 1;
937 break;
938 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
939 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
940 break;
941 case GRUB_INSTALL_PLATFORM_I386_EFI:
942 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
943 case GRUB_INSTALL_PLATFORM_ARM_EFI:
944 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
945 case GRUB_INSTALL_PLATFORM_IA64_EFI:
946 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
947 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
948 case GRUB_INSTALL_PLATFORM_I386_QEMU:
949 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
950 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
951 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
952 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
953 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
954 case GRUB_INSTALL_PLATFORM_I386_XEN:
955 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
956 free (install_device);
957 install_device = NULL;
958 break;
959
960 /* pacify warning. */
961 case GRUB_INSTALL_PLATFORM_MAX:
962 break;
963 }
964
965 if (!bootdir)
966 bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME);
967
968 {
969 char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME);
970 grub_install_mkdir_p (t);
971 grubdir = canonicalize_file_name (t);
972 if (!grubdir)
973 grub_util_error (_("failed to get canonical path of `%s'"), t);
974 free (t);
975 }
976 device_map = grub_util_path_concat (2, grubdir, "device.map");
977
978 if (recheck)
979 grub_util_unlink (device_map);
980
981 device_map_check_duplicates (device_map);
982 grub_util_biosdisk_init (device_map);
983
984 /* Initialize all modules. */
985 grub_init_all ();
986 grub_gcry_init_all ();
987 grub_hostfs_init ();
988 grub_host_init ();
989
990 switch (platform)
991 {
992 case GRUB_INSTALL_PLATFORM_I386_EFI:
993 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
994 case GRUB_INSTALL_PLATFORM_ARM_EFI:
995 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
996 case GRUB_INSTALL_PLATFORM_IA64_EFI:
997 is_efi = 1;
998 break;
999 default:
1000 is_efi = 0;
1001 break;
1002
1003 /* pacify warning. */
1004 case GRUB_INSTALL_PLATFORM_MAX:
1005 break;
1006 }
1007
1008 /* Find the EFI System Partition. */
1009
1010 if (is_efi)
1011 {
1012 grub_fs_t fs;
1013 free (install_device);
1014 install_device = NULL;
1015 if (!efidir)
1016 {
1017 char *d = grub_util_path_concat (2, bootdir, "efi");
1018 char *dr = NULL;
1019 if (!grub_util_is_directory (d))
1020 {
1021 free (d);
1022 d = grub_util_path_concat (2, bootdir, "EFI");
1023 }
1024 /*
1025 The EFI System Partition may have been given directly using
1026 --root-directory.
1027 */
1028 if (!grub_util_is_directory (d)
1029 && rootdir && grub_strcmp (rootdir, "/") != 0)
1030 {
1031 free (d);
1032 d = xstrdup (rootdir);
1033 }
1034 if (grub_util_is_directory (d))
1035 dr = grub_make_system_path_relative_to_its_root (d);
1036 /* Is it a mount point? */
1037 if (dr && dr[0] == '\0')
1038 efidir = d;
1039 else
1040 free (d);
1041 free (dr);
1042 }
1043 if (!efidir)
1044 grub_util_error ("%s", _("cannot find EFI directory"));
1045 efidir_device_names = grub_guess_root_devices (efidir);
1046 if (!efidir_device_names || !efidir_device_names[0])
1047 grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1048 efidir);
1049 install_device = efidir_device_names[0];
1050
1051 for (curdev = efidir_device_names; *curdev; curdev++)
1052 grub_util_pull_device (*curdev);
1053
1054 efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]);
1055 if (!efidir_grub_devname)
1056 grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
1057 efidir_device_names[0]);
1058
1059 efidir_grub_dev = grub_device_open (efidir_grub_devname);
1060 if (! efidir_grub_dev)
1061 grub_util_error ("%s", grub_errmsg);
1062
1063 fs = grub_fs_probe (efidir_grub_dev);
1064 if (! fs)
1065 grub_util_error ("%s", grub_errmsg);
1066
1067 efidir_is_mac = 0;
1068
1069 if (grub_strcmp (fs->name, "hfs") == 0
1070 || grub_strcmp (fs->name, "hfsplus") == 0)
1071 efidir_is_mac = 1;
1072
1073 if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
1074 grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir);
1075
1076 /* The EFI specification requires that an EFI System Partition must
1077 contain an "EFI" subdirectory, and that OS loaders are stored in
1078 subdirectories below EFI. Vendors are expected to pick names that do
1079 not collide with other vendors. To minimise collisions, we use the
1080 name of our distributor if possible.
1081 */
1082 char *t;
1083 efi_distributor = bootloader_id;
1084 if (removable)
1085 {
1086 /* The specification makes stricter requirements of removable
1087 devices, in order that only one image can be automatically loaded
1088 from them. The image must always reside under /EFI/BOOT, and it
1089 must have a specific file name depending on the architecture.
1090 */
1091 efi_distributor = "BOOT";
1092 switch (platform)
1093 {
1094 case GRUB_INSTALL_PLATFORM_I386_EFI:
1095 efi_file = "BOOTIA32.EFI";
1096 break;
1097 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1098 efi_file = "BOOTX64.EFI";
1099 break;
1100 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1101 efi_file = "BOOTIA64.EFI";
1102 break;
1103 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1104 efi_file = "BOOTARM.EFI";
1105 break;
1106 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1107 efi_file = "BOOTAA64.EFI";
1108 break;
1109 default:
1110 grub_util_error ("%s", _("You've found a bug"));
1111 break;
1112 }
1113 }
1114 else
1115 {
1116 /* It is convenient for each architecture to have a different
1117 efi_file, so that different versions can be installed in parallel.
1118 */
1119 switch (platform)
1120 {
1121 case GRUB_INSTALL_PLATFORM_I386_EFI:
1122 efi_file = "grubia32.efi";
1123 break;
1124 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1125 efi_file = "grubx64.efi";
1126 break;
1127 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1128 efi_file = "grubia64.efi";
1129 break;
1130 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1131 efi_file = "grubarm.efi";
1132 break;
1133 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1134 efi_file = "grubaa64.efi";
1135 break;
1136 default:
1137 efi_file = "grub.efi";
1138 break;
1139 }
1140 }
1141 t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
1142 free (efidir);
1143 efidir = t;
1144 grub_install_mkdir_p (efidir);
1145 }
1146
1147 if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
1148 {
1149 int is_guess = 0;
1150 if (!macppcdir)
1151 {
1152 char *d;
1153
1154 is_guess = 1;
1155 d = grub_util_path_concat (2, bootdir, "macppc");
1156 if (!grub_util_is_directory (d))
1157 {
1158 free (d);
1159 d = grub_util_path_concat (2, bootdir, "efi");
1160 }
1161 /* Find the Mac HFS(+) System Partition. */
1162 if (!grub_util_is_directory (d))
1163 {
1164 free (d);
1165 d = grub_util_path_concat (2, bootdir, "EFI");
1166 }
1167 if (!grub_util_is_directory (d))
1168 {
1169 free (d);
1170 d = 0;
1171 }
1172 if (d)
1173 macppcdir = d;
1174 }
1175 if (macppcdir)
1176 {
1177 char **macppcdir_device_names = NULL;
1178 grub_device_t macppcdir_grub_dev = NULL;
1179 char *macppcdir_grub_devname;
1180 grub_fs_t fs;
1181
1182 macppcdir_device_names = grub_guess_root_devices (macppcdir);
1183 if (!macppcdir_device_names || !macppcdir_device_names[0])
1184 grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1185 macppcdir);
1186
1187 for (curdev = macppcdir_device_names; *curdev; curdev++)
1188 grub_util_pull_device (*curdev);
1189
1190 macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]);
1191 if (!macppcdir_grub_devname)
1192 grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
1193 macppcdir_device_names[0]);
1194
1195 macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname);
1196 if (! macppcdir_grub_dev)
1197 grub_util_error ("%s", grub_errmsg);
1198
1199 fs = grub_fs_probe (macppcdir_grub_dev);
1200 if (! fs)
1201 grub_util_error ("%s", grub_errmsg);
1202
1203 if (grub_strcmp (fs->name, "hfs") != 0
1204 && grub_strcmp (fs->name, "hfsplus") != 0
1205 && !is_guess)
1206 grub_util_error (_("filesystem on %s is neither HFS nor HFS+"),
1207 macppcdir);
1208 if (grub_strcmp (fs->name, "hfs") == 0
1209 || grub_strcmp (fs->name, "hfsplus") == 0)
1210 {
1211 install_device = macppcdir_device_names[0];
1212 is_prep = 0;
1213 }
1214 }
1215 }
1216
1217 grub_install_copy_files (grub_install_source_directory,
1218 grubdir, platform);
1219
1220 char *envfile = grub_util_path_concat (2, grubdir, "grubenv");
1221 if (!grub_util_is_regular (envfile))
1222 grub_util_create_envblk_file (envfile);
1223
1224 size_t ndev = 0;
1225
1226 /* Write device to a variable so we don't have to traverse /dev every time. */
1227 grub_devices = grub_guess_root_devices (grubdir);
1228 if (!grub_devices || !grub_devices[0])
1229 grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1230 grubdir);
1231
1232 for (curdev = grub_devices; *curdev; curdev++)
1233 {
1234 grub_util_pull_device (*curdev);
1235 ndev++;
1236 }
1237
1238 grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1));
1239
1240 for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
1241 curdrive++)
1242 {
1243 *curdrive = grub_util_get_grub_dev (*curdev);
1244 if (! *curdrive)
1245 grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
1246 *curdev);
1247 }
1248 *curdrive = 0;
1249
1250 grub_dev = grub_device_open (grub_drives[0]);
1251 if (! grub_dev)
1252 grub_util_error ("%s", grub_errmsg);
1253
1254 grub_fs = grub_fs_probe (grub_dev);
1255 if (! grub_fs)
1256 grub_util_error ("%s", grub_errmsg);
1257
1258 grub_install_push_module (grub_fs->name);
1259
1260 if (grub_dev->disk)
1261 probe_mods (grub_dev->disk);
1262
1263 for (curdrive = grub_drives + 1; *curdrive; curdrive++)
1264 {
1265 grub_device_t dev = grub_device_open (*curdrive);
1266 if (!dev)
1267 continue;
1268 if (dev->disk)
1269 probe_mods (dev->disk);
1270 grub_device_close (dev);
1271 }
1272
1273 if (!config.is_cryptodisk_enabled && have_cryptodisk)
1274 grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. "
1275 "Set `%s' in file `%s'."), "GRUB_ENABLE_CRYPTODISK=y",
1276 grub_util_get_config_filename ());
1277
1278 if (disk_module && grub_strcmp (disk_module, "ata") == 0)
1279 grub_install_push_module ("pata");
1280 else if (disk_module && grub_strcmp (disk_module, "native") == 0)
1281 {
1282 grub_install_push_module ("pata");
1283 grub_install_push_module ("ahci");
1284 grub_install_push_module ("ohci");
1285 grub_install_push_module ("uhci");
1286 grub_install_push_module ("usbms");
1287 }
1288 else if (disk_module && disk_module[0])
1289 grub_install_push_module (disk_module);
1290
1291 relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir);
1292 if (relative_grubdir[0] == '\0')
1293 {
1294 free (relative_grubdir);
1295 relative_grubdir = xstrdup ("/");
1296 }
1297
1298 char *platname = grub_install_get_platform_name (platform);
1299 char *platdir;
1300 {
1301 char *t = grub_util_path_concat (2, grubdir,
1302 platname);
1303 platdir = canonicalize_file_name (t);
1304 if (!platdir)
1305 grub_util_error (_("failed to get canonical path of `%s'"),
1306 t);
1307 free (t);
1308 }
1309 load_cfg = grub_util_path_concat (2, platdir,
1310 "load.cfg");
1311
1312 grub_util_unlink (load_cfg);
1313
1314 if (debug_image && debug_image[0])
1315 {
1316 load_cfg_f = grub_util_fopen (load_cfg, "wb");
1317 have_load_cfg = 1;
1318 fprintf (load_cfg_f, "set debug='%s'\n",
1319 debug_image);
1320 }
1321 char *prefix_drive = NULL;
1322 char *install_drive = NULL;
1323
1324 if (install_device)
1325 {
1326 if (install_device[0] == '('
1327 && install_device[grub_strlen (install_device) - 1] == ')')
1328 {
1329 size_t len = grub_strlen (install_device) - 2;
1330 install_drive = xmalloc (len + 1);
1331 memcpy (install_drive, install_device + 1, len);
1332 install_drive[len] = '\0';
1333 }
1334 else
1335 {
1336 grub_util_pull_device (install_device);
1337 install_drive = grub_util_get_grub_dev (install_device);
1338 if (!install_drive)
1339 grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
1340 install_device);
1341 }
1342 }
1343
1344 if (!have_abstractions)
1345 {
1346 if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
1347 || grub_drives[1]
1348 || (!install_drive
1349 && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
1350 || (install_drive && !is_same_disk (grub_drives[0], install_drive))
1351 || !have_bootdev (platform))
1352 {
1353 char *uuid = NULL;
1354 /* generic method (used on coreboot and ata mod). */
1355 if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev,
1356 &uuid))
1357 {
1358 grub_print_error ();
1359 grub_errno = 0;
1360 uuid = NULL;
1361 }
1362
1363 if (!load_cfg_f)
1364 load_cfg_f = grub_util_fopen (load_cfg, "wb");
1365 have_load_cfg = 1;
1366 if (uuid)
1367 {
1368 fprintf (load_cfg_f, "search.fs_uuid %s root ",
1369 uuid);
1370 grub_install_push_module ("search_fs_uuid");
1371 }
1372 else
1373 {
1374 char *rndstr = get_rndstr ();
1375 char *fl = grub_util_path_concat (3, grubdir,
1376 "uuid", rndstr);
1377 char *fldir = grub_util_path_concat (2, grubdir,
1378 "uuid");
1379 char *relfl;
1380 FILE *flf;
1381 grub_install_mkdir_p (fldir);
1382 flf = grub_util_fopen (fl, "w");
1383 if (!flf)
1384 grub_util_error (_("Can't create file: %s"), strerror (errno));
1385 fclose (flf);
1386 relfl = grub_make_system_path_relative_to_its_root (fl);
1387 fprintf (load_cfg_f, "search.file %s root ",
1388 relfl);
1389 grub_install_push_module ("search_fs_file");
1390 }
1391 for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
1392 curdrive++)
1393 {
1394 const char *map;
1395 char *g = NULL;
1396 grub_device_t dev;
1397 if (curdrive == grub_drives)
1398 dev = grub_dev;
1399 else
1400 dev = grub_device_open (*curdrive);
1401 if (!dev)
1402 continue;
1403
1404 if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
1405 {
1406 grub_util_fprint_full_disk_name (load_cfg_f,
1407 dev->disk->name,
1408 dev);
1409 fprintf (load_cfg_f, " ");
1410 if (dev != grub_dev)
1411 grub_device_close (dev);
1412 continue;
1413 }
1414
1415 map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
1416
1417 if (map)
1418 {
1419 grub_util_fprint_full_disk_name (load_cfg_f, map, dev);
1420 fprintf (load_cfg_f, " ");
1421 }
1422
1423
1424 if (disk_module && disk_module[0]
1425 && grub_strcmp (disk_module, "biosdisk") != 0)
1426 g = grub_util_guess_baremetal_drive (*curdev);
1427 else
1428 switch (platform)
1429 {
1430 case GRUB_INSTALL_PLATFORM_I386_PC:
1431 g = grub_util_guess_bios_drive (*curdev);
1432 break;
1433 case GRUB_INSTALL_PLATFORM_I386_EFI:
1434 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1435 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1436 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1437 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1438 g = grub_util_guess_efi_drive (*curdev);
1439 break;
1440 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1441 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1442 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1443 {
1444 const char * ofpath = grub_util_devname_to_ofpath (*curdev);
1445 g = xasprintf ("ieee1275/%s", ofpath);
1446 break;
1447 }
1448 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1449 case GRUB_INSTALL_PLATFORM_I386_QEMU:
1450 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1451 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1452 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1453 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1454 g = grub_util_guess_baremetal_drive (*curdev);
1455 break;
1456 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1457 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1458 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1459 case GRUB_INSTALL_PLATFORM_I386_XEN:
1460 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1461 grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
1462 break;
1463 /* pacify warning. */
1464 case GRUB_INSTALL_PLATFORM_MAX:
1465 break;
1466 }
1467 if (g)
1468 {
1469 grub_util_fprint_full_disk_name (load_cfg_f, g, dev);
1470 fprintf (load_cfg_f, " ");
1471 }
1472 if (dev != grub_dev)
1473 grub_device_close (dev);
1474 }
1475 fprintf (load_cfg_f, "\n");
1476 char *escaped_relpath = escape (relative_grubdir);
1477 fprintf (load_cfg_f, "set prefix=($root)'%s'\n",
1478 escaped_relpath);
1479 }
1480 else
1481 {
1482 /* We need to hardcode the partition number in the core image's prefix. */
1483 char *p;
1484 for (p = grub_drives[0]; *p; )
1485 {
1486 if (*p == '\\' && p[1])
1487 {
1488 p += 2;
1489 continue;
1490 }
1491 if (*p == ',' || *p == '\0')
1492 break;
1493 p++;
1494 }
1495 prefix_drive = xasprintf ("(%s)", p);
1496 }
1497 }
1498 else
1499 {
1500 if (config.is_cryptodisk_enabled)
1501 {
1502 if (grub_dev->disk)
1503 probe_cryptodisk_uuid (grub_dev->disk);
1504
1505 for (curdrive = grub_drives + 1; *curdrive; curdrive++)
1506 {
1507 grub_device_t dev = grub_device_open (*curdrive);
1508 if (!dev)
1509 continue;
1510 if (dev->disk)
1511 probe_cryptodisk_uuid (dev->disk);
1512 grub_device_close (dev);
1513 }
1514 }
1515 prefix_drive = xasprintf ("(%s)", grub_drives[0]);
1516 }
1517
1518 char mkimage_target[200];
1519 const char *core_name = NULL;
1520
1521 switch (platform)
1522 {
1523 case GRUB_INSTALL_PLATFORM_I386_EFI:
1524 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1525 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1526 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1527 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1528 core_name = "core.efi";
1529 snprintf (mkimage_target, sizeof (mkimage_target),
1530 "%s-%s",
1531 grub_install_get_platform_cpu (platform),
1532 grub_install_get_platform_platform (platform));
1533 break;
1534 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1535 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1536 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1537 core_name = "core.elf";
1538 snprintf (mkimage_target, sizeof (mkimage_target),
1539 "%s-%s-elf",
1540 grub_install_get_platform_cpu (platform),
1541 grub_install_get_platform_platform (platform));
1542 break;
1543
1544 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1545 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1546 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1547 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1548 case GRUB_INSTALL_PLATFORM_I386_XEN:
1549 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1550 core_name = "core.elf";
1551 snprintf (mkimage_target, sizeof (mkimage_target),
1552 "%s-%s",
1553 grub_install_get_platform_cpu (platform),
1554 grub_install_get_platform_platform (platform));
1555 break;
1556
1557
1558 case GRUB_INSTALL_PLATFORM_I386_PC:
1559 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1560 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1561 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1562 case GRUB_INSTALL_PLATFORM_I386_QEMU:
1563 snprintf (mkimage_target, sizeof (mkimage_target),
1564 "%s-%s",
1565 grub_install_get_platform_cpu (platform),
1566 grub_install_get_platform_platform (platform));
1567 core_name = "core.img";
1568 break;
1569 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1570 strcpy (mkimage_target, "sparc64-ieee1275-raw");
1571 core_name = "core.img";
1572 break;
1573 /* pacify warning. */
1574 case GRUB_INSTALL_PLATFORM_MAX:
1575 break;
1576 }
1577
1578 if (!core_name)
1579 grub_util_error ("%s", _("You've found a bug"));
1580
1581 if (load_cfg_f)
1582 fclose (load_cfg_f);
1583
1584 char *imgfile = grub_util_path_concat (2, platdir,
1585 core_name);
1586 char *prefix = xasprintf ("%s%s", prefix_drive ? : "",
1587 relative_grubdir);
1588 grub_install_make_image_wrap (/* source dir */ grub_install_source_directory,
1589 /*prefix */ prefix,
1590 /* output */ imgfile,
1591 /* memdisk */ NULL,
1592 have_load_cfg ? load_cfg : NULL,
1593 /* image target */ mkimage_target, 0);
1594 /* Backward-compatibility kludges. */
1595 switch (platform)
1596 {
1597 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1598 {
1599 char *dst = grub_util_path_concat (2, bootdir, "grub.elf");
1600 grub_install_copy_file (imgfile, dst, 1);
1601 free (dst);
1602 }
1603 break;
1604
1605 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1606 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1607 {
1608 char *dst = grub_util_path_concat (2, grubdir, "grub");
1609 grub_install_copy_file (imgfile, dst, 1);
1610 free (dst);
1611 }
1612 break;
1613
1614 case GRUB_INSTALL_PLATFORM_I386_EFI:
1615 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1616 {
1617 char *dst = grub_util_path_concat (2, platdir, "grub.efi");
1618 grub_install_make_image_wrap (/* source dir */ grub_install_source_directory,
1619 /* prefix */ "",
1620 /* output */ dst,
1621 /* memdisk */ NULL,
1622 have_load_cfg ? load_cfg : NULL,
1623 /* image target */ mkimage_target, 0);
1624 }
1625 break;
1626 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1627 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1628 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1629 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1630 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1631 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1632 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1633 case GRUB_INSTALL_PLATFORM_I386_PC:
1634 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1635 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1636 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1637 case GRUB_INSTALL_PLATFORM_I386_QEMU:
1638 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1639 case GRUB_INSTALL_PLATFORM_I386_XEN:
1640 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1641 break;
1642 /* pacify warning. */
1643 case GRUB_INSTALL_PLATFORM_MAX:
1644 break;
1645 }
1646
1647 /* Perform the platform-dependent install */
1648
1649 switch (platform)
1650 {
1651 case GRUB_INSTALL_PLATFORM_I386_PC:
1652 {
1653 char *boot_img_src = grub_util_path_concat (2,
1654 grub_install_source_directory,
1655 "boot.img");
1656 char *boot_img = grub_util_path_concat (2, platdir,
1657 "boot.img");
1658 grub_install_copy_file (boot_img_src, boot_img, 1);
1659
1660 grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'",
1661 /* TRANSLATORS: This is a prefix in the log to indicate that usually
1662 a command would be executed but due to an option was skipped. */
1663 install_bootsector ? "" : _("NOT RUNNING: "),
1664 allow_floppy ? "--allow-floppy " : "",
1665 verbosity ? "--verbose " : "",
1666 force ? "--force " : "",
1667 !fs_probe ? "--skip-fs-probe" : "",
1668 !add_rs_codes ? "--no-rs-codes" : "",
1669 platdir,
1670 device_map,
1671 install_device);
1672
1673 /* Now perform the installation. */
1674 if (install_bootsector)
1675 grub_util_bios_setup (platdir, "boot.img", "core.img",
1676 install_drive, force,
1677 fs_probe, allow_floppy, add_rs_codes);
1678 break;
1679 }
1680 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1681 {
1682 char *boot_img_src = grub_util_path_concat (2,
1683 grub_install_source_directory,
1684 "boot.img");
1685 char *boot_img = grub_util_path_concat (2, platdir,
1686 "boot.img");
1687 grub_install_copy_file (boot_img_src, boot_img, 1);
1688
1689 grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
1690 install_bootsector ? "" : "NOT RUNNING: ",
1691 allow_floppy ? "--allow-floppy " : "",
1692 verbosity ? "--verbose " : "",
1693 force ? "--force " : "",
1694 !fs_probe ? "--skip-fs-probe" : "",
1695 platdir,
1696 device_map,
1697 install_drive);
1698
1699 /* Now perform the installation. */
1700 if (install_bootsector)
1701 grub_util_sparc_setup (platdir, "boot.img", "core.img",
1702 install_device, force,
1703 fs_probe, allow_floppy,
1704 0 /* unused */ );
1705 break;
1706 }
1707
1708 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1709 if (macppcdir)
1710 {
1711 char *core_services = grub_util_path_concat (4, macppcdir,
1712 "System", "Library",
1713 "CoreServices");
1714 char *mach_kernel = grub_util_path_concat (2, macppcdir,
1715 "mach_kernel");
1716 char *grub_elf, *bootx;
1717 FILE *f;
1718 grub_device_t ins_dev;
1719 char *grub_chrp = grub_util_path_concat (2,
1720 grub_install_source_directory,
1721 "grub.chrp");
1722
1723 grub_install_mkdir_p (core_services);
1724
1725 bootx = grub_util_path_concat (2, core_services, "BootX");
1726 grub_install_copy_file (grub_chrp, bootx, 1);
1727
1728 grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
1729 grub_install_copy_file (imgfile, grub_elf, 1);
1730
1731 f = grub_util_fopen (mach_kernel, "r+");
1732 if (!f)
1733 grub_util_error (_("Can't create file: %s"), strerror (errno));
1734 fclose (f);
1735
1736 fill_core_services (core_services);
1737
1738 ins_dev = grub_device_open (install_drive);
1739
1740 bless (ins_dev, core_services, 0);
1741
1742 if (update_nvram)
1743 {
1744 const char *dev;
1745 int partno;
1746
1747 partno = ins_dev->disk->partition
1748 ? ins_dev->disk->partition->number + 1 : 0;
1749 dev = grub_util_get_os_disk (install_device);
1750 grub_install_register_ieee1275 (0, dev, partno,
1751 "\\\\BootX");
1752 }
1753 grub_device_close (ins_dev);
1754 free (grub_elf);
1755 free (bootx);
1756 free (mach_kernel);
1757 free (grub_chrp);
1758 break;
1759 }
1760 /* If a install device is defined, copy the core.elf to PReP partition. */
1761 if (is_prep && install_device && install_device[0])
1762 {
1763 grub_device_t ins_dev;
1764 ins_dev = grub_device_open (install_drive);
1765 if (!ins_dev || !is_prep_partition (ins_dev))
1766 {
1767 grub_util_error ("%s", _("the chosen partition is not a PReP partition"));
1768 }
1769 if (is_prep_empty (ins_dev))
1770 {
1771 if (write_to_disk (ins_dev, imgfile))
1772 grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
1773 }
1774 else
1775 {
1776 char *s = xasprintf ("dd if=/dev/zero of=%s", install_device);
1777 grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"),
1778 s);
1779 }
1780 grub_device_close (ins_dev);
1781 if (update_nvram)
1782 grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
1783 0, NULL);
1784 break;
1785 }
1786 /* fallthrough. */
1787 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1788 if (update_nvram)
1789 {
1790 const char *dev;
1791 char *relpath;
1792 int partno;
1793 relpath = grub_make_system_path_relative_to_its_root (imgfile);
1794 partno = grub_dev->disk->partition
1795 ? grub_dev->disk->partition->number + 1 : 0;
1796 dev = grub_util_get_os_disk (grub_devices[0]);
1797 grub_install_register_ieee1275 (0, dev,
1798 partno, relpath);
1799 }
1800 break;
1801 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1802 grub_install_sgi_setup (install_device, imgfile, "grub");
1803 break;
1804
1805 case GRUB_INSTALL_PLATFORM_I386_EFI:
1806 if (!efidir_is_mac)
1807 {
1808 char *dst = grub_util_path_concat (2, efidir, "grub.efi");
1809 /* For old macs. Suggested by Peter Jones. */
1810 grub_install_copy_file (imgfile, dst, 1);
1811 free (dst);
1812 }
1813
1814 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1815 if (efidir_is_mac)
1816 {
1817 char *boot_efi;
1818 char *core_services = grub_util_path_concat (4, efidir,
1819 "System", "Library",
1820 "CoreServices");
1821 char *mach_kernel = grub_util_path_concat (2, efidir,
1822 "mach_kernel");
1823 FILE *f;
1824 grub_device_t ins_dev;
1825
1826 grub_install_mkdir_p (core_services);
1827
1828 boot_efi = grub_util_path_concat (2, core_services, "boot.efi");
1829 grub_install_copy_file (imgfile, boot_efi, 1);
1830
1831 f = grub_util_fopen (mach_kernel, "r+");
1832 if (!f)
1833 grub_util_error (_("Can't create file: %s"), strerror (errno));
1834 fclose (f);
1835
1836 fill_core_services(core_services);
1837
1838 ins_dev = grub_device_open (install_drive);
1839
1840 bless (ins_dev, boot_efi, 1);
1841 if (!removable && update_nvram)
1842 {
1843 /* Try to make this image bootable using the EFI Boot Manager, if available. */
1844 grub_install_register_efi (efidir_grub_dev,
1845 "\\System\\Library\\CoreServices",
1846 efi_distributor);
1847 }
1848
1849 grub_device_close (ins_dev);
1850 free (boot_efi);
1851 free (mach_kernel);
1852 break;
1853 }
1854 case GRUB_INSTALL_PLATFORM_ARM_EFI:
1855 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1856 case GRUB_INSTALL_PLATFORM_IA64_EFI:
1857 {
1858 char *dst = grub_util_path_concat (2, efidir, efi_file);
1859 grub_install_copy_file (imgfile, dst, 1);
1860 free (dst);
1861 }
1862 if (!removable && update_nvram)
1863 {
1864 char * efifile_path;
1865 char * part;
1866
1867 /* Try to make this image bootable using the EFI Boot Manager, if available. */
1868 if (!efi_distributor || efi_distributor[0] == '\0')
1869 grub_util_error ("%s", _("EFI bootloader id isn't specified."));
1870 efifile_path = xasprintf ("\\EFI\\%s\\%s",
1871 efi_distributor,
1872 efi_file);
1873 part = (efidir_grub_dev->disk->partition
1874 ? grub_partition_get_name (efidir_grub_dev->disk->partition)
1875 : 0);
1876 grub_util_info ("Registering with EFI: distributor = `%s',"
1877 " path = `%s', ESP at %s%s%s",
1878 efi_distributor, efifile_path,
1879 efidir_grub_dev->disk->name,
1880 (part ? ",": ""), (part ? : ""));
1881 grub_free (part);
1882 grub_install_register_efi (efidir_grub_dev,
1883 efifile_path, efi_distributor);
1884 }
1885 break;
1886
1887 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1888 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1889 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1890 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1891 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1892 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1893 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1894 case GRUB_INSTALL_PLATFORM_I386_QEMU:
1895 case GRUB_INSTALL_PLATFORM_I386_XEN:
1896 case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1897 grub_util_warn ("%s",
1898 _("WARNING: no platform-specific install was performed"));
1899 break;
1900 /* pacify warning. */
1901 case GRUB_INSTALL_PLATFORM_MAX:
1902 break;
1903 }
1904
1905 fprintf (stderr, "%s\n", _("Installation finished. No error reported."));
1906
1907 /* Free resources. */
1908 grub_gcry_fini_all ();
1909 grub_fini_all ();
1910
1911 return 0;
1912 }