2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2013 Free Software Foundation, Inc.
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.
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.
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/>.
21 #include <grub/util/install.h>
22 #include <grub/emu/hostdisk.h>
23 #include <grub/util/misc.h>
24 #include <grub/misc.h>
25 #include <grub/i18n.h>
26 #include <grub/emu/exec.h>
27 #include <sys/types.h>
33 get_ofpathname (const char *dev)
35 size_t alloced = 4096;
36 char *ret = xmalloc (alloced);
41 pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd);
45 FILE *fp = fdopen (fd, "r");
52 if (alloced == offset)
55 ret = xrealloc (ret, alloced);
57 r = fread (ret + offset, 1, alloced - offset, fp);
61 if (offset > 0 && ret[offset - 1] == '\n')
63 if (offset > 0 && ret[offset - 1] == '\r')
65 if (alloced == offset)
68 ret = xrealloc (ret, alloced);
77 grub_util_error (_("couldn't find IEEE1275 device path for %s.\nYou will have to set `boot-device' variable manually"),
82 grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
85 pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
92 grub_util_warn (_("Unable to open stream from %s: %s"),
93 "efibootmgr", strerror (errno));
97 FILE *fp = fdopen (fd, "r");
100 grub_util_warn (_("Unable to open stream from %s: %s"),
101 "efibootmgr", strerror (errno));
111 ret = getline (&line, &len, fp);
114 if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0
115 || line[sizeof ("Boot") - 1] < '0'
116 || line[sizeof ("Boot") - 1] > '9')
118 if (!strcasestr (line, efi_distributor))
120 bootnum = line + sizeof ("Boot") - 1;
123 rc = grub_util_exec ((const char * []){ "efibootmgr", "-q",
124 "-b", bootnum, "-B", NULL });
126 rc = grub_util_exec ((const char * []){ "efibootmgr",
127 "-b", bootnum, "-B", NULL });
135 grub_install_register_efi (grub_device_t efidir_grub_dev,
136 const char *efifile_path,
137 const char *efi_distributor)
139 const char * efidir_disk;
142 efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
143 efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
145 if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
147 /* TRANSLATORS: This message is shown when required executable `%s'
149 grub_util_error (_("%s: not found"), "efibootmgr");
152 /* On Linux, we need the efivars kernel modules. */
154 grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
156 /* Delete old entries from the same distributor. */
157 ret = grub_install_remove_efi_entries_by_distributor (efi_distributor);
161 char *efidir_part_str = xasprintf ("%d", efidir_part);
164 ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
165 "-c", "-d", efidir_disk,
166 "-p", efidir_part_str, "-w",
167 "-L", efi_distributor, "-l",
168 efifile_path, NULL });
170 ret = grub_util_exec ((const char * []){ "efibootmgr",
171 "-c", "-d", efidir_disk,
172 "-p", efidir_part_str, "-w",
173 "-L", efi_distributor, "-l",
174 efifile_path, NULL });
175 free (efidir_part_str);
180 grub_install_register_ieee1275 (int is_prep, const char *install_device,
181 int partno, const char *relpath)
185 if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL }))
187 /* TRANSLATORS: This message is shown when required executable `%s'
189 grub_util_error (_("%s: not found"), "ofpathname");
192 /* Get the Open Firmware device tree path translation. */
199 ofpath = get_ofpathname (install_device);
200 boot_device = xmalloc (strlen (ofpath) + 1
201 + sizeof ("XXXXXXXXXXXXXXXXXXXX")
202 + 1 + strlen (relpath) + 1);
203 ptr = grub_stpcpy (boot_device, ofpath);
205 grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d",
209 for (iptr = relpath; *iptr; iptr++, ptr++)
219 boot_device = get_ofpathname (install_device);
221 if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
222 boot_device, NULL }))
224 char *cmd = xasprintf ("setenv boot-device %s", boot_device);
225 grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"),
234 grub_install_sgi_setup (const char *install_device,
235 const char *imgfile, const char *destname)
237 grub_util_exec ((const char * []){ "dvhtool", "-d",
238 install_device, "--unix-to-vh",
239 imgfile, destname, NULL });
240 grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually."));