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