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);
91 grub_util_warn (_("Unable to open stream from %s: %s"),
92 "efibootmgr", strerror (errno));
96 FILE *fp = fdopen (fd, "r");
99 grub_util_warn (_("Unable to open stream from %s: %s"),
100 "efibootmgr", strerror (errno));
110 ret = getline (&line, &len, fp);
113 if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0
114 || line[sizeof ("Boot") - 1] < '0'
115 || line[sizeof ("Boot") - 1] > '9')
117 if (!strcasestr (line, efi_distributor))
119 bootnum = line + sizeof ("Boot") - 1;
122 grub_util_exec ((const char * []){ "efibootmgr", "-q",
123 "-b", bootnum, "-B", NULL });
125 grub_util_exec ((const char * []){ "efibootmgr",
126 "-b", bootnum, "-B", NULL });
133 grub_install_register_efi (grub_device_t efidir_grub_dev,
134 const char *efifile_path,
135 const char *efi_distributor)
137 const char * efidir_disk;
139 efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
140 efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
142 if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
144 /* TRANSLATORS: This message is shown when required executable `%s'
146 grub_util_error (_("%s: not found"), "efibootmgr");
149 /* On Linux, we need the efivars kernel modules. */
151 grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
153 /* Delete old entries from the same distributor. */
154 grub_install_remove_efi_entries_by_distributor (efi_distributor);
156 char *efidir_part_str = xasprintf ("%d", efidir_part);
159 grub_util_exec ((const char * []){ "efibootmgr", "-q",
160 "-c", "-d", efidir_disk,
161 "-p", efidir_part_str, "-w",
162 "-L", efi_distributor, "-l",
163 efifile_path, NULL });
165 grub_util_exec ((const char * []){ "efibootmgr",
166 "-c", "-d", efidir_disk,
167 "-p", efidir_part_str, "-w",
168 "-L", efi_distributor, "-l",
169 efifile_path, NULL });
170 free (efidir_part_str);
174 grub_install_register_ieee1275 (int is_prep, const char *install_device,
175 int partno, const char *relpath)
179 if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL }))
181 /* TRANSLATORS: This message is shown when required executable `%s'
183 grub_util_error (_("%s: not found"), "ofpathname");
186 /* Get the Open Firmware device tree path translation. */
193 ofpath = get_ofpathname (install_device);
194 boot_device = xmalloc (strlen (ofpath) + 1
195 + sizeof ("XXXXXXXXXXXXXXXXXXXX")
196 + 1 + strlen (relpath) + 1);
197 ptr = grub_stpcpy (boot_device, ofpath);
199 grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d",
203 for (iptr = relpath; *iptr; iptr++, ptr++)
213 boot_device = get_ofpathname (install_device);
215 if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
216 boot_device, NULL }))
218 char *cmd = xasprintf ("setenv boot-device %s", boot_device);
219 grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"),
228 grub_install_sgi_setup (const char *install_device,
229 const char *imgfile, const char *destname)
231 grub_util_exec ((const char * []){ "dvhtool", "-d",
232 install_device, "--unix-to-vh",
233 imgfile, destname, NULL });
234 grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually."));