eeea31b220
When booted from stick, EFI would use GPT partition and our root device detection algortihm depends on GRUB's ability to see the same partitions. Hence include msdos and gpt partmap modules on EFI even when they're not needed to access root filesystem.
885 lines
28 KiB
C
885 lines
28 KiB
C
/*
|
|
* Make GRUB rescue image
|
|
*
|
|
* GRUB -- GRand Unified Bootloader
|
|
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
|
*
|
|
* GRUB is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GRUB is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <grub/util/install.h>
|
|
#include <grub/util/misc.h>
|
|
#include <grub/emu/exec.h>
|
|
#include <grub/emu/config.h>
|
|
#include <grub/emu/hostdisk.h>
|
|
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
|
#pragma GCC diagnostic ignored "-Wmissing-declarations"
|
|
#include <argp.h>
|
|
#pragma GCC diagnostic error "-Wmissing-prototypes"
|
|
#pragma GCC diagnostic error "-Wmissing-declarations"
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX];
|
|
static char *rom_directory;
|
|
static char *label_font;
|
|
static char *label_color;
|
|
static char *label_bgcolor;
|
|
static char *product_name;
|
|
static char *product_version;
|
|
static int xorriso_tail_argc;
|
|
static int xorriso_tail_arg_alloc;
|
|
static char **xorriso_tail_argv;
|
|
static char *output_image;
|
|
static char *xorriso;
|
|
static char *boot_grub;
|
|
static int xorriso_argc;
|
|
static int xorriso_arg_alloc;
|
|
static char **xorriso_argv;
|
|
static char *iso_uuid;
|
|
static char *iso9660_dir;
|
|
|
|
static void
|
|
xorriso_push (const char *val)
|
|
{
|
|
if (xorriso_arg_alloc <= xorriso_argc + 1)
|
|
{
|
|
xorriso_arg_alloc = 2 * (4 + xorriso_argc);
|
|
xorriso_argv = xrealloc (xorriso_argv,
|
|
sizeof (xorriso_argv[0])
|
|
* xorriso_arg_alloc);
|
|
}
|
|
xorriso_argv[xorriso_argc++] = xstrdup (val);
|
|
}
|
|
|
|
static void
|
|
xorriso_link (const char *from, const char *to)
|
|
{
|
|
char *tof = grub_util_path_concat (2, iso9660_dir, to);
|
|
char *val = xasprintf ("%s=%s", from, tof);
|
|
xorriso_push (val);
|
|
free (val);
|
|
free (tof);
|
|
}
|
|
|
|
enum
|
|
{
|
|
OPTION_OUTPUT = 'o',
|
|
OPTION_ROM_DIRECTORY = 0x301,
|
|
OPTION_XORRISO,
|
|
OPTION_GLUE_EFI,
|
|
OPTION_RENDER_LABEL,
|
|
OPTION_LABEL_FONT,
|
|
OPTION_LABEL_COLOR,
|
|
OPTION_LABEL_BGCOLOR,
|
|
OPTION_PRODUCT_NAME,
|
|
OPTION_PRODUCT_VERSION,
|
|
OPTION_SPARC_BOOT,
|
|
OPTION_ARCS_BOOT
|
|
};
|
|
|
|
static struct argp_option options[] = {
|
|
GRUB_INSTALL_OPTIONS,
|
|
{"output", 'o', N_("FILE"),
|
|
0, N_("save output in FILE [required]"), 2},
|
|
{"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"),
|
|
0, N_("save ROM images in DIR [optional]"), 2},
|
|
{"xorriso", OPTION_XORRISO, N_("FILE"),
|
|
/* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */
|
|
0, N_("use FILE as xorriso [optional]"), 2},
|
|
{"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2},
|
|
{"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2},
|
|
{"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
|
|
{"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
|
|
{"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
|
|
{"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2},
|
|
{"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
|
|
{"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2},
|
|
{"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2},
|
|
{0, 0, 0, 0, 0, 0}
|
|
};
|
|
|
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
|
|
|
static char *
|
|
help_filter (int key, const char *text, void *input __attribute__ ((unused)))
|
|
{
|
|
switch (key)
|
|
{
|
|
case ARGP_KEY_HELP_PRE_DOC:
|
|
/* TRANSLATORS: it generates one single image which is bootable through any method. */
|
|
return strdup (_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image."));
|
|
case ARGP_KEY_HELP_POST_DOC:
|
|
{
|
|
char *p1, *out;
|
|
|
|
p1 = xasprintf (_("Generates a bootable CD/USB/floppy image. Arguments other than options to this program"
|
|
" are passed to xorriso, and indicate source files, source directories, or any of the "
|
|
"mkisofs options listed by the output of `%s'."), "xorriso -as mkisofs -help");
|
|
out = xasprintf ("%s\n\n%s\n\n%s", p1,
|
|
_("Option -- switches to native xorriso command mode."),
|
|
_("Mail xorriso support requests to <bug-xorriso@gnu.org>."));
|
|
free (p1);
|
|
return out;
|
|
}
|
|
default:
|
|
return grub_install_help_filter (key, text, input);
|
|
}
|
|
}
|
|
|
|
#pragma GCC diagnostic error "-Wformat-nonliteral"
|
|
|
|
enum {
|
|
SYS_AREA_AUTO,
|
|
SYS_AREA_COMMON,
|
|
SYS_AREA_SPARC,
|
|
SYS_AREA_ARCS
|
|
} system_area = SYS_AREA_AUTO;
|
|
|
|
static error_t
|
|
argp_parser (int key, char *arg, struct argp_state *state)
|
|
{
|
|
if (grub_install_parse (key, arg))
|
|
return 0;
|
|
switch (key)
|
|
{
|
|
case OPTION_OUTPUT:
|
|
free (output_image);
|
|
output_image = xstrdup (arg);
|
|
return 0;
|
|
case OPTION_ROM_DIRECTORY:
|
|
free (rom_directory);
|
|
rom_directory = xstrdup (arg);
|
|
return 0;
|
|
|
|
/*
|
|
FIXME:
|
|
# Intentionally undocumented
|
|
--grub-mkimage-extra)
|
|
mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
|
|
--grub-mkimage-extra=*)
|
|
mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
|
|
*/
|
|
case OPTION_SPARC_BOOT:
|
|
system_area = SYS_AREA_SPARC;
|
|
return 0;
|
|
case OPTION_ARCS_BOOT:
|
|
system_area = SYS_AREA_ARCS;
|
|
return 0;
|
|
case OPTION_PRODUCT_NAME:
|
|
free (product_name);
|
|
product_name = xstrdup (arg);
|
|
return 0;
|
|
case OPTION_PRODUCT_VERSION:
|
|
free (product_version);
|
|
product_version = xstrdup (arg);
|
|
return 0;
|
|
/* Accept and ignore for compatibility. */
|
|
case OPTION_GLUE_EFI:
|
|
case OPTION_RENDER_LABEL:
|
|
return 0;
|
|
case OPTION_LABEL_FONT:
|
|
free (label_font);
|
|
label_font = xstrdup (arg);
|
|
return 0;
|
|
|
|
case OPTION_LABEL_COLOR:
|
|
free (label_color);
|
|
label_color = xstrdup (arg);
|
|
return 0;
|
|
|
|
case OPTION_LABEL_BGCOLOR:
|
|
free (label_bgcolor);
|
|
label_bgcolor = xstrdup (arg);
|
|
return 0;
|
|
|
|
case OPTION_XORRISO:
|
|
free (xorriso);
|
|
xorriso = xstrdup (arg);
|
|
return 0;
|
|
|
|
case ARGP_KEY_ARG:
|
|
if (xorriso_tail_arg_alloc <= xorriso_tail_argc)
|
|
{
|
|
xorriso_tail_arg_alloc = 2 * (4 + xorriso_tail_argc);
|
|
xorriso_tail_argv = xrealloc (xorriso_tail_argv,
|
|
sizeof (xorriso_tail_argv[0])
|
|
* xorriso_tail_arg_alloc);
|
|
}
|
|
xorriso_tail_argv[xorriso_tail_argc++] = xstrdup (arg);
|
|
return 0;
|
|
default:
|
|
return ARGP_ERR_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
struct argp argp = {
|
|
options, argp_parser, N_("[OPTION] SOURCE..."),
|
|
NULL, NULL, help_filter, NULL
|
|
};
|
|
|
|
static void
|
|
write_part (FILE *f, const char *srcdir)
|
|
{
|
|
FILE *in;
|
|
char *inname = grub_util_path_concat (2, srcdir, "partmap.lst");
|
|
char buf[260];
|
|
in = grub_util_fopen (inname, "rb");
|
|
if (!in)
|
|
return;
|
|
while (fgets (buf, 256, in))
|
|
{
|
|
char *ptr;
|
|
for (ptr = buf + strlen (buf) - 1;
|
|
ptr >= buf && (*ptr == '\n' || *ptr == '\r');
|
|
ptr--);
|
|
ptr[1] = '\0';
|
|
fprintf (f, "insmod %s\n", buf);
|
|
}
|
|
fclose (in);
|
|
}
|
|
|
|
static void
|
|
make_image_abs (enum grub_install_plat plat,
|
|
const char *mkimage_target,
|
|
const char *output)
|
|
{
|
|
char *load_cfg;
|
|
FILE *load_cfg_f;
|
|
|
|
if (!source_dirs[plat])
|
|
return;
|
|
|
|
grub_util_info (N_("enabling %s support ..."),
|
|
mkimage_target);
|
|
|
|
load_cfg = grub_util_make_temporary_file ();
|
|
|
|
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
|
fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid);
|
|
fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n");
|
|
|
|
write_part (load_cfg_f, source_dirs[plat]);
|
|
fclose (load_cfg_f);
|
|
|
|
grub_install_push_module ("search");
|
|
grub_install_push_module ("iso9660");
|
|
grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output,
|
|
0, load_cfg,
|
|
mkimage_target, 0);
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
grub_util_unlink (load_cfg);
|
|
}
|
|
|
|
static void
|
|
make_image (enum grub_install_plat plat,
|
|
const char *mkimage_target,
|
|
const char *output_sub)
|
|
{
|
|
char *out = grub_util_path_concat (2, boot_grub, output_sub);
|
|
make_image_abs (plat, mkimage_target, out);
|
|
free (out);
|
|
}
|
|
|
|
static void
|
|
make_image_fwdisk_abs (enum grub_install_plat plat,
|
|
const char *mkimage_target,
|
|
const char *output)
|
|
{
|
|
char *load_cfg;
|
|
FILE *load_cfg_f;
|
|
|
|
if (!source_dirs[plat])
|
|
return;
|
|
|
|
grub_util_info (N_("enabling %s support ..."),
|
|
mkimage_target);
|
|
|
|
load_cfg = grub_util_make_temporary_file ();
|
|
|
|
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
|
write_part (load_cfg_f, source_dirs[plat]);
|
|
fclose (load_cfg_f);
|
|
|
|
grub_install_push_module ("iso9660");
|
|
grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output,
|
|
0, load_cfg, mkimage_target, 0);
|
|
grub_install_pop_module ();
|
|
}
|
|
|
|
static int
|
|
check_xorriso (const char *val)
|
|
{
|
|
const char *argv[5];
|
|
int fd;
|
|
pid_t pid;
|
|
FILE *mdadm;
|
|
char *buf = NULL;
|
|
size_t len = 0;
|
|
int ret = 0;
|
|
|
|
argv[0] = xorriso;
|
|
argv[1] = "-as";
|
|
argv[2] = "mkisofs";
|
|
argv[3] = "-help";
|
|
argv[4] = NULL;
|
|
|
|
pid = grub_util_exec_pipe_stderr (argv, &fd);
|
|
|
|
if (!pid)
|
|
return 0;
|
|
|
|
/* Parent. Read mdadm's output. */
|
|
mdadm = fdopen (fd, "r");
|
|
if (! mdadm)
|
|
return 0;
|
|
|
|
while (getline (&buf, &len, mdadm) > 0)
|
|
{
|
|
if (grub_strstr (buf, val))
|
|
ret = 1;
|
|
}
|
|
|
|
close (fd);
|
|
waitpid (pid, NULL, 0);
|
|
free (buf);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
make_image_fwdisk (enum grub_install_plat plat,
|
|
const char *mkimage_target,
|
|
const char *output_sub)
|
|
{
|
|
char *out = grub_util_path_concat (2, boot_grub, output_sub);
|
|
make_image_fwdisk_abs (plat, mkimage_target, out);
|
|
free (out);
|
|
}
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
char *romdir;
|
|
char *sysarea_img = NULL;
|
|
const char *pkgdatadir;
|
|
|
|
grub_util_host_init (&argc, &argv);
|
|
grub_util_disable_fd_syncs ();
|
|
|
|
pkgdatadir = grub_util_get_pkgdatadir ();
|
|
|
|
product_name = xstrdup (PACKAGE_NAME);
|
|
product_version = xstrdup (PACKAGE_VERSION);
|
|
xorriso = xstrdup ("xorriso");
|
|
label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
|
|
|
|
argp_parse (&argp, argc, argv, 0, 0, 0);
|
|
|
|
if (!output_image)
|
|
grub_util_error ("%s", _("output file must be specified"));
|
|
|
|
grub_init_all ();
|
|
grub_hostfs_init ();
|
|
grub_host_init ();
|
|
|
|
xorriso_push (xorriso);
|
|
xorriso_push ("-as");
|
|
xorriso_push ("mkisofs");
|
|
xorriso_push ("-graft-points");
|
|
|
|
iso9660_dir = grub_util_make_temporary_dir ();
|
|
grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir);
|
|
boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub");
|
|
grub_install_mkdir_p (boot_grub);
|
|
romdir = grub_util_path_concat (2, boot_grub, "roms");
|
|
grub_util_mkdir (romdir);
|
|
|
|
if (!grub_install_source_directory)
|
|
{
|
|
const char *pkglibdir = grub_util_get_pkglibdir ();
|
|
enum grub_install_plat plat;
|
|
|
|
for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
|
|
{
|
|
char *platdir = grub_util_path_concat (2, pkglibdir,
|
|
grub_install_get_platform_name (plat));
|
|
|
|
if (!grub_util_is_directory (platdir))
|
|
{
|
|
free (platdir);
|
|
continue;
|
|
}
|
|
source_dirs[plat] = platdir;
|
|
grub_install_copy_files (platdir,
|
|
boot_grub, plat);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
enum grub_install_plat plat;
|
|
plat = grub_install_get_target (grub_install_source_directory);
|
|
grub_install_copy_files (grub_install_source_directory,
|
|
boot_grub, plat);
|
|
source_dirs[plat] = xstrdup (grub_install_source_directory);
|
|
}
|
|
if (system_area == SYS_AREA_AUTO || grub_install_source_directory)
|
|
{
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
|
|
system_area = SYS_AREA_COMMON;
|
|
else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275])
|
|
system_area = SYS_AREA_SPARC;
|
|
else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
|
|
system_area = SYS_AREA_ARCS;
|
|
}
|
|
|
|
/* obtain date-based UUID. */
|
|
{
|
|
time_t tim;
|
|
struct tm *tmm;
|
|
tim = time (NULL);
|
|
tmm = gmtime (&tim);
|
|
iso_uuid = xmalloc (55);
|
|
grub_snprintf (iso_uuid, 50,
|
|
"%04d-%02d-%02d-%02d-%02d-%02d-00",
|
|
tmm->tm_year + 1900,
|
|
tmm->tm_mon + 1,
|
|
tmm->tm_mday,
|
|
tmm->tm_hour,
|
|
tmm->tm_min,
|
|
tmm->tm_sec);
|
|
}
|
|
{
|
|
char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40);
|
|
char *optr;
|
|
const char *iptr;
|
|
optr = grub_stpcpy (uuid_out, "--modification-date=");
|
|
for (iptr = iso_uuid; *iptr; iptr++)
|
|
if (*iptr != '-')
|
|
*optr++ = *iptr;
|
|
*optr = '\0';
|
|
xorriso_push (uuid_out);
|
|
free (uuid_out);
|
|
}
|
|
|
|
/* build BIOS core.img. */
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC])
|
|
{
|
|
char *load_cfg;
|
|
FILE *load_cfg_f;
|
|
char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img");
|
|
load_cfg = grub_util_make_temporary_file ();
|
|
|
|
grub_util_info (N_("enabling %s support ..."), "BIOS");
|
|
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
|
write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]);
|
|
fclose (load_cfg_f);
|
|
|
|
grub_install_push_module ("biosdisk");
|
|
grub_install_push_module ("iso9660");
|
|
grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
|
|
"/boot/grub", output,
|
|
0, load_cfg,
|
|
"i386-pc-eltorito", 0);
|
|
|
|
xorriso_push ("-b");
|
|
xorriso_push ("boot/grub/i386-pc/eltorito.img");
|
|
xorriso_push ("-no-emul-boot");
|
|
xorriso_push ("-boot-load-size");
|
|
xorriso_push ("4");
|
|
xorriso_push ("-boot-info-table");
|
|
if (system_area == SYS_AREA_COMMON)
|
|
{
|
|
if (check_xorriso ("grub2-boot-info"))
|
|
{
|
|
char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
|
|
"boot_hybrid.img");
|
|
xorriso_push ("--grub2-boot-info");
|
|
xorriso_push ("--grub2-mbr");
|
|
xorriso_push (boot_hybrid);
|
|
}
|
|
else
|
|
{
|
|
FILE *sa, *bi;
|
|
size_t sz;
|
|
char buf[512];
|
|
char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
|
|
"boot.img");
|
|
grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later."));
|
|
sysarea_img = grub_util_make_temporary_file ();
|
|
sa = grub_util_fopen (sysarea_img, "wb");
|
|
if (!sa)
|
|
grub_util_error (_("cannot open `%s': %s"), sysarea_img,
|
|
strerror (errno));
|
|
bi = grub_util_fopen (bin, "rb");
|
|
if (!bi)
|
|
grub_util_error (_("cannot open `%s': %s"), bin,
|
|
strerror (errno));
|
|
if (fread (buf, 1, 512, bi) != 512)
|
|
grub_util_error (_("cannot read `%s': %s"), bin,
|
|
strerror (errno));
|
|
fclose (bi);
|
|
fwrite (buf, 1, 512, sa);
|
|
|
|
grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
|
|
"/boot/grub", sa, sysarea_img,
|
|
0, load_cfg,
|
|
"i386-pc", 0);
|
|
sz = ftello (sa);
|
|
fflush (sa);
|
|
grub_util_fd_sync (fileno (sa));
|
|
fclose (sa);
|
|
|
|
if (sz > 32768)
|
|
{
|
|
grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later."));
|
|
}
|
|
else
|
|
{
|
|
xorriso_push ("-G");
|
|
xorriso_push (sysarea_img);
|
|
}
|
|
}
|
|
}
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
}
|
|
|
|
/** build multiboot core.img */
|
|
grub_install_push_module ("pata");
|
|
grub_install_push_module ("ahci");
|
|
grub_install_push_module ("at_keyboard");
|
|
make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf");
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
|
|
make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf");
|
|
|
|
char *core_services = NULL;
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
|
|
{
|
|
char *mach_ker, *sv, *label, *label_text;
|
|
FILE *f;
|
|
core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices");
|
|
grub_install_mkdir_p (core_services);
|
|
|
|
mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel");
|
|
f = grub_util_fopen (mach_ker, "wb");
|
|
fclose (f);
|
|
free (mach_ker);
|
|
|
|
sv = grub_util_path_concat (2, core_services, "SystemVersion.plist");
|
|
f = grub_util_fopen (sv, "wb");
|
|
fprintf (f, "<plist version=\"1.0\">\n"
|
|
"<dict>\n"
|
|
" <key>ProductBuildVersion</key>\n"
|
|
" <string></string>\n"
|
|
" <key>ProductName</key>\n"
|
|
" <string>%s</string>\n"
|
|
" <key>ProductVersion</key>\n"
|
|
" <string>%s</string>\n"
|
|
"</dict>\n"
|
|
"</plist>\n", product_name, product_version);
|
|
fclose (f);
|
|
free (sv);
|
|
label = grub_util_path_concat (2, core_services, ".disk_label");
|
|
char *label_string = xasprintf ("%s %s", product_name, product_version);
|
|
grub_util_render_label (label_font, label_bgcolor ? : "white",
|
|
label_color ? : "black", label_string, label);
|
|
free (label);
|
|
label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
|
|
f = grub_util_fopen (label_text, "wb");
|
|
fprintf (f, "%s\n", label_string);
|
|
fclose (f);
|
|
free (label_string);
|
|
free (label_text);
|
|
if (system_area == SYS_AREA_COMMON)
|
|
{
|
|
xorriso_push ("-hfsplus");
|
|
xorriso_push ("-apm-block-size");
|
|
xorriso_push ("2048");
|
|
xorriso_push ("-hfsplus-file-creator-type");
|
|
xorriso_push ("chrp");
|
|
xorriso_push ("tbxj");
|
|
xorriso_push ("/System/Library/CoreServices/.disk_label");
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
|
|
{
|
|
xorriso_push ("-hfs-bless-by");
|
|
xorriso_push ("i");
|
|
xorriso_push ("/System/Library/CoreServices/boot.efi");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI])
|
|
{
|
|
char *efidir = grub_util_make_temporary_dir ();
|
|
char *efidir_efi = grub_util_path_concat (2, efidir, "efi");
|
|
char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot");
|
|
char *imgname, *img32, *img64, *img_mac = NULL;
|
|
char *efiimgfat;
|
|
grub_install_mkdir_p (efidir_efi_boot);
|
|
|
|
grub_install_push_module ("part_gpt");
|
|
grub_install_push_module ("part_msdos");
|
|
|
|
imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi");
|
|
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname);
|
|
free (imgname);
|
|
|
|
grub_install_push_module ("part_apple");
|
|
img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi");
|
|
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64);
|
|
grub_install_pop_module ();
|
|
|
|
grub_install_push_module ("part_apple");
|
|
img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi");
|
|
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32);
|
|
grub_install_pop_module ();
|
|
|
|
imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi");
|
|
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname);
|
|
free (imgname);
|
|
|
|
imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi");
|
|
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi",
|
|
imgname);
|
|
free (imgname);
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
|
|
{
|
|
imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi");
|
|
/* For old macs. Suggested by Peter Jones. */
|
|
grub_install_copy_file (img32, imgname, 1);
|
|
}
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
|| source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
|
|
img_mac = grub_util_path_concat (2, core_services, "boot.efi");
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
|
|
&& source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
|
|
grub_util_glue_efi (img32, img64, img_mac);
|
|
else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
|
|
grub_install_copy_file (img64, img_mac, 1);
|
|
else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
|
|
grub_install_copy_file (img32, img_mac, 1);
|
|
|
|
free (img_mac);
|
|
free (img32);
|
|
free (img64);
|
|
free (efidir_efi_boot);
|
|
|
|
efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img");
|
|
grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i",
|
|
efiimgfat, "::", NULL });
|
|
grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL });
|
|
xorriso_push ("--efi-boot");
|
|
xorriso_push ("efi.img");
|
|
xorriso_push ("-efi-boot-part");
|
|
xorriso_push ("--efi-boot-image");
|
|
|
|
grub_util_unlink_recursive (efidir);
|
|
free (efiimgfat);
|
|
free (efidir_efi);
|
|
free (efidir);
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
}
|
|
|
|
grub_install_push_module ("part_apple");
|
|
make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf");
|
|
grub_install_pop_module ();
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
|
|
{
|
|
char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
|
|
"grub.chrp");
|
|
char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
|
|
"bootinfo.txt");
|
|
char *bootx = grub_util_path_concat (2, core_services, "BootX");
|
|
char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp");
|
|
char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt");
|
|
grub_install_copy_file (grub_chrp, bootx, 1);
|
|
grub_install_mkdir_p (ppc_chrp);
|
|
grub_install_copy_file (bisrc, bitgt, 1);
|
|
xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf");
|
|
xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf");
|
|
/* FIXME: add PreP */
|
|
if (system_area == SYS_AREA_COMMON)
|
|
{
|
|
xorriso_push ("-hfsplus-file-creator-type");
|
|
xorriso_push ("chrp");
|
|
xorriso_push ("tbxi");
|
|
xorriso_push ("/System/Library/CoreServices/BootX");
|
|
xorriso_push ("-hfs-bless-by");
|
|
xorriso_push ("p");
|
|
xorriso_push ("/System/Library/CoreServices");
|
|
}
|
|
xorriso_push ("-sysid");
|
|
xorriso_push ("PPC");
|
|
}
|
|
|
|
make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
|
|
"sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img");
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]
|
|
&& system_area == SYS_AREA_SPARC)
|
|
{
|
|
char *cdboot;
|
|
FILE *in, *out;
|
|
char buf[512];
|
|
sysarea_img = grub_util_make_temporary_file ();
|
|
cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275],
|
|
"cdboot.img");
|
|
in = grub_util_fopen (cdboot, "rb");
|
|
if (!in)
|
|
grub_util_error (_("cannot open `%s': %s"), cdboot,
|
|
strerror (errno));
|
|
out = grub_util_fopen (sysarea_img, "wb");
|
|
if (!out)
|
|
grub_util_error (_("cannot open `%s': %s"), sysarea_img,
|
|
strerror (errno));
|
|
memset (buf, 0, 512);
|
|
fwrite (buf, 1, 512, out);
|
|
if (fread (buf, 1, 512, in) != 512)
|
|
grub_util_error (_("cannot read `%s': %s"), cdboot,
|
|
strerror (errno));
|
|
fwrite (buf, 1, 512, out);
|
|
fclose (in);
|
|
fclose (out);
|
|
xorriso_push ("-G");
|
|
xorriso_push (sysarea_img);
|
|
xorriso_push ("-B");
|
|
xorriso_push (",");
|
|
xorriso_push ("--grub2-sparc-core");
|
|
xorriso_push ("/boot/grub/sparc64-ieee1275/core.img");
|
|
}
|
|
|
|
make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img");
|
|
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
|
|
{
|
|
xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img");
|
|
xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img");
|
|
xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img");
|
|
}
|
|
if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS)
|
|
{
|
|
xorriso_push ("-mips-boot");
|
|
xorriso_push ("/boot/grub/mips-arc/sashARCS");
|
|
xorriso_push ("-mips-boot");
|
|
xorriso_push ("/boot/grub/mips-arc/sash");
|
|
xorriso_push ("-mips-boot");
|
|
xorriso_push ("/boot/grub/mips-arc/grub");
|
|
}
|
|
|
|
make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe");
|
|
|
|
grub_install_push_module ("pata");
|
|
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf");
|
|
|
|
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf");
|
|
|
|
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin");
|
|
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin");
|
|
|
|
make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf");
|
|
|
|
grub_install_push_module ("at_keyboard");
|
|
|
|
make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img");
|
|
|
|
grub_install_push_module ("ahci");
|
|
|
|
make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf");
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
grub_install_pop_module ();
|
|
|
|
if (rom_directory)
|
|
{
|
|
const struct
|
|
{
|
|
enum grub_install_plat plat;
|
|
const char *from, *to;
|
|
} roms[] =
|
|
{
|
|
{GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"},
|
|
{GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"},
|
|
{GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"},
|
|
{GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"},
|
|
{GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"},
|
|
{GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"},
|
|
{GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"},
|
|
};
|
|
grub_size_t i;
|
|
for (i = 0; i < ARRAY_SIZE (roms); i++)
|
|
{
|
|
char *from = grub_util_path_concat (2, boot_grub, roms[i].from);
|
|
char *to = grub_util_path_concat (2, rom_directory, roms[i].to);
|
|
grub_install_copy_file (from, to, 0);
|
|
}
|
|
}
|
|
|
|
xorriso_push ("--protective-msdos-label");
|
|
xorriso_push ("-o");
|
|
xorriso_push (output_image);
|
|
xorriso_push ("-r");
|
|
xorriso_push (iso9660_dir);
|
|
xorriso_push ("--sort-weight");
|
|
xorriso_push ("0");
|
|
xorriso_push ("/");
|
|
xorriso_push ("--sort-weight");
|
|
xorriso_push ("1");
|
|
xorriso_push ("/boot");
|
|
int i;
|
|
for (i = 0; i < xorriso_tail_argc; i++)
|
|
xorriso_push (xorriso_tail_argv[i]);
|
|
|
|
xorriso_argv[xorriso_argc] = NULL;
|
|
|
|
grub_util_exec ((const char *const *)xorriso_argv);
|
|
|
|
grub_util_unlink_recursive (iso9660_dir);
|
|
|
|
if (sysarea_img)
|
|
grub_util_unlink (sysarea_img);
|
|
|
|
free (core_services);
|
|
free (romdir);
|
|
return 0;
|
|
}
|