Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir

the function of these files exceeds what can be sanely handled in shell
	in posix-comaptible way. Also writing it in C extends the functionality
	to non-UNIX-like OS and minimal environments.
This commit is contained in:
Vladimir Serbinenko 2013-11-16 20:21:16 +01:00
parent 9ef81064a3
commit cd46aa6cef
52 changed files with 5811 additions and 2101 deletions

View file

@ -1,3 +1,15 @@
2013-11-16 Andrey Borzenkov <arvidjaar@gmail.com>
* util/grub-install.c (device_map_check_duplicates): Fix incorrect
order of qsort arguments (number of elements vs. element size).
2013-11-16 Vladimir Serbinenko <phcoder@gmail.com>
Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir
the function of these files exceeds what can be sanely handled in shell
in posix-comaptible way. Also writing it in C extends the functionality
to non-UNIX-like OS and minimal environments.
2013-11-16 Vladimir Serbinenko <phcoder@gmail.com> 2013-11-16 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/arm/cache.S: Don't switch back to ARM mode when * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when

View file

@ -397,5 +397,27 @@ default_payload.elf: grub-mkstandalone grub-mkimage
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump setpci lsacpi chain' --fonts= --themes= --locales= -d grub-core/ pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump setpci lsacpi chain' --fonts= --themes= --locales= -d grub-core/
endif endif
windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
test -d $(windowsdir) && rm -rf $(windowsdir) || true
test -d $(windowsdir) || mkdir $(windowsdir)
$(MAKE) -C po $(AM_MAKEFLAGS) windowsdir
$(MAKE) -C grub-core $(AM_MAKEFLAGS) windowsdir
test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes
test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield
for x in $(PROGRAMS); do \
$(STRIP) $$x -o $(windowsdir)/$$x; \
done
for x in $(pkgdata_DATA); do \
cp -fp $$x $(windowsdir)/$$x; \
done
for x in $(starfield_DATA); do \
cp -fp $$x $(windowsdir)/themes/starfield/$$(basename $$x); \
done
windowszip=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows.zip
windowszip: windowsdir
test -f $(windowszip) && rm $(windowszip) || true
zip -r $(windowszip) $(windowsdir)
EXTRA_DIST += linguas.sh EXTRA_DIST += linguas.sh

View file

@ -171,6 +171,10 @@ program = {
common = util/resolve.c; common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c; common = grub-core/osdep/init.c;
common = grub-core/osdep/config.c;
extra_dist = grub-core/osdep/windows/config.c;
extra_dist = grub-core/osdep/unix/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c; common = grub-core/kern/arm/dl_helper.c;
@ -310,6 +314,7 @@ program = {
installdir = sbin; installdir = sbin;
mansection = 8; mansection = 8;
common = util/grub-probe.c; common = util/grub-probe.c;
common = util/probe.c;
common = grub-core/osdep/ofpath.c; common = grub-core/osdep/ofpath.c;
common = grub-core/kern/emu/argp_common.c; common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c; common = grub-core/osdep/init.c;
@ -479,38 +484,165 @@ script = {
installdir = grubconf; installdir = grubconf;
}; };
script = { program = {
mansection = 1; mansection = 1;
name = grub-mkrescue; name = grub-mkrescue;
common = util/grub-install_header;
common = util/grub-mkrescue.in; common = util/grub-mkrescue.c;
enable = noemu; common = util/render-label.c;
common = util/glue-efi.c;
common = util/mkimage.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
common = grub-core/lib/reed_solomon.c;
common = grub-core/osdep/random.c;
common = grub-core/osdep/ofpath.c;
common = grub-core/osdep/platform.c;
common = grub-core/osdep/platform_unix.c;
common = grub-core/osdep/compress.c;
extra_dist = grub-core/osdep/unix/compress.c;
extra_dist = grub-core/osdep/basic/compress.c;
common = util/editenv.c;
common = grub-core/osdep/blocklist.c;
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
ldadd = '$(LIBLZMA)';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_HAVE_EXEC;
}; };
script = { program = {
mansection = 1; mansection = 1;
name = grub-mkstandalone; name = grub-mkstandalone;
common = util/grub-install_header; common = util/grub-mkstandalone.c;
common = util/grub-mkstandalone.in;
common = util/render-label.c;
common = util/glue-efi.c;
common = util/mkimage.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
common = grub-core/lib/reed_solomon.c;
common = grub-core/osdep/random.c;
common = grub-core/osdep/ofpath.c;
common = grub-core/osdep/platform.c;
common = grub-core/osdep/platform_unix.c;
extra_dist = grub-core/osdep/linux/platform.c;
extra_dist = grub-core/osdep/basic/platform.c;
extra_dist = grub-core/osdep/basic/no_platform.c;
extra_dist = grub-core/osdep/unix/platform.c;
common = grub-core/osdep/compress.c;
common = util/editenv.c;
common = grub-core/osdep/blocklist.c;
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
ldadd = '$(LIBLZMA)';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
script = { program = {
mansection = 8; mansection = 8;
installdir = sbin; installdir = sbin;
name = grub-install; name = grub-install;
common = util/grub-install_header; common = util/grub-install.c;
common = util/grub-install.in; common = util/probe.c;
common = util/mkimage.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
common = grub-core/lib/reed_solomon.c;
common = grub-core/osdep/random.c;
common = grub-core/osdep/ofpath.c;
common = grub-core/osdep/platform.c;
common = grub-core/osdep/platform_unix.c;
common = grub-core/osdep/compress.c;
common = util/editenv.c;
common = grub-core/osdep/blocklist.c;
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
enable = noemu; enable = noemu;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
ldadd = '$(LIBLZMA)';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
script = { program = {
mansection = 1; mansection = 1;
installdir = bin; installdir = bin;
name = grub-mknetdir; name = grub-mknetdir;
common = util/grub-install_header; common = util/grub-mknetdir.c;
common = util/grub-mknetdir.in;
common = util/mkimage.c;
common = util/grub-install-common.c;
common = util/setup_bios.c;
common = util/setup_sparc.c;
common = grub-core/lib/reed_solomon.c;
common = grub-core/osdep/random.c;
common = grub-core/osdep/ofpath.c;
common = grub-core/osdep/platform.c;
common = grub-core/osdep/platform_unix.c;
common = grub-core/osdep/compress.c;
common = util/editenv.c;
common = grub-core/osdep/blocklist.c;
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
ldadd = '$(LIBLZMA)';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
script = { script = {

View file

@ -75,14 +75,10 @@ if test "x$TARGET_CFLAGS" = x; then
TARGET_CFLAGS="$TARGET_CFLAGS -Os" TARGET_CFLAGS="$TARGET_CFLAGS -Os"
fi fi
BUILD_CPPFLAGS="$BUILD_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
# Default HOST_CPPFLAGS # Default HOST_CPPFLAGS
HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include"
HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_LIBDIR=\\\"\$(pkglibdir)\\\""
HOST_CPPFLAGS="$HOST_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W"
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include"
@ -192,6 +188,12 @@ case "$host_os" in
cygwin | windows* | mingw32*) host_kernel=windows ;; cygwin | windows* | mingw32*) host_kernel=windows ;;
esac esac
case "$host_os" in
cygwin | windows* | mingw32*) have_exec=n ;;
aros*) have_exec=n ;;
*) have_exec=y;;
esac
case "$platform" in case "$platform" in
coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;; coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;;
multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;; multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
@ -1458,6 +1460,20 @@ AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes])
AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
AM_CONDITIONAL([COND_CYGWIN], [test x$target_os = xcygwin]) AM_CONDITIONAL([COND_CYGWIN], [test x$target_os = xcygwin])
AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x])
AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy])
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
datarootdir="$(eval echo "$datarootdir")"
grub_libdir="$(eval echo "$libdir")"
grub_localedir="$(eval echo "$localedir")"
grub_datadir="$(eval echo "$datadir")"
grub_sysconfdir="$(eval echo "$sysconfdir")"
AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir])
AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir])
AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir])
AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir])
# Output files. # Output files.
cpudir="${target_cpu}" cpudir="${target_cpu}"

View file

@ -428,3 +428,10 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
platform_DATA += efiemu32.o efiemu64.o platform_DATA += efiemu32.o efiemu64.o
CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
endif endif
windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform)
for x in $(platform_DATA); do \
cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \
done

View file

@ -609,3 +609,78 @@ grub_util_biosdisk_get_osdev (grub_disk_t disk)
return map[disk->id].device; return map[disk->id].device;
} }
static char *
grub_util_path_concat_real (size_t n, int ext, va_list ap)
{
size_t totlen = 0;
char **l = xmalloc ((n + ext) * sizeof (l[0]));
char *r, *p, *pi;
size_t i;
int first = 1;
for (i = 0; i < n + ext; i++)
{
l[i] = va_arg (ap, char *);
if (l[i])
totlen += strlen (l[i]) + 1;
}
r = xmalloc (totlen + 10);
p = r;
for (i = 0; i < n; i++)
{
pi = l[i];
if (!pi)
continue;
while (*pi == '/')
pi++;
if ((p != r || (pi != l[i] && first)) && (p == r || *(p - 1) != '/'))
*p++ = '/';
first = 0;
p = grub_stpcpy (p, pi);
while (p != r && p != r + 1 && *(p - 1) == '/')
p--;
}
if (ext && l[i])
p = grub_stpcpy (p, l[i]);
*p = '\0';
free (l);
return r;
}
char *
grub_util_path_concat (size_t n, ...)
{
va_list ap;
char *r;
va_start (ap, n);
r = grub_util_path_concat_real (n, 0, ap);
va_end (ap);
return r;
}
char *
grub_util_path_concat_ext (size_t n, ...)
{
va_list ap;
char *r;
va_start (ap, n);
r = grub_util_path_concat_real (n, 1, ap);
va_end (ap);
return r;
}

View file

@ -0,0 +1,94 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 <config-util.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/exec.h>
#include <grub/emu/config.h>
#include <grub/util/install.h>
#include <grub/util/misc.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
const char *
grub_util_get_config_filename (void)
{
static char *value = NULL;
if (!value)
value = grub_util_path_concat (3, GRUB_SYSCONFDIR,
"default", "grub");
return value;
}
const char *
grub_util_get_pkgdatadir (void)
{
const char *ret = getenv ("pkgdatadir");
if (ret)
return ret;
return GRUB_DATADIR "/" PACKAGE;
}
const char *
grub_util_get_pkglibdir (void)
{
return GRUB_LIBDIR "/" PACKAGE;
}
const char *
grub_util_get_localedir (void)
{
return LOCALEDIR;
}
void
grub_util_load_config (struct grub_util_config *cfg)
{
const char *cfgfile;
FILE *f = NULL;
const char *v;
memset (cfg, 0, sizeof (*cfg));
v = getenv ("GRUB_ENABLE_CRYPTODISK");
if (v && v[0] == 'y' && v[1] == '\0')
cfg->is_cryptodisk_enabled = 1;
v = getenv ("GRUB_DISTRIBUTOR");
if (v)
cfg->grub_distributor = xstrdup (v);
cfgfile = grub_util_get_config_filename ();
if (!grub_util_is_regular (cfgfile))
return;
f = grub_util_fopen (cfgfile, "r");
if (f)
{
grub_util_parse_config (f, cfg, 0);
fclose (f);
}
else
grub_util_warn (_("cannot open config file `%s': %s"),
cfgfile, strerror (errno));
}

View file

@ -41,6 +41,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <time.h>
#include <string.h> #include <string.h>
#include <dos/dos.h> #include <dos/dos.h>
@ -516,6 +517,17 @@ grub_util_is_directory (const char *path)
return S_ISDIR (st.st_mode); return S_ISDIR (st.st_mode);
} }
int
grub_util_is_regular (const char *path)
{
struct stat st;
if (stat (path, &st) == -1)
return 0;
return S_ISREG (st.st_mode);
}
int int
grub_util_is_special_file (const char *path) grub_util_is_special_file (const char *path)
{ {
@ -525,3 +537,53 @@ grub_util_is_special_file (const char *path)
return 1; return 1;
return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode));
} }
static char *
get_temp_name (void)
{
static int ctr = 0;
char *t;
struct stat st;
while (1)
{
t = xasprintf ("T:grub.%d.%d.%d.%d", (int) getpid (), (int) getppid (),
ctr++, time (0));
if (stat (t, &st) == -1)
return t;
free (t);
}
}
char *
grub_util_make_temporary_file (void)
{
char *ret = get_temp_name ();
FILE *f;
f = grub_util_fopen (ret, "wb");
if (f)
fclose (f);
return ret;
}
char *
grub_util_make_temporary_dir (void)
{
char *ret = get_temp_name ();
grub_util_mkdir (ret);
return ret;
}
grub_uint32_t
grub_util_get_mtime (const char *path)
{
struct stat st;
if (stat (path, &st) == -1)
return 0;
return st.st_mtime;
}

View file

@ -0,0 +1,21 @@
#include <config.h>
#include <grub/util/install.h>
#include <grub/util/misc.h>
int
grub_install_compress_gzip (const char *src, const char *dest)
{
grub_util_error ("no compression is available for your platform");
}
int
grub_install_compress_xz (const char *src, const char *dest)
{
grub_util_error ("no compression is available for your platform");
}
int
grub_install_compress_lzop (const char *src, const char *dest)
{
grub_util_error ("no compression is available for your platform");
}

View file

@ -20,6 +20,7 @@
#include <config-util.h> #include <config-util.h>
#include <grub/util/misc.h> #include <grub/util/misc.h>
#include <grub/i18n.h>
#include "progname.h" #include "progname.h"
@ -29,7 +30,9 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
{ {
set_program_name ((*argv)[0]); set_program_name ((*argv)[0]);
#ifdef GRUB_UTIL #if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
grub_util_init_nls (); setlocale (LC_ALL, "");
#endif bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
} }

View file

@ -0,0 +1,46 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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 <grub/types.h>
#include <grub/emu/misc.h>
#include <grub/util/install.h>
#include <grub/util/misc.h>
#include "platform.c"
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
int partno, const char *relpath)
{
grub_util_error ("%s", "no IEEE1275 routines are available for your platform");
}
void
grub_install_register_efi (const char *efidir_disk, int efidir_part,
const char *efifile_path,
const char *efi_distributor)
{
grub_util_error ("%s", "no EFI routines are available for your platform");
}
void
grub_install_sgi_setup (const char *install_device,
const char *imgfile, const char *destname)
{
grub_util_error ("%s", "no SGI routines are available for your platform");
}

View file

@ -0,0 +1,26 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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 <grub/util/install.h>
const char *
grub_install_get_default_x86_platform (void)
{
return "i386-pc";
}

View file

@ -0,0 +1,5 @@
#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__)
#include "unix/compress.c"
#else
#include "basic/compress.c"
#endif

7
grub-core/osdep/config.c Normal file
View file

@ -0,0 +1,7 @@
#if defined (__MINGW32__) && !defined (__CYGWIN__)
#include "windows/config.c"
#elif defined (__AROS__)
#include "aros/config.c"
#else
#include "unix/config.c"
#endif

View file

@ -0,0 +1,85 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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/emu/exec.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <sys/utsname.h>
static int
is_not_empty_directory (const char *dir)
{
DIR *d;
struct dirent *de;
d = opendir (dir);
if (!d)
return 0;
while ((de = readdir (d)))
{
if (strcmp (de->d_name, ".") == 0
|| strcmp (de->d_name, "..") == 0)
continue;
closedir (d);
return 1;
}
closedir (d);
return 0;
}
static int
is_64_kernel (void)
{
struct utsname un;
if (uname (&un) < 0)
return 0;
return strcmp (un.machine, "x86_64") == 0;
}
const char *
grub_install_get_default_x86_platform (void)
{
/*
On Linux, we need the efivars kernel modules.
If no EFI is available this module just does nothing
besides a small hello and if we detect efi we'll load it
anyway later. So it should be safe to
try to load it here.
*/
grub_util_exec ((const char * []){ "modprobe", "-q",
"efivars", NULL });
if (is_not_empty_directory ("/sys/firmware/efi"))
{
if (is_64_kernel ())
return "x86_64-efi";
else
return "i386-efi";
}
else if (is_not_empty_directory ("/proc/device-tree"))
return "i386-ieee1275";
else
return "i386-pc";
}

View file

@ -0,0 +1,7 @@
#ifdef __linux__
#include "linux/platform.c"
#elif defined (__MINGW32__) || defined (__CYGWIN__) || defined (__AROS__)
#include "basic/no_platform.c"
#else
#include "basic/platform.c"
#endif

View file

@ -0,0 +1,3 @@
#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__)
#include "unix/platform.c"
#endif

View file

@ -0,0 +1,41 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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 <grub/emu/exec.h>
#include <grub/util/install.h>
int
grub_install_compress_gzip (const char *src, const char *dest)
{
return grub_util_exec_redirect ((const char * []) { "gzip", "--best",
"--stdout", NULL }, src, dest);
}
int
grub_install_compress_xz (const char *src, const char *dest)
{
return grub_util_exec_redirect ((const char * []) { "xz",
"--lzma2=dict=128KiB", "--check=none", "--stdout", NULL }, src, dest);
}
int
grub_install_compress_lzop (const char *src, const char *dest)
{
return grub_util_exec_redirect ((const char * []) { "lzop", "-9", "-c",
NULL }, src, dest);
}

View file

@ -0,0 +1,139 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 <config-util.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/exec.h>
#include <grub/emu/config.h>
#include <grub/util/install.h>
#include <grub/util/misc.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
const char *
grub_util_get_config_filename (void)
{
static char *value = NULL;
if (!value)
value = grub_util_path_concat (3, GRUB_SYSCONFDIR,
"default", "grub");
return value;
}
const char *
grub_util_get_pkgdatadir (void)
{
const char *ret = getenv ("pkgdatadir");
if (ret)
return ret;
return GRUB_DATADIR "/" PACKAGE;
}
const char *
grub_util_get_pkglibdir (void)
{
return GRUB_LIBDIR "/" PACKAGE;
}
const char *
grub_util_get_localedir (void)
{
return LOCALEDIR;
}
void
grub_util_load_config (struct grub_util_config *cfg)
{
pid_t pid;
const char *argv[4];
char *script, *ptr;
const char *cfgfile, *iptr;
FILE *f = NULL;
int fd;
const char *v;
memset (cfg, 0, sizeof (*cfg));
v = getenv ("GRUB_ENABLE_CRYPTODISK");
if (v && v[0] == 'y' && v[1] == '\0')
cfg->is_cryptodisk_enabled = 1;
v = getenv ("GRUB_DISTRIBUTOR");
if (v)
cfg->grub_distributor = xstrdup (v);
cfgfile = grub_util_get_config_filename ();
if (!grub_util_is_regular (cfgfile))
return;
argv[0] = "sh";
argv[1] = "-c";
script = xmalloc (4 * strlen (cfgfile) + 300);
ptr = script;
memcpy (ptr, ". '", 3);
ptr += 3;
for (iptr = cfgfile; *iptr; iptr++)
{
if (*iptr == '\\')
{
memcpy (ptr, "'\\''", 4);
ptr += 4;
continue;
}
*ptr++ = *iptr;
}
strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\", "
"\"$GRUB_ENABLE_CRYPTODISK\", \"$GRUB_DISTRIBUTOR\"");
argv[2] = script;
argv[3] = '\0';
pid = grub_util_exec_pipe (argv, &fd);
if (pid)
f = fdopen (fd, "r");
if (f)
{
grub_util_parse_config (f, cfg, 1);
fclose (f);
}
if (pid)
{
close (fd);
waitpid (pid, NULL, 0);
}
if (f)
return;
f = grub_util_fopen (cfgfile, "r");
if (f)
{
grub_util_parse_config (f, cfg, 0);
fclose (f);
}
else
grub_util_warn (_("cannot open config file `%s': %s"),
cfgfile, strerror (errno));
}

View file

@ -38,6 +38,23 @@ grub_util_exec (const char *const *argv)
{ {
pid_t pid; pid_t pid;
int status = -1; int status = -1;
char *str, *pstr;
const char *const *ptr;
grub_size_t strl = 0;
for (ptr = argv; *ptr; ptr++)
strl += grub_strlen (*ptr) + 1;
pstr = str = xmalloc (strl);
for (ptr = argv; *ptr; ptr++)
{
pstr = grub_stpcpy (pstr, *ptr);
*pstr++ = ' ';
}
if (pstr > str)
pstr--;
*pstr = '\0';
grub_util_info ("executing %s", str);
grub_free (str);
pid = fork (); pid = fork ();
if (pid < 0) if (pid < 0)
@ -71,6 +88,29 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
{ {
pid_t mdadm_pid; pid_t mdadm_pid;
int status = -1; int status = -1;
char *str, *pstr;
const char *const *ptr;
grub_size_t strl = 0;
for (ptr = argv; *ptr; ptr++)
strl += grub_strlen (*ptr) + 1;
strl += grub_strlen (stdin_file) + 2;
strl += grub_strlen (stdout_file) + 2;
pstr = str = xmalloc (strl);
for (ptr = argv; *ptr; ptr++)
{
pstr = grub_stpcpy (pstr, *ptr);
*pstr++ = ' ';
}
*pstr++ = '<';
pstr = grub_stpcpy (pstr, stdin_file);
*pstr++ = ' ';
*pstr++ = '>';
pstr = grub_stpcpy (pstr, stdout_file);
*pstr = '\0';
grub_util_info ("executing %s", str);
grub_free (str);
mdadm_pid = fork (); mdadm_pid = fork ();
if (mdadm_pid < 0) if (mdadm_pid < 0)
@ -87,6 +127,8 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
#endif #endif
in = open (stdin_file, O_RDONLY); in = open (stdin_file, O_RDONLY);
if (in < 0)
exit (127);
dup2 (in, STDIN_FILENO); dup2 (in, STDIN_FILENO);
close (in); close (in);
@ -94,6 +136,9 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
dup2 (out, STDOUT_FILENO); dup2 (out, STDOUT_FILENO);
close (out); close (out);
if (out < 0)
exit (127);
/* Ensure child is not localised. */ /* Ensure child is not localised. */
setenv ("LC_ALL", "C", 1); setenv ("LC_ALL", "C", 1);

View file

@ -246,6 +246,17 @@ grub_util_is_regular (const char *path)
return S_ISREG (st.st_mode); return S_ISREG (st.st_mode);
} }
grub_uint32_t
grub_util_get_mtime (const char *path)
{
struct stat st;
if (stat (path, &st) == -1)
return 0;
return st.st_mtime;
}
int int
grub_util_is_special_file (const char *path) grub_util_is_special_file (const char *path)
{ {
@ -256,4 +267,39 @@ grub_util_is_special_file (const char *path)
return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode));
} }
char *
grub_util_make_temporary_file (void)
{
const char *t = getenv ("TMPDIR");
size_t tl;
char *tmp;
if (!t)
t = "/tmp";
tl = strlen (t);
tmp = xmalloc (tl + sizeof ("/grub.XXXXXX"));
memcpy (tmp, t, tl);
memcpy (tmp + tl, "/grub.XXXXXX",
sizeof ("/grub.XXXXXX"));
mkstemp (tmp);
return tmp;
}
char *
grub_util_make_temporary_dir (void)
{
const char *t = getenv ("TMPDIR");
size_t tl;
char *tmp;
if (!t)
t = "/tmp";
tl = strlen (t);
tmp = xmalloc (tl + sizeof ("/grub.XXXXXX"));
memcpy (tmp, t, tl);
memcpy (tmp + tl, "/grub.XXXXXX",
sizeof ("/grub.XXXXXX"));
mkdtemp (tmp);
return tmp;
}
#endif #endif

View file

@ -0,0 +1,213 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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/misc.h>
#include <grub/i18n.h>
#include <grub/emu/exec.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
static char *
get_ofpathname (const char *dev)
{
char *ret = xmalloc (2 * PATH_MAX);
char *end = ret + 2 * PATH_MAX - 1;
int fd;
pid_t pid;
char *ptr = ret;
pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd);
if (!pid)
goto fail;
FILE *fp = fdopen (fd, "r");
if (!fp)
goto fail;
while (!feof (fp) && ptr < end)
{
size_t r;
r = fread (ptr, 1, end - ptr, fp);
ptr += r;
}
fclose (fp);
return ret;
fail:
grub_util_error (_("couldn't find IEEE1275 device tree path for %s.\nYou will have to set `boot-device' variable manually"),
dev);
}
static void
grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
{
int fd;
pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
char *line = NULL;
size_t len = 0;
if (!pid)
{
grub_util_warn (_("Unable to open stream from %s: %s"),
"efibootmgr", strerror (errno));
return;
}
FILE *fp = fdopen (fd, "r");
if (!fp)
{
grub_util_warn (_("Unable to open stream from %s: %s"),
"efibootmgr", strerror (errno));
return;
}
line = xmalloc (80);
len = 80;
while (1)
{
int ret;
char *bootnum;
ret = getline (&line, &len, fp);
if (ret == -1)
break;
if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0
|| line[sizeof ("Boot") - 1] < '0'
|| line[sizeof ("Boot") - 1] > '9')
continue;
if (!strcasestr (line, efi_distributor))
continue;
bootnum = line + sizeof ("Boot") - 1;
bootnum[4] = '\0';
if (!verbosity)
grub_util_exec ((const char * []){ "efibootmgr", "-q",
"-b", bootnum, "-B", NULL });
else
grub_util_exec ((const char * []){ "efibootmgr",
"-b", bootnum, "-B", NULL });
}
free (line);
}
void
grub_install_register_efi (const char *efidir_disk, int efidir_part,
const char *efifile_path,
const char *efi_distributor)
{
if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
{
/* TRANSLATORS: This message is shown when required executable `%s'
isn't found. */
grub_util_error (_("%s: not found"), "efibootmgr");
}
/* On Linux, we need the efivars kernel modules. */
#ifdef __linux__
grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
#endif
/* Delete old entries from the same distributor. */
grub_install_remove_efi_entries_by_distributor (efi_distributor);
char *efidir_part_str = xasprintf ("%d", efidir_part);
if (!verbosity)
grub_util_exec ((const char * []){ "efibootmgr", "-q",
"-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w",
"-L", efi_distributor, "-l",
efifile_path, NULL });
else
grub_util_exec ((const char * []){ "efibootmgr",
"-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w",
"-L", efi_distributor, "-l",
efifile_path, NULL });
free (efidir_part_str);
}
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
int partno, const char *relpath)
{
char *boot_device;
if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL }))
{
/* TRANSLATORS: This message is shown when required executable `%s'
isn't found. */
grub_util_error (_("%s: not found"), "ofpathname");
}
/* Get the Open Firmware device tree path translation. */
if (!is_prep)
{
char *ptr;
char *ofpath;
const char *iptr;
ofpath = get_ofpathname (install_device);
boot_device = xmalloc (strlen (ofpath) + 1
+ sizeof ("XXXXXXXXXXXXXXXXXXXX")
+ 1 + strlen (relpath) + 1);
ptr = grub_stpcpy (boot_device, ofpath);
*ptr++ = ':';
grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d",
partno);
ptr += strlen (ptr);
*ptr++ = ',';
for (iptr = relpath; *iptr; iptr++, ptr++)
{
if (*iptr == '/')
*ptr = '\\';
else
*ptr = *iptr;
}
*ptr = '\0';
}
else
boot_device = get_ofpathname (install_device);
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
boot_device, NULL }))
{
char *cmd = xasprintf ("setenv boot-device %s", boot_device);
grub_util_error ("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n",
cmd);
free (cmd);
}
free (boot_device);
}
void
grub_install_sgi_setup (const char *install_device,
const char *imgfile, const char *destname)
{
grub_util_exec ((const char * []){ "dvhtool", "-d",
install_device, "--unix-to-vh",
imgfile, destname, NULL });
grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually."));
}

View file

@ -0,0 +1,57 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 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 <config-util.h>
#include <grub/emu/hostfile.h>
#include <grub/emu/config.h>
#include <grub/util/install.h>
#include <grub/util/misc.h>
void
grub_util_load_config (struct grub_util_config *cfg)
{
const char *cfgfile;
FILE *f = NULL;
const char *v;
cfgfile = grub_util_get_config_filename ();
if (!grub_util_is_regular (cfgfile))
return;
memset (cfg, 0, sizeof (*cfg));
v = getenv ("GRUB_ENABLE_CRYPTODISK");
if (v && v[0] == 'y' && v[1] == '\0')
cfg->is_cryptodisk_enabled = 1;
v = getenv ("GRUB_DISTRIBUTOR");
if (v)
cfg->grub_distributor = xstrdup (v);
f = grub_util_fopen (cfgfile, "r");
if (f)
{
grub_util_parse_config (f, cfg, 0);
fclose (f);
}
else
grub_util_warn (_("cannot open config file `%s': %s"),
cfgfile, strerror (errno));
}

View file

@ -46,6 +46,7 @@
#include <windows.h> #include <windows.h>
#include <winioctl.h> #include <winioctl.h>
#include <wincrypt.h>
#if SIZEOF_TCHAR == 1 #if SIZEOF_TCHAR == 1
@ -411,6 +412,89 @@ grub_util_unlink (const char *name)
return ret; return ret;
} }
int
grub_util_rmdir (const char *name)
{
LPTSTR name_windows;
int ret;
name_windows = grub_util_get_windows_path (name);
ret = !RemoveDirectory (name_windows);
free (name_windows);
return ret;
}
static char *
get_temp_name (void)
{
TCHAR rt[1024];
TCHAR *ptr;
HCRYPTPROV hCryptProv;
grub_uint8_t rnd[5];
const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
int i;
GetTempPath (ARRAY_SIZE (rt) - 100, rt);
if (!CryptAcquireContext (&hCryptProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)
|| !CryptGenRandom (hCryptProv, 5, rnd))
grub_util_error ("%s", _("couldn't retrieve random data"));
CryptReleaseContext (hCryptProv, 0);
for (ptr = rt; *ptr; ptr++);
memcpy (ptr, TEXT("\\GRUB."), sizeof (TEXT("\\GRUB.")));
ptr += sizeof ("\\GRUB.") - 1;
for (i = 0; i < 8; i++)
{
grub_size_t b = i * 5;
grub_uint8_t r;
grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
grub_size_t f2;
if (f1 > 5)
f1 = 5;
f2 = 5 - f1;
r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
if (f2)
r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
if (r < 10)
*ptr++ = '0' + r;
else
*ptr++ = 'a' + (r - 10);
}
*ptr = '\0';
return grub_util_tchar_to_utf8 (rt);
}
char *
grub_util_make_temporary_file (void)
{
char *ret = get_temp_name ();
FILE *f;
f = grub_util_fopen (ret, "wb");
if (f)
fclose (f);
return ret;
}
char *
grub_util_make_temporary_dir (void)
{
char *ret = get_temp_name ();
grub_util_mkdir (ret);
return ret;
}
int int
grub_util_is_directory (const char *name) grub_util_is_directory (const char *name)
{ {
@ -444,6 +528,33 @@ grub_util_is_regular (const char *name)
&& !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr; && !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr;
} }
grub_uint32_t
grub_util_get_mtime (const char *path)
{
LPTSTR name_windows;
BOOL b;
WIN32_FILE_ATTRIBUTE_DATA attr;
ULARGE_INTEGER us_ul;
name_windows = grub_util_get_windows_path (path);
if (!name_windows)
return 0;
b = GetFileAttributesEx (name_windows, GetFileExInfoStandard, &attr);
grub_free (name_windows);
if (!b)
return 0;
us_ul.LowPart = attr.ftLastWriteTime.dwLowDateTime;
us_ul.HighPart = attr.ftLastWriteTime.dwHighDateTime;
return (us_ul.QuadPart / 10000000)
- 86400ULL * 365 * (1970 - 1601)
- 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
}
#ifdef __MINGW32__ #ifdef __MINGW32__
FILE * FILE *

View file

@ -21,6 +21,7 @@
#include <grub/util/misc.h> #include <grub/util/misc.h>
#include <grub/osdep/hostfile.h> #include <grub/osdep/hostfile.h>
#include <grub/util/windows.h> #include <grub/util/windows.h>
#include <grub/emu/config.h>
#include <wincon.h> #include <wincon.h>
#include <windows.h> #include <windows.h>
@ -111,10 +112,42 @@ set_console_unicode_font (void)
} }
} }
static char *grub_util_base_directory;
static char *locale_dir;
const char *
grub_util_get_config_filename (void)
{
static char *value = NULL;
if (!value)
value = grub_util_path_concat (2, grub_util_base_directory, "grub.cfg");
return value;
}
const char *
grub_util_get_pkgdatadir (void)
{
return grub_util_base_directory;
}
const char *
grub_util_get_localedir (void)
{
return locale_dir;
}
const char *
grub_util_get_pkglibdir (void)
{
return grub_util_base_directory;
}
void void
grub_util_host_init (int *argc __attribute__ ((unused)), grub_util_host_init (int *argc __attribute__ ((unused)),
char ***argv) char ***argv)
{ {
char *ptr;
SetConsoleOutputCP (CP_UTF8); SetConsoleOutputCP (CP_UTF8);
SetConsoleCP (CP_UTF8); SetConsoleCP (CP_UTF8);
@ -137,9 +170,21 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
#error "Unsupported TCHAR size" #error "Unsupported TCHAR size"
#endif #endif
grub_util_base_directory = canonicalize_file_name ((*argv)[0]);
if (!grub_util_base_directory)
grub_util_base_directory = xstrdup ((*argv)[0]);
for (ptr = grub_util_base_directory + strlen (grub_util_base_directory) - 1;
ptr >= grub_util_base_directory && *ptr != '/' && *ptr != '\\'; ptr--);
if (ptr >= grub_util_base_directory)
*ptr = '\0';
locale_dir = grub_util_path_concat (2, grub_util_base_directory, "locale");
set_program_name ((*argv)[0]); set_program_name ((*argv)[0]);
#ifdef GRUB_UTIL #if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
grub_util_init_nls (); setlocale (LC_ALL, "");
#endif bindtextdomain (PACKAGE, locale_dir);
textdomain (PACKAGE);
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
} }

48
include/grub/emu/config.h Normal file
View file

@ -0,0 +1,48 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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/>.
*/
#ifndef GRUB_CONFIG_EMU_HEADER
#define GRUB_CONFIG_EMU_HEADER 1
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/emu/hostfile.h>
#include <stdio.h>
const char *
grub_util_get_config_filename (void);
const char *
grub_util_get_pkgdatadir (void);
const char *
grub_util_get_pkglibdir (void);
const char *
grub_util_get_localedir (void);
struct grub_util_config
{
int is_cryptodisk_enabled;
char *grub_distributor;
};
void
grub_util_load_config (struct grub_util_config *cfg);
void
grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple);
#endif

View file

@ -20,8 +20,10 @@
#define GRUB_UTIL_GETROOT_HEADER 1 #define GRUB_UTIL_GETROOT_HEADER 1
#include <grub/types.h> #include <grub/types.h>
#include <grub/device.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h>
enum grub_dev_abstraction_types { enum grub_dev_abstraction_types {
GRUB_DEV_ABSTRACTION_NONE, GRUB_DEV_ABSTRACTION_NONE,
@ -89,4 +91,14 @@ grub_util_get_grub_dev_os (const char *os_dev);
grub_disk_addr_t grub_disk_addr_t
grub_util_find_partition_start_os (const char *dev); grub_util_find_partition_start_os (const char *dev);
char *
grub_util_guess_bios_drive (const char *orig_path);
char *
grub_util_guess_efi_drive (const char *orig_path);
char *
grub_util_guess_baremetal_drive (const char *orig_path);
void
grub_util_fprint_full_disk_name (FILE *f,
const char *drive, grub_device_t dev);
#endif /* ! GRUB_UTIL_GETROOT_HEADER */ #endif /* ! GRUB_UTIL_GETROOT_HEADER */

View file

@ -31,6 +31,11 @@ grub_util_is_special_file (const char *path);
int int
grub_util_is_regular (const char *path); grub_util_is_regular (const char *path);
char *
grub_util_path_concat (size_t n, ...);
char *
grub_util_path_concat_ext (size_t n, ...);
int int
grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off); grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off);
ssize_t ssize_t
@ -49,5 +54,13 @@ EXPORT_FUNC(grub_util_fd_close) (grub_util_fd_t fd);
grub_uint64_t grub_uint64_t
grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize); grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize);
char *
grub_util_make_temporary_file (void);
char *
grub_util_make_temporary_dir (void);
void
grub_util_unlink_recursive (const char *name);
grub_uint32_t
grub_util_get_mtime (const char *name);
#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */

View file

@ -0,0 +1,39 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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/>.
*/
#ifndef GRUB_EMU_EXEC_H
#define GRUB_EMU_EXEC_H 1
#include <config.h>
#include <stdarg.h>
#include <sys/types.h>
pid_t
grub_util_exec_pipe (const char *const *argv, int *fd);
pid_t
grub_util_exec_pipe_stderr (const char *const *argv, int *fd);
int
grub_util_exec (const char *const *argv);
int
grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
const char *stdout_file);
int
grub_util_exec_redirect_null (const char *const *argv);
#endif

View file

@ -50,6 +50,12 @@ grub_util_fd_readdir (grub_util_fd_dir_t dirp)
return readdir (dirp); return readdir (dirp);
} }
static inline int
grub_util_rmdir (const char *pathname)
{
return rmdir (pathname);
}
static inline int static inline int
grub_util_unlink (const char *pathname) grub_util_unlink (const char *pathname)
{ {
@ -62,7 +68,7 @@ grub_util_rename (const char *from, const char *to)
return rename (from, to); return rename (from, to);
} }
#define grub_util_mkdir(a) mkdir (a) #define grub_util_mkdir(a) mkdir (a, 0700)
struct grub_util_fd struct grub_util_fd
{ {
@ -86,7 +92,7 @@ enum grub_util_fd_open_flags_t
GRUB_UTIL_FD_O_RDONLY = O_RDONLY, GRUB_UTIL_FD_O_RDONLY = O_RDONLY,
GRUB_UTIL_FD_O_WRONLY = O_WRONLY, GRUB_UTIL_FD_O_WRONLY = O_WRONLY,
GRUB_UTIL_FD_O_RDWR = O_RDWR, GRUB_UTIL_FD_O_RDWR = O_RDWR,
GRUB_UTIL_FD_O_CREAT = O_CREAT, GRUB_UTIL_FD_O_CREATTRUNC = O_CREAT | O_TRUNC,
GRUB_UTIL_FD_O_SYNC = (0 GRUB_UTIL_FD_O_SYNC = (0
#ifdef O_SYNC #ifdef O_SYNC
| O_SYNC | O_SYNC

View file

@ -59,6 +59,12 @@ grub_util_unlink (const char *pathname)
return unlink (pathname); return unlink (pathname);
} }
static inline int
grub_util_rmdir (const char *pathname)
{
return rmdir (pathname);
}
static inline int static inline int
grub_util_rename (const char *from, const char *to) grub_util_rename (const char *from, const char *to)
{ {

View file

@ -55,6 +55,9 @@ grub_util_fd_closedir (grub_util_fd_dir_t dirp);
grub_util_fd_dirent_t grub_util_fd_dirent_t
grub_util_fd_readdir (grub_util_fd_dir_t dirp); grub_util_fd_readdir (grub_util_fd_dir_t dirp);
int
grub_util_rmdir (const char *pathname);
enum grub_util_fd_open_flags_t enum grub_util_fd_open_flags_t
{ {
GRUB_UTIL_FD_O_RDONLY = 1, GRUB_UTIL_FD_O_RDONLY = 1,

View file

@ -26,6 +26,104 @@
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/emu/hostfile.h> #include <grub/emu/hostfile.h>
#define GRUB_INSTALL_OPTIONS \
{ "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \
0, N_("pre-load specified modules MODULES"), 1 }, \
{ "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \
N_("MODULES"), 0, \
N_("install only MODULES and their dependencies [default=all]"), 1 }, \
{ "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \
0, N_("install THEMES [default=%s]"), 1 }, \
{ "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \
0, N_("install FONTS [default=%s]"), 1 }, \
{ "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\
0, N_("install only LOCALES [default=all]"), 1 }, \
{ "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \
"no,xz,gz,lzo", OPTION_ARG_OPTIONAL, \
N_("compress GRUB files [optional]"), 1 }, \
/* TRANSLATORS: platform here isn't identifier. It can be translated. */ \
{ "directory", 'd', N_("DIR"), 0, \
N_("use images and modules under DIR [default=%s/<platform>]"), 1 }, \
{ "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \
N_("DIR"), OPTION_HIDDEN, \
N_("use images and modules under DIR [default=%s/<platform>]"), 1 }, \
{ "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \
"FILE", OPTION_HIDDEN, 0, 1 }, \
/* TRANSLATORS: "embed" is a verb (command description). "*/ \
{ "pubkey", 'k', N_("FILE"), 0, \
N_("embed FILE as public key for signature checking"), 0}, \
{ "verbose", 'v', 0, 0, \
N_("increase verbosity"), 1 }
int
grub_install_parse (int key, char *arg);
void
grub_install_push_module (const char *val);
void
grub_install_pop_module (void);
char *
grub_install_help_filter (int key, const char *text,
void *input __attribute__ ((unused)));
enum grub_install_plat
{
GRUB_INSTALL_PLATFORM_I386_PC,
GRUB_INSTALL_PLATFORM_I386_EFI,
GRUB_INSTALL_PLATFORM_I386_QEMU,
GRUB_INSTALL_PLATFORM_I386_COREBOOT,
GRUB_INSTALL_PLATFORM_I386_MULTIBOOT,
GRUB_INSTALL_PLATFORM_I386_IEEE1275,
GRUB_INSTALL_PLATFORM_X86_64_EFI,
GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON,
GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275,
GRUB_INSTALL_PLATFORM_MIPSEL_ARC,
GRUB_INSTALL_PLATFORM_MIPS_ARC,
GRUB_INSTALL_PLATFORM_IA64_EFI,
GRUB_INSTALL_PLATFORM_ARM_UBOOT,
GRUB_INSTALL_PLATFORM_ARM_EFI,
GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS,
GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
GRUB_INSTALL_PLATFORM_MAX
};
enum grub_install_options {
GRUB_INSTALL_OPTIONS_DIRECTORY = 'd',
GRUB_INSTALL_OPTIONS_VERBOSITY = 'v',
GRUB_INSTALL_OPTIONS_MODULES = 0x201,
GRUB_INSTALL_OPTIONS_INSTALL_MODULES,
GRUB_INSTALL_OPTIONS_INSTALL_THEMES,
GRUB_INSTALL_OPTIONS_INSTALL_FONTS,
GRUB_INSTALL_OPTIONS_INSTALL_LOCALES,
GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS,
GRUB_INSTALL_OPTIONS_DIRECTORY2,
GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE
};
extern char *grub_install_source_directory;
enum grub_install_plat
grub_install_get_target (const char *src);
void
grub_install_mkdir_p (const char *dst);
void
grub_install_copy_files (const char *src,
const char *dst,
enum grub_install_plat platid);
char *
grub_install_get_platform_name (enum grub_install_plat platid);
const char *
grub_install_get_platform_cpu (enum grub_install_plat platid);
const char *
grub_install_get_platform_platform (enum grub_install_plat platid);
typedef enum { typedef enum {
GRUB_COMPRESSION_AUTO, GRUB_COMPRESSION_AUTO,
GRUB_COMPRESSION_NONE, GRUB_COMPRESSION_NONE,
@ -33,6 +131,25 @@ typedef enum {
GRUB_COMPRESSION_LZMA GRUB_COMPRESSION_LZMA
} grub_compression_t; } grub_compression_t;
void
grub_install_make_image_wrap (const char *dir, const char *prefix,
const char *outname, char *memdisk_path,
char *config_path,
const char *format, int note,
grub_compression_t comp);
void
grub_install_make_image_wrap_file (const char *dir, const char *prefix,
FILE *fp, const char *outname,
char *memdisk_path,
char *config_path,
const char *mkimage_target, int note,
grub_compression_t comp);
int
grub_install_copy_file (const char *src,
const char *dst,
int is_critical);
struct grub_install_image_target_desc; struct grub_install_image_target_desc;
void void
@ -66,6 +183,32 @@ grub_install_get_image_targets_string (void);
const char * const char *
grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); grub_util_get_target_dirname (const struct grub_install_image_target_desc *t);
void
grub_install_create_envblk_file (const char *name);
const char *
grub_install_get_default_x86_platform (void);
void
grub_install_register_efi (const char *efidir_disk, int efidir_part,
const char *efifile_path,
const char *efi_distributor);
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
int partno, const char *relpath);
void
grub_install_sgi_setup (const char *install_device,
const char *imgfile, const char *destname);
int
grub_install_compress_gzip (const char *src, const char *dest);
int
grub_install_compress_lzop (const char *src, const char *dest);
int
grub_install_compress_xz (const char *src, const char *dest);
void void
grub_install_get_blocklist (grub_device_t root_dev, grub_install_get_blocklist (grub_device_t root_dev,
const char *core_path, const char *core_img, const char *core_path, const char *core_img,
@ -89,4 +232,10 @@ grub_util_render_label (const char *label_font,
const char *label_string, const char *label_string,
const char *label); const char *label);
const char *
grub_util_get_target_name (const struct grub_install_image_target_desc *t);
extern char *grub_install_copy_buffer;
#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576
#endif #endif

View file

@ -68,10 +68,10 @@ UPDATEPOFILES = @UPDATEPOFILES@
DUMMYPOFILES = @DUMMYPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@
DISTFILES.common = Makefile.in.in remove-potcdate.sin \ DISTFILES.common = Makefile.in.in remove-potcdate.sin \
$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) \
$(DISTFILES.common.extra3) $(DISTFILES.common.extra4) $(DISTFILES.common.extra3) $(DISTFILES.common.extra4) $(DISTFILES.common.extra5)
DISTFILES = $(DISTFILES.common) Makevars POTFILES.in POTFILES-shell.in \ DISTFILES = $(DISTFILES.common) Makevars POTFILES.in POTFILES-shell.in \
$(POFILES) $(GMOFILES) \ $(POFILES) $(GMOFILES) \
$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) grub.d.sed README $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) $(DISTFILES.extra5) grub.d.sed README
POTFILES = \ POTFILES = \

11
po/Rules-windowsdir Normal file
View file

@ -0,0 +1,11 @@
# generate windowsdir
DISTFILES.common.extra5 = Rules-windowsdir
windowsdir="$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows"
windowsdir: $(GMOFILES)
test -d "$(windowsdir)/locale" || mkdir "$(windowsdir)/locale"
for x in $(CATALOGS); do \
test -d "$(windowsdir)/locale/$${x%.gmo}" || mkdir "$(windowsdir)/locale/$${x%.gmo}"; \
cp -fp "$(srcdir)/$$x" "$(windowsdir)/locale/$${x%.gmo}/grub.mo"; \
done

View file

@ -347,8 +347,8 @@ fi
if [ x$boot != xnet ] && [ x$boot != xemu ]; then if [ x$boot != xnet ] && [ x$boot != xemu ]; then
cp -R "@srcdir@/themes" "@builddir@" cp -R "@srcdir@/themes" "@builddir@"
pkgdatadir="@builddir@" sh "@builddir@/grub-mkrescue" "--grub-mkimage=${builddir}/grub-mkimage" "--grub-render-label=${builddir}/grub-render-label" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
--rom-directory="${rom_directory}" "--grub-mkimage-extra=$mkimage_extra_arg" ${mkrescue_args} \ --rom-directory="${rom_directory}" $mkimage_extra_arg ${mkrescue_args} \
"/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
${files} >/dev/null 2>&1 ${files} >/dev/null 2>&1
fi fi
@ -418,7 +418,7 @@ do_trim ()
if [ x$boot = xnet ]; then if [ x$boot = xnet ]; then
netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
pkgdatadir="@builddir@" sh "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${cfgfile}" "$netdir/boot/grub/grub.cfg"
cp "${source}" "$netdir/boot/grub/testcase.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg"
timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim

112
util/config.c Normal file
View file

@ -0,0 +1,112 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2013 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 <string.h>
#include <grub/emu/config.h>
#include <grub/util/misc.h>
void
grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple)
{
char *buffer = NULL;
size_t sz = 0;
while (getline (&buffer, &sz, f) >= 0)
{
const char *ptr;
for (ptr = buffer; *ptr && grub_isspace (*ptr); ptr++);
if (grub_strncmp (ptr, "GRUB_ENABLE_CRYPTODISK=",
sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1) == 0)
{
ptr += sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1;
if (*ptr == '"' || *ptr == '\'')
ptr++;
if (*ptr == 'y')
cfg->is_cryptodisk_enabled = 1;
continue;
}
if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=",
sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0)
{
char *optr;
enum { NONE, SNGLQUOT, DBLQUOT } state;
if (simple)
{
free (cfg->grub_distributor);
cfg->grub_distributor = xstrdup (ptr);
continue;
}
free (cfg->grub_distributor);
cfg->grub_distributor = xmalloc (strlen (ptr) + 1);
optr = cfg->grub_distributor;
state = NONE;
for (; *ptr; ptr++)
switch (*ptr)
{
case '\\':
if (state == SNGLQUOT)
{
*optr++ = *ptr;
continue;
}
if (ptr[1])
{
*optr++ = ptr[1];
ptr++;
continue;
}
ptr++;
break;
case '"':
if (state == NONE)
{
state = DBLQUOT;
continue;
}
if (state == DBLQUOT)
{
state = NONE;
continue;
}
*optr++ = *ptr;
continue;
case '\'':
if (state == SNGLQUOT)
{
state = NONE;
continue;
}
if (state == NONE)
{
state = SNGLQUOT;
continue;
}
*optr++ = *ptr;
continue;
default:
*optr++ = *ptr;
continue;
}
*optr = '\0';
}
}
}

863
util/grub-install-common.c Normal file
View file

@ -0,0 +1,863 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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/types.h>
#include <grub/emu/misc.h>
#include <grub/util/misc.h>
#include <grub/misc.h>
#include <grub/device.h>
#include <grub/disk.h>
#include <grub/file.h>
#include <grub/fs.h>
#include <grub/env.h>
#include <grub/term.h>
#include <grub/mm.h>
#include <grub/lib/hexdump.h>
#include <grub/crypto.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/zfs/zfs.h>
#include <grub/util/install.h>
#include <grub/util/resolve.h>
#include <grub/emu/hostfile.h>
#include <grub/emu/config.h>
#include <grub/emu/hostfile.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
char *
grub_install_help_filter (int key, const char *text,
void *input __attribute__ ((unused)))
{
switch (key)
{
case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
return xasprintf(text, "starfield");
case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
return xasprintf(text, "unicode");
case GRUB_INSTALL_OPTIONS_DIRECTORY:
case GRUB_INSTALL_OPTIONS_DIRECTORY2:
return xasprintf(text, grub_util_get_pkglibdir ());
default:
return (char *) text;
}
}
static int (*compress_func) (const char *src, const char *dest) = NULL;
char *grub_install_copy_buffer;
int
grub_install_copy_file (const char *src,
const char *dst,
int is_needed)
{
grub_util_fd_t in, out;
ssize_t r;
grub_util_info ("copying `%s' -> `%s'", src, dst);
in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY);
if (!GRUB_UTIL_FD_IS_VALID (in))
{
if (is_needed)
grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
else
grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
return 0;
}
out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY
| GRUB_UTIL_FD_O_CREATTRUNC);
if (!GRUB_UTIL_FD_IS_VALID (out))
{
grub_util_error (_("cannot open `%s': %s"), dst,
grub_util_fd_strerror ());
grub_util_fd_close (in);
return 0;
}
if (!grub_install_copy_buffer)
grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
while (1)
{
r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
if (r <= 0)
break;
grub_util_fd_write (out, grub_install_copy_buffer, r);
}
grub_util_fd_sync (out);
grub_util_fd_close (in);
grub_util_fd_close (out);
if (r < 0)
grub_util_error ("cannot copy `%s' to `%s': %s",
src, dst, grub_util_fd_strerror ());
return 1;
}
int
grub_install_compress_file (const char *in_name,
const char *out_name,
int is_needed)
{
int ret;
if (!compress_func)
ret = grub_install_copy_file (in_name, out_name, is_needed);
else
{
grub_util_info ("compressing `%s' -> `%s'", in_name, out_name);
ret = !compress_func (in_name, out_name);
if (!ret && is_needed)
grub_util_warn ("can't compress `%s' to `%s'", in_name, out_name);
}
if (!ret && is_needed)
grub_util_error ("cannot copy `%s' to `%s': %s",
in_name, out_name, grub_util_fd_strerror ());
return ret;
}
static int
is_path_separator (char c)
{
#if defined (__MINGW32__) || defined (__CYGWIN__)
if (c == '\\')
return 1;
#endif
if (c == '/')
return 1;
return 0;
}
void
grub_install_mkdir_p (const char *dst)
{
char *t = xstrdup (dst);
char *p;
for (p = t; *p; p++)
{
if (is_path_separator (*p))
{
char s = *p;
*p = '\0';
grub_util_mkdir (t);
*p = s;
}
}
grub_util_mkdir (t);
free (t);
}
static void
clean_grub_dir (const char *di)
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
d = grub_util_fd_opendir (di);
if (!d)
grub_util_error (_("cannot open directory `%s': %s"),
di, grub_util_fd_strerror ());
while ((de = grub_util_fd_readdir (d)))
{
const char *ext = strrchr (de->d_name, '.');
if ((ext && (strcmp (ext, ".mod") == 0
|| strcmp (ext, ".lst") == 0
|| strcmp (ext, ".img") == 0
|| strcmp (ext, ".mo") == 0)
&& strcmp (de->d_name, "menu.lst") != 0)
|| strcmp (de->d_name, "efiemu32.o") == 0
|| strcmp (de->d_name, "efiemu64.o") == 0)
{
char *x = grub_util_path_concat (2, di, de->d_name);
if (grub_util_unlink (x) < 0)
grub_util_error ("cannont delete `%s': %s", x,
grub_util_fd_strerror ());
free (x);
}
}
grub_util_fd_closedir (d);
}
struct install_list
{
int is_default;
char **entries;
size_t n_entries;
size_t n_alloc;
};
struct install_list install_modules = { 1, 0, 0, 0 };
struct install_list modules = { 1, 0, 0, 0 };
struct install_list install_locales = { 1, 0, 0, 0 };
struct install_list install_fonts = { 1, 0, 0, 0 };
struct install_list install_themes = { 1, 0, 0, 0 };
char *grub_install_source_directory = NULL;
void
grub_install_push_module (const char *val)
{
modules.is_default = 0;
if (modules.n_entries + 1 >= modules.n_alloc)
{
modules.n_alloc <<= 1;
if (modules.n_alloc < 16)
modules.n_alloc = 16;
modules.entries = xrealloc (modules.entries,
modules.n_alloc * sizeof (modules.entries));
}
modules.entries[modules.n_entries++] = xstrdup (val);
modules.entries[modules.n_entries] = NULL;
}
void
grub_install_pop_module (void)
{
modules.n_entries--;
free (modules.entries[modules.n_entries]);
modules.entries[modules.n_entries] = NULL;
}
static void
handle_install_list (struct install_list *il, const char *val,
int default_all)
{
const char *ptr;
char **ce;
il->is_default = 0;
free (il->entries);
il->entries = NULL;
il->n_entries = 0;
if (strcmp (val, "all") == 0 && default_all)
{
il->is_default = 1;
return;
}
ptr = val;
while (1)
{
while (*ptr && grub_isspace (*ptr))
ptr++;
if (!*ptr)
break;
while (*ptr && !grub_isspace (*ptr))
ptr++;
il->n_entries++;
}
il->n_alloc = il->n_entries + 1;
il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0]));
for (ce = il->entries; ; ce++)
{
const char *bptr;
while (*ptr && grub_isspace (*ptr))
ptr++;
if (!*ptr)
break;
bptr = ptr;
while (*ptr && !grub_isspace (*ptr))
ptr++;
*ce = xmalloc (ptr - bptr + 1);
memcpy (*ce, bptr, ptr - bptr);
(*ce)[ptr - bptr] = '\0';
ce++;
}
*ce = NULL;
}
static char **pubkeys;
static size_t npubkeys;
int
grub_install_parse (int key, char *arg)
{
switch (key)
{
case 'k':
pubkeys = xrealloc (pubkeys,
sizeof (pubkeys[0])
* (npubkeys + 1));
pubkeys[npubkeys++] = xstrdup (arg);
return 1;
case GRUB_INSTALL_OPTIONS_VERBOSITY:
verbosity++;
return 1;
case GRUB_INSTALL_OPTIONS_DIRECTORY:
case GRUB_INSTALL_OPTIONS_DIRECTORY2:
free (grub_install_source_directory);
grub_install_source_directory = xstrdup (arg);
return 1;
case GRUB_INSTALL_OPTIONS_INSTALL_MODULES:
handle_install_list (&install_modules, arg, 0);
return 1;
case GRUB_INSTALL_OPTIONS_MODULES:
handle_install_list (&modules, arg, 0);
return 1;
case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES:
handle_install_list (&install_locales, arg, 0);
return 1;
case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
handle_install_list (&install_themes, arg, 0);
return 1;
case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
handle_install_list (&install_fonts, arg, 0);
return 1;
case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS:
if (strcmp (arg, "no") == 0)
{
compress_func = NULL;
return 1;
}
if (strcmp (arg, "gz") == 0)
{
compress_func = grub_install_compress_gzip;
return 1;
}
if (strcmp (arg, "xz") == 0)
{
compress_func = grub_install_compress_xz;
return 1;
}
if (strcmp (arg, "lzo") == 0)
{
compress_func = grub_install_compress_lzop;
return 1;
}
grub_util_error (_("Unrecognized compression `%s'"), arg);
case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
return 1;
default:
return 0;
}
}
static int
decompressors (void)
{
if (compress_func == grub_install_compress_gzip)
{
grub_install_push_module ("gzio");
return 1;
}
if (compress_func == grub_install_compress_xz)
{
grub_install_push_module ("xzio");
grub_install_push_module ("gcry_crc");
return 2;
}
if (compress_func == grub_install_compress_lzop)
{
grub_install_push_module ("lzopio");
grub_install_push_module ("adler32");
grub_install_push_module ("gcry_crc");
return 3;
}
return 0;
}
void
grub_install_make_image_wrap_file (const char *dir, const char *prefix,
FILE *fp, const char *outname,
char *memdisk_path,
char *config_path,
const char *mkimage_target, int note,
grub_compression_t comp)
{
const struct grub_install_image_target_desc *tgt;
const char *const compnames[] =
{
[GRUB_COMPRESSION_AUTO] = "auto",
[GRUB_COMPRESSION_NONE] = "none",
[GRUB_COMPRESSION_XZ] = "xz",
[GRUB_COMPRESSION_LZMA] = "lzma",
};
grub_size_t slen = 1;
char *s, *p;
char **pk, **md;
int dc = decompressors ();
if (memdisk_path)
slen += 20 + grub_strlen (memdisk_path);
if (config_path)
slen += 20 + grub_strlen (config_path);
for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
slen += 20 + grub_strlen (*pk);
for (md = modules.entries; *md; md++)
{
slen += 10 + grub_strlen (*md);
}
p = s = xmalloc (slen);
if (memdisk_path)
{
p = grub_stpcpy (p, "--memdisk '");
p = grub_stpcpy (p, memdisk_path);
*p++ = '\'';
*p++ = ' ';
}
if (config_path)
{
p = grub_stpcpy (p, "--config '");
p = grub_stpcpy (p, config_path);
*p++ = '\'';
*p++ = ' ';
}
for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
{
p = grub_stpcpy (p, "--pubkey '");
p = grub_stpcpy (p, *pk);
*p++ = '\'';
*p++ = ' ';
}
for (md = modules.entries; *md; md++)
{
*p++ = '\'';
p = grub_stpcpy (p, *md);
*p++ = '\'';
*p++ = ' ';
}
*p = '\0';
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
" --output '%s' "
"--format '%s' --compression '%s' %s %s\n",
dir, prefix,
outname, mkimage_target,
compnames[comp], note ? "--note" : "", s);
tgt = grub_install_get_image_target (mkimage_target);
if (!tgt)
grub_util_error (_("unknown target format %s\n"), mkimage_target);
grub_install_generate_image (dir, prefix, fp, outname,
modules.entries, memdisk_path,
pubkeys, npubkeys, config_path, tgt,
note, comp);
while (dc--)
grub_install_pop_module ();
}
void
grub_install_make_image_wrap (const char *dir, const char *prefix,
const char *outname, char *memdisk_path,
char *config_path,
const char *mkimage_target, int note,
grub_compression_t comp)
{
FILE *fp;
fp = grub_util_fopen (outname, "wb");
if (! fp)
grub_util_error (_("cannot open `%s': %s"), outname,
strerror (errno));
grub_install_make_image_wrap_file (dir, prefix, fp, outname,
memdisk_path, config_path,
mkimage_target, note, comp);
fflush (fp);
fsync (fileno (fp));
fclose (fp);
}
static void
copy_by_ext (const char *srcd,
const char *dstd,
const char *extf,
int req)
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
d = grub_util_fd_opendir (srcd);
if (!d && !req)
return;
if (!d)
grub_util_error (_("cannot open directory `%s': %s"),
srcd, grub_util_fd_strerror ());
while ((de = grub_util_fd_readdir (d)))
{
const char *ext = strrchr (de->d_name, '.');
if (ext && strcmp (ext, extf) == 0)
{
char *srcf = grub_util_path_concat (2, srcd, de->d_name);
char *dstf = grub_util_path_concat (2, dstd, de->d_name);
grub_install_compress_file (srcf, dstf, 1);
free (srcf);
free (dstf);
}
}
grub_util_fd_closedir (d);
}
static void
copy_all (const char *srcd,
const char *dstd)
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
d = grub_util_fd_opendir (srcd);
if (!d)
grub_util_error (_("cannot open directory `%s': %s"),
srcd, grub_util_fd_strerror ());
while ((de = grub_util_fd_readdir (d)))
{
char *srcf;
char *dstf;
if (strcmp (de->d_name, ".") == 0
|| strcmp (de->d_name, "..") == 0)
continue;
srcf = grub_util_path_concat (2, srcd, de->d_name);
if (grub_util_is_special_file (srcf)
|| grub_util_is_directory (srcf))
continue;
dstf = grub_util_path_concat (2, dstd, de->d_name);
grub_install_compress_file (srcf, dstf, 1);
free (srcf);
free (dstf);
}
grub_util_fd_closedir (d);
}
static void
copy_locales (const char *dstd)
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
const char *locale_dir = grub_util_get_localedir ();
d = grub_util_fd_opendir (LOCALEDIR);
if (!d)
{
grub_util_warn (_("cannot open directory `%s': %s"),
locale_dir, grub_util_fd_strerror ());
return;
}
while ((de = grub_util_fd_readdir (d)))
{
char *srcf;
char *dstf;
if (strcmp (de->d_name, ".") == 0)
continue;
if (strcmp (de->d_name, "..") == 0)
continue;
srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name,
"LC_MESSAGES", PACKAGE, ".mo");
dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo");
grub_install_compress_file (srcf, dstf, 0);
free (srcf);
free (dstf);
}
grub_util_fd_closedir (d);
}
static struct
{
enum grub_install_plat val;
const char *cpu;
const char *platform;
} platforms[] =
{
{ GRUB_INSTALL_PLATFORM_I386_PC, "i386", "pc" },
{ GRUB_INSTALL_PLATFORM_I386_EFI, "i386", "efi" },
{ GRUB_INSTALL_PLATFORM_I386_QEMU, "i386", "qemu" },
{ GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386", "coreboot" },
{ GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386", "multiboot" },
{ GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386", "ieee1275" },
{ GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64", "efi" },
{ GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel", "loongson" },
{ GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel", "qemu_mips" },
{ GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips", "qemu_mips" },
{ GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel", "arc" },
{ GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips", "arc" },
{ GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, "sparc64", "ieee1275" },
{ GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc", "ieee1275" },
{ GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64", "efi" },
{ GRUB_INSTALL_PLATFORM_ARM_EFI, "arm", "efi" },
{ GRUB_INSTALL_PLATFORM_ARM_UBOOT, "arm", "uboot" },
};
char *
grub_install_get_platform_name (enum grub_install_plat platid)
{
return xasprintf ("%s-%s", platforms[platid].cpu,
platforms[platid].platform);
}
const char *
grub_install_get_platform_cpu (enum grub_install_plat platid)
{
return platforms[platid].cpu;
}
const char *
grub_install_get_platform_platform (enum grub_install_plat platid)
{
return platforms[platid].platform;
}
void
grub_install_copy_files (const char *src,
const char *dst,
enum grub_install_plat platid)
{
char *dst_platform, *dst_locale, *dst_fonts;
const char *pkgdatadir = grub_util_get_pkgdatadir ();
{
char *platform;
platform = xasprintf ("%s-%s", platforms[platid].cpu,
platforms[platid].platform);
dst_platform = grub_util_path_concat (2, dst, platform);
free (platform);
}
dst_locale = grub_util_path_concat (2, dst, "locale");
dst_fonts = grub_util_path_concat (2, dst, "fonts");
grub_install_mkdir_p (dst_platform);
grub_install_mkdir_p (dst_locale);
clean_grub_dir (dst);
clean_grub_dir (dst_platform);
clean_grub_dir (dst_locale);
if (install_modules.is_default)
copy_by_ext (src, dst_platform, ".mod", 1);
else
{
struct grub_util_path_list *path_list, *p;
path_list = grub_util_resolve_dependencies (src, "moddep.lst",
install_modules.entries);
for (p = path_list; p; p = p->next)
{
char *srcf = grub_util_path_concat_ext (2, src, p->name, ".mo");
char *dstf = grub_util_path_concat_ext (2, dst, p->name, ".mo");
grub_install_compress_file (srcf, dstf, 1);
free (srcf);
free (dstf);
}
}
const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o",
"moddep.lst", "command.lst",
"fs.lst", "partmap.lst",
"parttool.lst",
"video.lst", "crypto.lst",
"terminal.lst" };
size_t i;
for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++)
{
char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]);
char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]);
if (i == 0 || i == 1)
grub_install_compress_file (srcf, dstf, 0);
else
grub_install_compress_file (srcf, dstf, 1);
free (srcf);
free (dstf);
}
if (install_locales.is_default)
{
char *srcd = grub_util_path_concat (2, src, "po");
copy_by_ext (srcd, dst_locale, ".mo", 0);
copy_locales (dst_locale);
free (srcd);
}
else
{
for (i = 0; i < install_locales.n_entries; i++)
{
char *srcf = grub_util_path_concat_ext (3, src,
"po",
install_locales.entries[i],
".mo");
char *dstf = grub_util_path_concat_ext (2, dst_locale,
install_locales.entries[i],
".mo");
if (grub_install_compress_file (srcf, dstf, 0))
{
free (srcf);
free (dstf);
continue;
}
free (srcf);
srcf = grub_util_path_concat_ext (4,
LOCALEDIR,
install_locales.entries[i],
"LC_MESSAGES",
PACKAGE,
".mo");
if (grub_install_compress_file (srcf, dstf, 0))
{
free (srcf);
free (dstf);
continue;
}
grub_util_error (_("cannot find locale `%s'"),
install_locales.entries[i]);
}
}
if (install_themes.is_default)
{
install_themes.is_default = 0;
install_themes.n_entries = 1;
install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0]));
install_themes.entries[0] = xstrdup ("starfield");
install_themes.entries[1] = NULL;
}
for (i = 0; i < install_themes.n_entries; i++)
{
char *srcf = grub_util_path_concat (4, pkgdatadir, "themes",
install_themes.entries[i],
"theme.txt");
if (grub_util_is_regular (srcf))
{
char *srcd = grub_util_path_concat (3, pkgdatadir, "themes",
install_themes.entries[i]);
char *dstd = grub_util_path_concat (3, dst, "themes",
install_themes.entries[i]);
grub_install_mkdir_p (dstd);
copy_all (srcd, dstd);
free (srcd);
free (dstd);
}
free (srcf);
}
if (install_fonts.is_default)
{
install_fonts.is_default = 0;
install_fonts.n_entries = 1;
install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0]));
install_fonts.entries[0] = xstrdup ("unicode");
install_fonts.entries[1] = NULL;
}
grub_install_mkdir_p (dst_fonts);
for (i = 0; i < install_fonts.n_entries; i++)
{
char *srcf = grub_util_path_concat_ext (2, pkgdatadir,
install_fonts.entries[i],
".pf2");
char *dstf = grub_util_path_concat_ext (2, dst_fonts,
install_fonts.entries[i],
".pf2");
grub_install_compress_file (srcf, dstf, 0);
free (srcf);
free (dstf);
}
free (dst_platform);
free (dst_locale);
free (dst_fonts);
}
enum grub_install_plat
grub_install_get_target (const char *src)
{
char *fn;
grub_util_fd_t f;
char buf[2048];
size_t r;
char *c, *pl, *p;
size_t i;
fn = grub_util_path_concat (2, src, "modinfo.sh");
f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY);
if (!GRUB_UTIL_FD_IS_VALID (f))
grub_util_error (_("%s doesn't exist. Please specify --target or --directory"),
fn);
r = grub_util_fd_read (f, buf, sizeof (buf) - 1);
grub_util_fd_close (f);
buf[r] = '\0';
c = strstr (buf, "grub_modinfo_target_cpu=");
if (!c || (c != buf && !grub_isspace (*(c-1))))
grub_util_error (_("invalid modinfo file `%s'"), fn);
pl = strstr (buf, "grub_modinfo_platform=");
if (!pl || (pl != buf && !grub_isspace (*(pl-1))))
grub_util_error (_("invalid modinfo file `%s'"), fn);
c += sizeof ("grub_modinfo_target_cpu=") - 1;
pl += sizeof ("grub_modinfo_platform=") - 1;
for (p = c; *p && !grub_isspace (*p); p++);
*p = '\0';
for (p = pl; *p && !grub_isspace (*p); p++);
*p = '\0';
for (i = 0; i < ARRAY_SIZE (platforms); i++)
if (strcmp (platforms[i].cpu, c) == 0
&& strcmp (platforms[i].platform, pl) == 0)
{
free (fn);
return platforms[i].val;
}
grub_util_error (_("Unknown platform `%s-%s'"), c, pl);
}
void
grub_util_unlink_recursive (const char *name)
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
d = grub_util_fd_opendir (name);
while ((de = grub_util_fd_readdir (d)))
{
char *fp;
if (strcmp (de->d_name, ".") == 0)
continue;
if (strcmp (de->d_name, "..") == 0)
continue;
fp = grub_util_path_concat (2, name, de->d_name);
if (grub_util_is_special_file (fp))
{
free (fp);
continue;
}
if (grub_util_is_regular (fp))
grub_util_unlink (fp);
else if (grub_util_is_directory (fp))
grub_util_unlink_recursive (fp);
free (fp);
}
grub_util_rmdir (name);
grub_util_fd_closedir (d);
}

1539
util/grub-install.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,829 +0,0 @@
#! /bin/sh
# Install GRUB on your drive.
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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/>.
# Initialize some variables.
sbindir="@sbindir@"
sysconfdir="@sysconfdir@"
host_os=@host_os@
target=
grub_probe="${sbindir}/@grub_probe@"
grub_editenv="${bindir}/@grub_editenv@"
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
rootdir=
bootdir=
grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`"
install_device=
force_lba=
recheck=no
debug=no
debug_image=
update_nvram=yes
removable=no
efi_quiet=-q
# Get GRUB_DISTRIBUTOR.
if test -f "${sysconfdir}/default/grub" ; then
. "${sysconfdir}/default/grub"
fi
bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr 'A-Z' 'a-z' | cut -d' ' -f1)"
if test -z "$bootloader_id"; then
bootloader_id=grub
fi
disk_module=unspecified
# Usage: usage
# Print the usage.
usage () {
# TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
# install to.
gettext_printf "Usage: %s [OPTION] [INSTALL_DEVICE]" "$self"
echo
gettext "Install GRUB on your drive." ; echo
echo
print_option_help "-h, --help" "$(gettext "print this message and exit")"
grub_print_install_files_help
dirmsg="$(gettext_printf "install GRUB images under the directory DIR/%s instead of the %s directory" "@grubdirname@" "$grubdir")"
print_option_help "--boot-directory=$(gettext "DIR")" "$dirmsg"
# TRANSLATORS: "TARGET" as in "target platform".
target_trans="$(gettext "TARGET")"
# TRANSLATORS: "current" refers to the platform user's currently running on
print_option_help "--target=$target_trans" "$(gettext "install GRUB for TARGET platform [default=current]")"
print_option_help "--grub-setup=$(gettext "FILE")" "$(gettext "use FILE as grub-setup")"
print_option_help "--grub-mkrelpath=$(gettext "FILE")" "$(gettext "use FILE as grub-mkrelpath")"
print_option_help "--grub-probe=$(gettext "FILE")" "$(gettext "use FILE as grub-probe")"
print_option_help "--grub-editenv=$(gettext "FILE")" "$(gettext "use FILE as grub-editenv")"
# TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
# effect but that it will make the resulting install unbootable from HDD.
print_option_help "--allow-floppy" "$(gettext "make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes.")"
print_option_help "--recheck" "$(gettext "delete device map if it already exists")"
print_option_help "--force" "$(gettext "install even if problems are detected")"
print_option_help "--force-file-id" "$(gettext "use identifier file even if UUID is available")"
print_option_help "--disk-module=$(gettext "MODULE")" "$(gettext "disk module to use (biosdisk or native). This option is only available on BIOS target.")"
print_option_help "--no-nvram" "$(gettext "don't update the \`boot-device' NVRAM variable. This option is only available on IEEE1275 targets.")"
print_option_help "--removable" "$(gettext "the installation device is removable. This option is only available on EFI.")"
print_option_help "--bootloader-id=$(gettext "ID")" "$(gettext "the ID of bootloader. This option is only available on EFI.")"
print_option_help "--efi-directory=$(gettext "DIR")" "$(gettext "use DIR as the EFI System Partition root.")"
echo
gettext "INSTALL_DEVICE must be system device filename.";echo
echo
gettext_printf "%s copies GRUB images into %s. On some platforms, it
may also install GRUB into the boot sector.\n" "$self" "$grubdir";echo
echo
gettext "Report bugs to <bug-grub@gnu.org>."; echo
}
allow_floppy=""
force_file_id=
efidir=
# Check the arguments.
while test $# -gt 0
do
grub_process_install_options "$@"
case "$grub_process_install_options_consumed" in
1) shift; continue;;
2) shift; shift; continue;;
esac
option=$1
shift
case "$option" in
-h | --help)
usage
exit 0 ;;
--force-file-id)
force_file_id=y ;;
# Accept and ignore for compatibility
--font)
shift;;
--font=*)
;;
# Accept for compatibility
--root-directory)
rootdir="`argument $option "$@"`"; shift;;
--root-directory=*)
rootdir="`echo "$option" | sed 's/--root-directory=//'`" ;;
--boot-directory)
bootdir="`argument $option "$@"`"; shift;;
--boot-directory=*)
bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;;
--efi-directory)
efidir="`argument $option "$@"`"; shift;;
--efi-directory=*)
efidir="`echo "$option" | sed 's/--efi-directory=//'`" ;;
--target)
target="`argument $option "$@"`"; shift;;
--target=*)
target="`echo "$option" | sed 's/--target=//'`" ;;
--grub-setup)
grub_setup="`argument "$option" "$@"`"; shift;;
--grub-setup=*)
grub_setup="`echo "$option" | sed 's/--grub-setup=//'`" ;;
--bootloader-id)
bootloader_id="`argument $option "$@"`"; shift;;
--bootloader-id=*)
bootloader_id="`echo "$option" | sed 's/--bootloader-id=//'`" ;;
--grub-mkrelpath)
grub_mkrelpath="`argument "$option" "$@"`"; shift;;
--grub-mkrelpath=*)
grub_mkrelpath="`echo "$option" | sed 's/--grub-mkrelpath=//'`" ;;
# Ignore: for compatibility
--grub-mkdevicemap)
shift;;
--grub-mkdevicemap=*)
;;
--grub-probe)
grub_probe="`argument "$option" "$@"`"; shift;;
--grub-probe=*)
grub_probe="`echo "$option" | sed 's/--grub-probe=//'`" ;;
--grub-editenv)
grub_editenv="`argument "$option" "$@"`"; shift;;
--grub-editenv=*)
grub_editenv="`echo "$option" | sed 's/--grub-editenv=//'`" ;;
--no-floppy)
;;
--recheck)
recheck=yes ;;
--removable)
removable=yes ;;
--allow-floppy)
allow_floppy="--allow-floppy" ;;
--disk-module)
disk_module="`argument "$option" "$@"`"; shift;
;;
--disk-module=*)
disk_module="`echo "$option" | sed 's/--disk-module=//'`"
;;
--no-nvram)
update_nvram=no ;;
# This is an undocumented feature...
--debug)
debug=yes ;;
--debug-image)
debug_image="`argument "$option" "$@"`"; shift;;
--debug-image=*)
debug_image="`echo "$option" | sed 's/--debug-image=//'`" ;;
-f | --force)
setup_force="--force" ;;
-*)
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
usage
exit 1
;;
*)
if test "x$install_device" != x; then
gettext "More than one install device?" 1>&2
echo 1>&2
usage
exit 1
fi
install_device="${option}" ;;
esac
done
if [ x$source_directory = x ]; then
if [ x$target = x ]; then
case x"`uname -m`" in
x"powerpc"* | x"ppc"*)
target="powerpc-ieee1275";;
x"sparc"*)
target="sparc64-ieee1275";;
x"mips"*"el")
target="mipsel-loongson";;
x"mips"*)
target="mips-arc";;
x"ia64"*)
target="ia64-efi";;
x"x86_64"* | x"amd64"*)
# On Linux, we need the efivars kernel modules.
# If no EFI is available this module just does nothing
# besides a small hello and if we detect efi we'll load it
# anyway later. So it should be safe to
# try to load it here.
case "$host_os" in
linux*)
modprobe -q efivars 2>/dev/null || true ;;
esac
if [ -d /sys/firmware/efi ]; then
target="x86_64-efi"
else
target=i386-pc
fi
;;
x"i"?"86"*)
# On Linux, we need the efivars kernel modules.
# If no EFI is available this module just does nothing
# besides a small hello and if we detect efi we'll load it
# anyway later. So it should be safe to
# try to load it here.
case "$host_os" in
linux*)
modprobe -q efivars 2>/dev/null || true ;;
esac
if [ -d /sys/firmware/efi ]; then
target="i386-efi"
elif [ -e /proc/device-tree ]; then
target=i386-pc
for x in /proc/device-tree/*; do
if [ -e "$x" ]; then
target="i386-ieee1275"
fi
done
else
target=i386-pc
fi
;;
x"arm"*)
target="arm-uboot";;
*)
gettext "Unable to determine your platform. Use --target." ;
echo ;;
esac
fi
source_directory="${libdir}/@PACKAGE@/$target"
fi
if ! [ -d "$source_directory" ]; then
gettext_printf "%s doesn't exist. Please specify --target or --directory\\n" "$source_directory"
exit 1
fi
. "${source_directory}"/modinfo.sh
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] ; then
if [ x$disk_module = xunspecified ]; then
disk_module=biosdisk
fi
elif [ "${grub_modinfo_platform}" = "ieee1275" ] || [ "${grub_modinfo_platform}" = "efi" ] || [ "${grub_modinfo_platform}" = "arc" ] || [ "${grub_modinfo_platform}" = "uboot" ] ; then
disk_module=
else
disk_module=native
fi
if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ]; then
grub_setup="${sbindir}/@grub_bios_setup@"
fi
if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]; then
grub_setup="${sbindir}/@grub_sparc64_setup@"
fi
if test "x$install_device" = x && ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \
|| [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]); then
gettext "Install device isn't specified." 1>&2
echo 1>&2
usage
exit 1
fi
if ! ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \
|| [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] \
|| [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] \
|| [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mips-arc" ]); then
install_device=
fi
# If the debugging feature is enabled, print commands.
setup_verbose=
if test x"$debug" = xyes; then
set -x
setup_verbose="--verbose"
efi_quiet=
fi
if [ -z "$bootdir" ]; then
# Default bootdir if bootdir not initialized.
bootdir="/@bootdirname@"
if [ -n "$rootdir" ] ; then
# Initialize bootdir if rootdir was initialized.
bootdir="${rootdir}/@bootdirname@"
fi
fi
grubdir="`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'`"
device_map="${grubdir}/device.map"
# Check if GRUB is installed.
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
set $grub_setup dummy
if test -f "$1"; then
:
else
# TRANSLATORS: This message is shown when required executable `%s'
# isn't found
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
fi
set "$grub_mkimage" dummy
if test -f "$1"; then
:
else
# TRANSLATORS: This message is shown when required executable `%s'
# isn't found
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
if [ x"$grub_modinfo_platform" = xefi ]; then
# Find the EFI System Partition.
if test -n "$efidir"; then
install_device="`"$grub_probe" --target=device --device-map= "${efidir}"`"
else
if test -d "${bootdir}/efi"; then
install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`"
# Is it a mount point?
if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
efidir="${bootdir}/efi"
fi
elif test -d "${bootdir}/EFI"; then
install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/EFI"`"
# Is it a mount point?
if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
efidir="${bootdir}/EFI"
fi
elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
# The EFI System Partition may have been given directly using
# --root-directory.
install_device="`"$grub_probe" --target=device --device-map= "${rootdir}"`"
# Is it a mount point?
if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${rootdir}/.."`"; then
efidir="${rootdir}"
fi
fi
if test -n "$efidir"; then
efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"`
if test "x$efi_fs" = xfat; then :; else
gettext_printf "%s doesn't look like an EFI partition.\n" "${efidir}" 1>&2
efidir=
fi
fi
fi
if test -n "$efidir"; then
# The EFI specification requires that an EFI System Partition must
# contain an "EFI" subdirectory, and that OS loaders are stored in
# subdirectories below EFI. Vendors are expected to pick names that do
# not collide with other vendors. To minimise collisions, we use the
# name of our distributor if possible.
efi_distributor="$bootloader_id"
if test $removable = yes; then
# The specification makes stricter requirements of removable
# devices, in order that only one image can be automatically loaded
# from them. The image must always reside under /EFI/BOOT, and it
# must have a specific file name depending on the architecture.
efi_distributor=BOOT
case "$grub_modinfo_target_cpu" in
i386)
efi_file=BOOTIA32.EFI ;;
x86_64)
efi_file=BOOTX64.EFI ;;
# GRUB does not yet support these architectures, but they're defined
# by the specification so we include them here to ease future
# expansion.
ia64)
efi_file=BOOTIA64.EFI ;;
arm)
efi_file=BOOTARM.EFI ;;
esac
else
# It is convenient for each architecture to have a different
# efi_file, so that different versions can be installed in parallel.
case "$grub_modinfo_target_cpu" in
i386)
efi_file=grubia32.efi ;;
x86_64)
efi_file=grubx64.efi ;;
# GRUB does not yet support these architectures, but they're defined
# by the specification so we include them here to ease future
# expansion.
ia64)
efi_file=grubia64.efi ;;
arm)
efi_file=grubarm.efi ;;
*)
efi_file=grub.efi ;;
esac
fi
efidir="$efidir/EFI/$efi_distributor"
mkdir -p "$efidir" || exit 1
else
# We don't know what's going on. Fall back to traditional
# (non-specification-compliant) behaviour.
efidir="$grubdir"
efi_distributor=
efi_file=grub.efi
fi
fi
# Create the GRUB directory if it is not present.
mkdir -p "$grubdir" || exit 1
mkdir -p "$grubdir/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1
# If --recheck is specified, remove the device map, if present.
if test $recheck = yes; then
rm -f "$device_map"
fi
# Device map file is optional
if test -f "$device_map"; then
# Make sure that there is no duplicated entry.
tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \
| sort | uniq -d | sed -n 1p`
if test -n "$tmp"; then
gettext_printf "The drive %s is defined multiple times in the device map %s\n" "$tmp" "$device_map" 1>&2
exit 1
fi
else
device_map=
fi
# Copy the GRUB images to the GRUB directory.
grub_install_files "${source_directory}" "${grubdir}" "${grub_modinfo_target_cpu}-$grub_modinfo_platform" all
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
for file in "${source_directory}"/*.img "${source_directory}"/efiemu??.o; do
if test -f "$file"; then
cp -f "$file" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1
fi
done
fi
if ! is_path_readable_by_grub "${grubdir}"; then
gettext_printf "Path \`%s' is not readable by GRUB on boot. Installation is impossible. Aborting.\n" "${grubdir}" 1>&2
exit 1
fi
# Write device to a variable so we don't have to traverse /dev every time.
grub_device="`"$grub_probe" --device-map="${device_map}" --target=device "${grubdir}"`" || exit 1
if ! test -f "${grubdir}"/grubenv; then
"$grub_editenv" "${grubdir}"/grubenv create
fi
# Create the core image. First, auto-detect the filesystem module.
fs_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs --device `"
if test "x$fs_module" = x ; then
gettext_printf "Auto-detection of a filesystem of %s failed.\n" "${grub_device}" 1>&2
gettext "Try with --recheck." 1>&2
echo 1>&2
gettext_printf "If the problem persists please report this together with the output of %s to <%s>" "\"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\"" "bug-grub@gnu.org" 1>&2
exit 1
fi
# Then the partition map module. In order to support partition-less media,
# this command is allowed to fail (--target=fs already grants us that the
# filesystem will be accessible).
partmap_module=
for x in `echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=partmap --device 2> /dev/null`; do
case "$x" in
netbsd | openbsd)
partmap_module="$partmap_module part_bsd";;
"") ;;
*)
partmap_module="$partmap_module part_$x";;
esac
done
# Device abstraction module, if any (lvm, raid).
devabstraction_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=abstraction --device`"
if [ "x$disk_module" = xata ]; then
disk_module=pata
fi
if [ "x$disk_module" = xnative ]; then
disk_module="pata ahci ohci"
if [ "x$grub_modinfo_target_cpu" = "xi386" ] || [ "x$grub_modinfo_target_cpu" = "xx86_64" ]; then
disk_module="$disk_module uhci"
fi
disk_module="$disk_module usbms"
fi
# The order in this list is critical. Be careful when modifying it.
modules="$modules $disk_module"
modules="$modules $fs_module $partmap_module $devabstraction_module"
relative_grubdir="`"$grub_mkrelpath" "${grubdir}"`" || exit 1
if [ "x${relative_grubdir}" = "x" ] ; then
relative_grubdir=/
fi
prefix_drive=
config_opt_file=
rm -f "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
if [ "x${debug_image}" != x ]; then
echo "set debug='${debug_image}'" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
fi
if [ "x${devabstraction_module}" = "x" ] ; then
if [ x"${install_device}" != x ]; then
if echo "${install_device}" | grep -qx "(.*)" ; then
install_drive="${install_device}"
else
install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1
fi
install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
fi
grub_drive="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=drive --device`" || exit 1
# Strip partition number
grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
if [ x"${install_device}" = x ] && [ x"${grub_modinfo_target_cpu}-$grub_modinfo_platform" = x"powerpc-ieee1275" ]; then
install_drive="$grub_drive"
fi
if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$grub_modinfo_platform" != xefi ] && [ "x$grub_modinfo_platform" != xpc ] && [ x"${grub_modinfo_platform}" != x"ieee1275" ]); then
# generic method (used on coreboot and ata mod)
uuid=
if [ x"$force_file_id" != xy ]; then
uuid="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs_uuid --device`"
fi
if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
elif [ x"$grub_modinfo_platform" = xpc ]; then
hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=bios_hints --device`"
elif [ x"$grub_modinfo_platform" = xefi ]; then
hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=efi_hints --device`"
elif [ x"$grub_modinfo_platform" = xieee1275 ]; then
hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device`"
elif [ x"$grub_modinfo_platform" = xloongson ] || [ x"$grub_modinfo_platform" = xqemu ] || [ x"$grub_modinfo_platform" = xcoreboot ] || [ x"$grub_modinfo_platform" = xmultiboot ] || [ x"$grub_modinfo_platform" = xqemu-mips ]; then
hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
else
gettext "No hints available for your platform. Expect reduced performance." 1>&2
echo 1>&2
hints=
fi
if [ x"$uuid" != x ]; then
echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
search_module=search_fs_uuid
else
mkdir -p "${grubdir}/uuid"
file="`mktemp "${grubdir}/uuid/XXXXXXXXXXXXXXXXXXXXXXXXX"`"
relfile="`${grub_mkrelpath} "$file"`"
echo "search.file '${relfile}' root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
search_module=search_fs_file
fi
echo 'set prefix=($root)'"$(echo "${relative_grubdir}" | sed "s,\\([ \"'\\\\]\\),\\\\\\1,g")" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
modules="$modules $search_module"
else
# we need to hardcode the partition number in the core image's prefix.
if [ x"$grub_partition" = x ]; then
prefix_drive="()"
else
# Comma is already there
prefix_drive="($grub_partition)"
fi
fi
else
if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
for uuid in "`echo "${grub_device}" | xargs "${grub_probe}" --target=cryptodisk_uuid --device`"; do
echo "cryptomount -u $uuid" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
done
config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
fi
prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
fi
case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
mips-qemu_mips | mipsel-qemu_mips) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}"-elf ;;
*) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}" ;;
esac
case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
i386-efi | x86_64-efi | ia64-efi) imgext=efi ;;
mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \
| powerpc-ieee1275 | mips-qemu_mips | mipsel-qemu_mips) imgext=elf ;;
*) imgext=img ;;
esac
if [ x"$config_opt_file" = x ]; then
"$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1
else
"$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1
fi
# Backward-compatibility kludges
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mipsel-loongson" ]; then
cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${bootdir}"/grub.elf
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then
cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${grubdir}/grub"
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-efi" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "x86_64-efi" ]; then
if [ x"$config_opt_file" = x ]; then
"$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1
else
"$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1
fi
fi
# Perform the grub_modinfo_platform-dependent install
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
# Now perform the installation.
"$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" \
--device-map="${device_map}" "${install_device}" || exit 1
elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then
# If a install device is defined, copy the core.elf to PReP partition.
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] && [ -n "${install_device}" ]; then
if [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t msdos_parttype)" != "41" ] \
&& [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t gpt_parttype)" != "9e1a2d38-c612-4316-aa26-8b49521e5a8b" ]; then
gettext "The chosen partition is not a PReP partition." 1>&2
echo 1>&2
exit 1
fi
if [ "$(file -s -b -L "${install_device}" | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then
dd if="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" of="${install_device}" status=noxfer || {
gettext "Failed to copy Grub to the PReP partition." 1>&2
echo 1>&2
exit 1
}
else
gettext "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:" 1>&2
echo 1>&2
echo " dd if=/dev/zero of=${install_device}"
exit 1
fi
fi
if [ x"$update_nvram" = xyes ]; then
ofpathname="`which ofpathname`"
nvsetenv="`which nvsetenv`"
set "$ofpathname" dummy
if test -f "$1"; then
:
else
# TRANSLATORS: This message is shown when required executable `%s'
# isn't found
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
set "$nvsetenv" dummy
if test -f "$1"; then
:
else
# TRANSLATORS: This message is shown when required executable `%s'
# isn't found
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != "powerpc-ieee1275" ] \
|| [ -z "${install_device}" ]; then
# Get the Open Firmware device tree path translation.
dev="`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
partno="`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`"
ofpath="`$ofpathname $dev`" || {
# TRANSLATORS: "device tree path" is the name of the device
# for IEEE1275
gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2
exit 1
}
# Point boot-device at the new grub install
boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" | sed 's,/,\\\\,g'`
else
dev="`echo "${install_device}" | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
boot_device="`$ofpathname "$dev"`" || {
# TRANSLATORS: "device tree path" is the name of the device
# for IEEE1275
gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2
exit 1
}
fi
"$nvsetenv" boot-device "$boot_device" || {
# TRANSLATORS: The %s will be replaced by an external program name.
gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2
gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2
echo 1>&2
echo " setenv boot-device $boot_device" 1>&2
exit 1
}
fi
elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xmips-arc ]; then
dvhtool -d "${install_device}" --unix-to-vh "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" grub
gettext "You will have to set \`SystemPartition' and \`OSLoader' manually." 1>&2
echo 1>&2
elif [ x"$grub_modinfo_platform" = xefi ]; then
cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/${efi_file}"
# For old macs. Suggested by Peter Jones.
if [ x$grub_modinfo_target_cpu = xi386 ]; then
cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/boot.efi"
fi
# Try to make this image bootable using the EFI Boot Manager, if available.
if test "$removable" = no; then
efibootmgr="`which efibootmgr`" || {
# TRANSLATORS: This message is shown when required executable `%s'
# isn't found
gettext_printf "%s: Not found.\n" "efibootmgr" 1>&2
exit 1
}
test -n "$efi_distributor" || {
gettext "EFI distributor id isn't specified." 1>&2
echo 1>&2
exit 1
}
# On Linux, we need the efivars kernel modules.
case "$host_os" in
linux*)
modprobe -q efivars 2>/dev/null || true ;;
esac
# Delete old entries from the same distributor.
for bootnum in `efibootmgr | grep '^Boot[0-9]' | \
fgrep -i " $efi_distributor" | cut -b5-8`; do
efibootmgr $efi_quiet -b "$bootnum" -B
done
# Add a new entry for the image we just created. efibootmgr needs to be
# given the disk device and partition number separately, so we have to
# fiddle about with grub-probe to get hold of this reasonably reliably.
# Use fresh device map text to avoid any problems with stale data, since
# all we need here is a one-to-one mapping.
efidir_drive="$("$grub_probe" --target=drive --device-map= "$efidir")"
efidir_disk="$("$grub_probe" --target=disk --device-map= "$efidir")"
if test -z "$efidir_drive" || test -z "$efidir_disk"; then
gettext_printf "Can't find GRUB drive for %s; unable to create EFI Boot Manager entry.\n" "$efidir" >&2
else
efidir_part="$(echo "$efidir_drive" | sed 's/^([^,]*,[^0-9]*//; s/[^0-9].*//')"
efibootmgr $efi_quiet -c -d "$efidir_disk" -p "$efidir_part" -w \
-L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file"
fi
fi
else
gettext "WARNING: no platform-specific install was performed" 1>&2
echo 1>&2
fi
gettext "Installation finished. No error reported." 1>&2
echo 1>&2
# Bye.
exit 0

View file

@ -1,263 +0,0 @@
#! /bin/sh
set -e
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 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/>.
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
bindir="@bindir@"
libdir="@libdir@"
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_TARNAME=@PACKAGE_TARNAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
datadir="@datadir@"
if [ "x$pkgdatadir" = x ]; then
pkgdatadir="${datadir}/@PACKAGE@"
fi
localedir="@datadir@/locale"
self=`basename $0`
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
. "${pkgdatadir}/grub-mkconfig_lib"
modules=
pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst \
handler.lst video.lst crypto.lst terminal.lst"
grub_mkimage="${bindir}/@grub_mkimage@"
grub_compress_file () {
if [ -f "$1" ] ; then
if [ "$compressor" != "" ] ; then
"$compressor" $compressor_opts "$1" > "$2"
else
cp -f "$1" "$2"
fi
else
gettext_printf "Skipping file \`%s': not a plain file\n" "$1" 1>&2
fi
}
grub_install_files () {
grub_install_files_source_directory="$1"
grub_install_files_target_directory="$2"
grub_install_files_platform="$3"
mkdir -p "${grub_install_files_target_directory}"/"${grub_install_files_platform}"
for file in "${grub_install_files_target_directory}"/*.mod \
"${grub_install_files_target_directory}"/*.lst \
"${grub_install_files_target_directory}"/*.img \
"${grub_install_files_target_directory}"/efiemu??.o \
"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.mod \
"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.lst \
"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.img \
"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/efiemu??.o;
do
if test -f "$file" && [ "`basename $file`" != menu.lst ]; then
rm -f "$file" || exit 1
fi
done
if [ x"$install_modules" = xall ]; then
for file in "${grub_install_files_source_directory}/"*.mod; do
grub_compress_file "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$(basename "$file")"
done
else
modules1=
modules2="$install_modules"
while [ x"$modules2" != x ]; do
modules3=
for x in $modules2; do
modules3="$modules3 $(grep "^$x:" "${grub_install_files_source_directory}/moddep.lst" | sed 's,^[^:]*:,,')"
done
modules1="$modules1 $modules2"
modules2="$modules3"
done
for file in $(echo "$modules1" | sed 's, ,\n,g' |sort -u); do
grub_compress_file "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$file.mod"
done
fi
for file in ${pkglib_DATA} efiemu32.o efiemu64.o; do
if test -f "${grub_install_files_source_directory}/${file}"; then
grub_compress_file "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/${file}"
fi
done
# Copy gettext files
mkdir -p "${grub_install_files_target_directory}"/locale
for file in "${grub_install_files_target_directory}"/locale/*.mo; do
if test -f "$file"; then
rm -f "$file" || exit 1
fi
done
if [ x"$install_locales" = xall ]; then
for file in "${grub_install_files_source_directory}"/po/*.mo; do
if test -f "$file"; then
grub_compress_file "$file" "${grub_install_files_target_directory}"/locale/"$(basename "$file")"
fi
done
for dir in "${localedir}"/*; do
if test -f "$dir/LC_MESSAGES/@PACKAGE@.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then
grub_compress_file "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"
fi
done
else
for locale in $install_locales; do
if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then
grub_compress_file "${grub_install_files_source_directory}"/po/locale.mo "${grub_install_files_target_directory}"/locale/$locale.mo
elif test -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo"; then
grub_compress_file "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo
fi
done
fi
for theme in ${install_themes} ; do
if test -f "${pkgdatadir}"/themes/"${theme}"/theme.txt; then
mkdir -p "${grub_install_files_target_directory}"/themes/"${theme}"
for file in "${pkgdatadir}"/themes/"${theme}"/*; do
grub_compress_file "$file" "${grub_install_files_target_directory}"/themes/"${theme}"/"$(basename "$file")"
done
fi
done
for font in ${install_fonts} ; do
if test -f "${pkgdatadir}"/"$font".pf2; then
mkdir -p "${grub_install_files_target_directory}"/fonts
grub_compress_file "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts/"$font".pf2
fi
done
}
grub_print_install_files_help () {
print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")"
print_option_help "--install-modules=$(gettext "MODULES")" "$(gettext "install only MODULES and their dependencies [default=all]")"
print_option_help "--themes=THEMES" "$(gettext_printf "install THEMES [default=%s]" "starfield")"
print_option_help "--fonts=FONTS" "$(gettext_printf "install FONTS [default=%s]" "unicode")"
print_option_help "--locales=LOCALES" "$(gettext_printf "install only LOCALES [default=all]")"
print_option_help "--compress[=no,xz,gz,lzo]" "$(gettext "compress GRUB files [optional]")"
# TRANSLATORS: platform here isn't identifier. It can be translated.
dir_msg="$(gettext_printf "use images and modules under DIR [default=%s/<platform>]" "${libdir}/@PACKAGE@")"
print_option_help "-d, --directory=$(gettext "DIR")" "$dir_msg"
print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")"
print_option_help "-v, --version" "$(gettext "print the version information and exit")"
}
install_modules=all
install_themes=starfield
install_fonts=unicode
install_locales=all
compress=no
grub_decompression_module=""
compressor=""
compressor_opts=""
source_directory=""
argument () {
opt=$1
shift
if test $# -eq 0; then
gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
exit 1
fi
echo $1
}
grub_parse_compress () {
compress="$1"
case x"$compress" in
xno) ;;
xgz)
compressor=`which gzip || true`
grub_decompression_module="gzio"
compressor_opts="--best --stdout";;
xxz)
compressor=`which xz || true`
grub_decompression_module="xzio gcry_crc"
compressor_opts="--lzma2=dict=128KiB --check=none --stdout";;
xlzo)
compressor=`which lzop || true`
grub_decompression_module="lzopio adler32 gcry_crc"
compressor_opts="-9 -c";;
*)
gettext_printf "Unrecognized compression \`%s'\n" "$compress" 1>&2
usage
exit 1
esac
}
grub_process_install_options () {
option=$1
shift
grub_process_install_options_consumed=0
case "$option" in
--install-modules)
install_modules=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
--install-modules=*)
install_modules=`echo "$option" | sed 's/--install-modules=//'`; grub_process_install_options_consumed=1; return ;;
--themes)
install_themes=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
--themes=*)
install_themes=`echo "$option" | sed 's/--themes=//'`; grub_process_install_options_consumed=1; return ;;
--fonts)
install_fonts=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
--fonts=*)
install_fonts=`echo "$option" | sed 's/--fonts=//'`; grub_process_install_options_consumed=1; return ;;
--locales)
install_locales=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
--locales=*)
install_locales=`echo "$option" | sed 's/--locales=//'`; grub_process_install_options_consumed=1; return ;;
--compress)
grub_parse_compress `argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
--compress=*)
grub_parse_compress `echo "${option}" | sed 's/--compress=//'`; grub_process_install_options_consumed=1; return ;;
--directory | -d)
source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
--directory=*)
source_directory=`echo "$option" | sed 's/--directory=//'` grub_process_install_options_consumed=1;;
# For backwards compatibility
--override-directory)
source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
--override-directory=*)
source_directory=`echo "$option" | sed 's/--override-directory=//'` grub_process_install_options_consumed=1;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'`;grub_process_install_options_consumed=1 ;;
--modules)
modules=`argument $option "$@"`; grub_process_install_options_consumed=2;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` grub_process_install_options_consumed=1;;
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
esac
}
export grub_decompression_module

View file

@ -45,6 +45,7 @@
#include <grub/ia64/reloc.h> #include <grub/ia64/reloc.h>
#include <grub/osdep/hostfile.h> #include <grub/osdep/hostfile.h>
#include <grub/util/install.h> #include <grub/util/install.h>
#include <grub/emu/config.h>
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include <argp.h> #include <argp.h>
@ -83,7 +84,7 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused)))
switch (key) switch (key)
{ {
case 'd': case 'd':
return xasprintf (text, GRUB_PKGLIBDIR); return xasprintf (text, grub_util_get_pkglibdir ());
case 'p': case 'p':
return xasprintf (text, DEFAULT_DIRECTORY); return xasprintf (text, DEFAULT_DIRECTORY);
case 'O': case 'O':
@ -268,10 +269,12 @@ main (int argc, char *argv[])
if (!arguments.dir) if (!arguments.dir)
{ {
const char *dn = grub_util_get_target_dirname (arguments.image_target); const char *dn = grub_util_get_target_dirname (arguments.image_target);
arguments.dir = xmalloc (sizeof (GRUB_PKGLIBDIR) + grub_strlen (dn) + 1); const char *pkglibdir = grub_util_get_pkglibdir ();
memcpy (arguments.dir, GRUB_PKGLIBDIR, sizeof (GRUB_PKGLIBDIR) - 1); char *ptr;
*(arguments.dir + sizeof (GRUB_PKGLIBDIR) - 1) = '/'; arguments.dir = xmalloc (grub_strlen (pkglibdir) + grub_strlen (dn) + 2);
strcpy (arguments.dir + sizeof (GRUB_PKGLIBDIR), dn); ptr = grub_stpcpy (arguments.dir, pkglibdir);
*ptr++ = '/';
strcpy (ptr, dn);
} }
grub_install_generate_image (arguments.dir, grub_install_generate_image (arguments.dir,

212
util/grub-mknetdir.c Normal file
View file

@ -0,0 +1,212 @@
/*
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013 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/emu/config.h>
#include <grub/util/misc.h>
#include <argp.h>
#include <string.h>
#include <errno.h>
static char *rootdir = NULL, *subdir = NULL;
static char *debug_image = NULL;
enum
{
OPTION_NET_DIRECTORY = 0x301,
OPTION_SUBDIR,
OPTION_DEBUG,
OPTION_DEBUG_IMAGE
};
static struct argp_option options[] = {
GRUB_INSTALL_OPTIONS,
{"net-directory", OPTION_NET_DIRECTORY, N_("DIR"),
0, N_("root directory of TFTP server"), 2},
{"subdir", OPTION_SUBDIR, N_("DIR"),
0, N_("relative subdirectory on network server"), 2},
{"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
{"debug-image", OPTION_DEBUG_IMAGE, "DEBUG", OPTION_HIDDEN, 0, 2},
{0, 0, 0, 0, 0, 0}
};
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_NET_DIRECTORY:
free (rootdir);
rootdir = xstrdup (arg);
return 0;
case OPTION_SUBDIR:
free (subdir);
subdir = xstrdup (arg);
return 0;
/* This is an undocumented feature... */
case OPTION_DEBUG:
verbosity++;
return 0;
case OPTION_DEBUG_IMAGE:
free (debug_image);
debug_image = xstrdup (arg);
return 0;
case ARGP_KEY_ARG:
default:
return ARGP_ERR_UNKNOWN;
}
}
struct argp argp = {
options, argp_parser, N_("[OPTION]"),
"\v"N_("copies GRUB images into net_directory/subdir/target_cpu-platform."),
NULL, grub_install_help_filter, NULL
};
static char *base;
static const struct
{
const char *mkimage_target;
const char *netmodule;
const char *ext;
} targets[GRUB_INSTALL_PLATFORM_MAX] =
{
[GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" },
[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" },
[GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" },
[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" },
[GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
[GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
[GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
[GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }
};
static void
process_input_dir (const char *input_dir, enum grub_install_plat platform)
{
char *platsub = grub_install_get_platform_name (platform);
char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub);
char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg");
char *prefix;
char *output;
char *grub_cfg;
FILE *cfg;
grub_install_copy_files (input_dir, base, platform);
grub_util_unlink (load_cfg);
if (debug_image)
{
FILE *f = grub_util_fopen (load_cfg, "wb");
if (!f)
grub_util_error (_("cannot open `%s': %s"), load_cfg,
strerror (errno));
fprintf (f, "set debug='%s'\n", debug_image);
fclose (f);
}
else
{
free (load_cfg);
load_cfg = 0;
}
prefix = xasprintf ("/%s", subdir);
if (!targets[platform].mkimage_target)
grub_util_error ("unsupported platform %s\n", platsub);
grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
cfg = grub_util_fopen (grub_cfg, "wb");
if (!cfg)
grub_util_error (_("cannot open `%s': %s"), grub_cfg,
strerror (errno));
fprintf (cfg, "source %s/grub.cfg", subdir);
fclose (cfg);
grub_install_push_module (targets[platform].netmodule);
output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext);
grub_install_make_image_wrap (input_dir, prefix, output,
0, load_cfg,
targets[platform].mkimage_target, 0,
GRUB_COMPRESSION_AUTO);
grub_install_pop_module ();
/* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */
printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"),
platsub, output);
free (platsub);
free (output);
free (prefix);
free (grub_cfg);
free (grubdir);
}
int
main (int argc, char *argv[])
{
const char *pkgdatadir = grub_util_get_pkgdatadir ();
grub_util_host_init (&argc, &argv);
rootdir = xstrdup ("/srv/tftp");
subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME);
argp_parse (&argp, argc, argv, 0, 0, 0);
base = grub_util_path_concat (2, rootdir, subdir);
/* Create the GRUB directory if it is not present. */
grub_install_mkdir_p (base);
grub_install_push_module ("tftp");
if (!grub_install_source_directory)
{
enum grub_install_plat plat;
for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
if (targets[plat].mkimage_target)
{
char *platdir = grub_util_path_concat (2, pkgdatadir,
grub_install_get_platform_name (plat));
if (!grub_util_is_directory (platdir))
{
free (platdir);
continue;
}
process_input_dir (platdir, plat);
}
}
else
{
enum grub_install_plat plat;
plat = grub_install_get_target (grub_install_source_directory);
process_input_dir (grub_install_source_directory, plat);
}
return 0;
}

View file

@ -1,183 +0,0 @@
# Install GRUB on your drive.
# 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/>.
# Initialize some variables.
host_os=@host_os@
rootdir=/srv/tftp
modules=
no_floppy=
recheck=no
debug=no
debug_image=
subdir="`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`"
pc_dir="${libdir}/@PACKAGE@/i386-pc"
ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275"
sparc_dir="${libdir}/@PACKAGE@/sparc64-ieee1275"
i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275"
efi32_dir="${libdir}/@PACKAGE@/i386-efi"
efi64_dir="${libdir}/@PACKAGE@/x86_64-efi"
itanium_dir="${libdir}/@PACKAGE@/ia64-efi"
# Usage: usage
# Print the usage.
usage () {
gettext_printf "Usage: %s [OPTION]\n" "$self"
echo
print_option_help "-h, --help" "$(gettext "print this message and exit")"
grub_print_install_files_help
print_option_help "--net-directory=$(gettext "DIR")" "$(gettext "root directory of TFTP server")"
print_option_help "--subdir=$(gettext "DIR")" "$(gettext "relative subdirectory on network server")"
echo
gettext_printf "%s copies GRUB images into net_directory/subdir/target_cpu-platform\n" "$self"
echo
gettext "Report bugs to <bug-grub@gnu.org>."; echo
}
# Check the arguments.
while test $# -gt 0
do
grub_process_install_options "$@"
case "$grub_process_install_options_consumed" in
1) shift; continue;;
2) shift; shift; continue;;
esac
option=$1
shift
case "$option" in
-h | --help)
usage
exit 0 ;;
--net-directory)
rootdir=`argument $option "$@"`; shift;;
--net-directory=*)
rootdir=`echo "$option" | sed 's/--net-directory=//'` ;;
--subdir)
subdir=`argument $option "$@"`; shift;;
--subdir=*)
subdir=`echo "$option" | sed 's/--subdir=//'` ;;
# This is an undocumented feature...
--debug)
debug=yes ;;
--debug-image)
debug_image=`argument $option "$@"`; shift;;
--debug-image=*)
debug_image=`echo "$option" | sed 's/--debug-image=//'` ;;
-*)
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
usage
exit 1
;;
*)
gettext_printf "Unknown extra argument \`%s'." "$option" 1>&2
echo 1>&2
usage
exit 1
;;
esac
done
set $grub_mkimage dummy
if test -f "$1"; then
:
else
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
# Create the GRUB directory if it is not present.
mkdir -p "${rootdir}/${subdir}" || exit 1
process_input_dir ()
{
input_dir="$1"
platform="$2"
grubdir="${rootdir}/${subdir}/${platform}"
config_opt=
grub_install_files "${input_dir}" "${rootdir}/${subdir}" "${platform}"
rm -f "${grubdir}"/load.cfg
if [ "x${debug_image}" != x ]; then
echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
fi
prefix="/${subdir}";
case "${platform}" in
i386-pc) mkimage_target=i386-pc-pxe;
netmodules="pxe";
ext=0 ;;
sparc64-ieee1275) mkimage_target=sparc64-ieee1275-aout;
netmodules="ofnet";
ext=img ;;
*-ieee1275) mkimage_target="${platform}";
netmodules="ofnet";
ext=elf ;;
*-efi) mkimage_target="${platform}";
netmodules="efinet";
ext=efi ;;
*) gettext_printf "Unsupported platform %s\n" ${platform};
exit 1;;
esac
cat << EOF > ${grubdir}/grub.cfg
source ${subdir}/grub.cfg
EOF
"$grub_mkimage" ${config_opt} -d "${input_dir}" -O ${mkimage_target} "--output=${grubdir}/core.$ext" "--prefix=$prefix" $modules $grub_decompression_module $netmodules tftp || exit 1
# TRANSLATORS: First %s is replaced by platform name. Second one by filename.
gettext_printf "Netboot directory for %s created. Configure your DHCP server to point to %s\n" "${platform}" "${subdir}/${platform}/core.$ext"
}
if [ "${source_directory}" = "" ] ; then
if test -e "${pc_dir}" ; then
process_input_dir "${pc_dir}" i386-pc
fi
if test -e "${ppc_dir}" ; then
process_input_dir "${ppc_dir}" powerpc-ieee1275
fi
if test -e "${sparc_dir}" ; then
process_input_dir ${sparc_dir} sparc64-ieee1275
fi
if test -e "${i386_ieee1275_dir}" ; then
process_input_dir "${i386_ieee1275_dir}" i386-ieee1275
fi
if test -e "${efi32_dir}" ; then
process_input_dir "${efi32_dir}" i386-efi
fi
if test -e "${efi64_dir}" ; then
process_input_dir "${efi64_dir}" x86_64-efi
fi
if test -e "${itanium_dir}" ; then
process_input_dir "${itanium_dir}" ia64-efi
fi
else
. "${source_directory}"/modinfo.sh
process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform}
fi
# Bye.
exit 0

827
util/grub-mkrescue.c Normal file
View file

@ -0,0 +1,827 @@
/*
* 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 <argp.h>
#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}
};
static char *
help_filter (int key, const char *text, void *input __attribute__ ((unused)))
{
switch (key)
{
case ARGP_KEY_HELP_POST_DOC:
return xasprintf (text, "xorriso -as mkisofs -help");
default:
return grub_install_help_filter (key, text, input);
}
}
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..."),
/* TRANSLATORS: it generates one single image which is bootable through any method. */
N_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")"\v"
N_("Generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of `%s'.\n\n"
"Option -- switches to native xorriso command mode.\n\n"
"Mail xorriso support requests to <bug-xorriso@gnu.org>."),
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,
grub_compression_t compress)
{
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,
compress);
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,
grub_compression_t compress)
{
char *out = grub_util_path_concat (2, boot_grub, output_sub);
make_image_abs (plat, mkimage_target,
out, GRUB_COMPRESSION_AUTO);
free (out);
}
static void
make_image_fwdisk_abs (enum grub_install_plat plat,
const char *mkimage_target,
const char *output)
{
if (!source_dirs[plat])
return;
grub_install_push_module ("iso9660");
grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output,
0, 0, mkimage_target, 0,
GRUB_COMPRESSION_AUTO);
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);
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"));
xorriso_push (xorriso);
xorriso_push ("-as");
xorriso_push ("mkisofs");
xorriso_push ("-graft-points");
iso9660_dir = grub_util_make_temporary_dir ();
grub_util_info ("temporaray 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)
{
enum grub_install_plat plat;
for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
{
char *platdir = grub_util_path_concat (2, pkgdatadir,
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_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,
GRUB_COMPRESSION_AUTO);
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 (sysarea_img, "wb");
if (!bi)
grub_util_error (_("cannot open `%s': %s"), bin,
strerror (errno));
fread (buf, 1, 512, bi);
fclose (bi);
fwrite (buf, 1, 512, sa);
grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
"/boot/grub", output,
0, load_cfg,
"i386-pc", 0,
GRUB_COMPRESSION_AUTO);
sz = ftello (sa);
fflush (sa);
fsync (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_COMPRESSION_AUTO);
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", 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])
{
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);
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);
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);
img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi");
make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32);
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);
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);
}
make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf");
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],
"grub.chrp");
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");
out = grub_util_fopen (sysarea_img, "wb");
memset (buf, 0, 512);
fwrite (buf, 1, 512, out);
fread (buf, 1, 512, in);
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", GRUB_COMPRESSION_AUTO);
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf", GRUB_COMPRESSION_XZ);
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin", GRUB_COMPRESSION_XZ);
make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fulong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ);
make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf", GRUB_COMPRESSION_AUTO);
grub_install_push_module ("at_keyboard");
make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img", GRUB_COMPRESSION_AUTO);
grub_install_push_module ("ahci");
make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf", GRUB_COMPRESSION_AUTO);
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;
}

View file

@ -1,493 +0,0 @@
#!/bin/sh
# Make GRUB rescue image
# 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/>.
# Initialize some variables.
multiboot_dir="${libdir}/@PACKAGE@/i386-multiboot"
coreboot_dir="${libdir}/@PACKAGE@/i386-coreboot"
qemu_dir="${libdir}/@PACKAGE@/i386-qemu"
mipsel_qemu_dir="${libdir}/@PACKAGE@/mipsel-qemu_mips"
loongson_dir="${libdir}/@PACKAGE@/mipsel-loongson"
mips_qemu_dir="${libdir}/@PACKAGE@/mips-qemu_mips"
pc_dir="${libdir}/@PACKAGE@/i386-pc"
i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275"
efi32_dir="${libdir}/@PACKAGE@/i386-efi"
efi64_dir="${libdir}/@PACKAGE@/x86_64-efi"
ia64_dir="${libdir}/@PACKAGE@/ia64-efi"
sparc64_dir="${libdir}/@PACKAGE@/sparc64-ieee1275"
arcs_dir="${libdir}/@PACKAGE@/mips-arc"
arc_dir="${libdir}/@PACKAGE@/mipsel-arc"
ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275"
rom_directory=
grub_render_label="${bindir}/@grub_render_label@"
grub_glue_efi="${bindir}/@grub_glue_efi@"
label_font="${pkgdatadir}/unicode.pf2"
label_color="black"
label_bgcolor="white"
product_name="${PACKAGE_NAME}"
product_version="${PACKAGE_VERSION}"
xorriso=xorriso
# Usage: usage
# Print the usage.
usage () {
gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self"
# TRANSLATORS: it generates one single image which is bootable through any method.
gettext "Make GRUB CD-ROM, disk, pendrive and floppy bootable image."; echo
echo
filetrans="$(gettext FILE)"
print_option_help "-h, --help" "$(gettext "print this message and exit")"
print_option_help "-o, --output=$filetrans" "$(gettext "save output in FILE [required]")"
grub_print_install_files_help
print_option_help "--rom-directory=$(gettext "DIR")" "$(gettext "save ROM images in DIR [optional]")"
# TRANSLATORS: xorriso is a program for creating ISOs and burning CDs
print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")"
print_option_help "--grub-glue-efi=$filetrans" "$(gettext "use FILE as grub-glue-efi")"
print_option_help "--grub-render-label=$filetrans" "$(gettext "use FILE as grub-render-label")"
print_option_help "--label-font=$filetrans" "$(gettext "use FILE as font for label")"
print_option_help "--label-color=$(gettext "COLOR")" "$(gettext "use COLOR for label")"
print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")"
print_option_help "--product-name=$(gettext "STRING")" "$(gettext "use STRING as product name")"
print_option_help "--product-version=$(gettext "STRING")" "$(gettext "use STRING as product version")"
print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc")"
print_option_help "--arcs-boot" "$(gettext "enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc")"
echo
gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt
echo
gettext "Option -- switches to native xorriso command mode."; echo
echo
gettext "Report bugs to <bug-grub@gnu.org>."; echo
gettext "Mail xorriso support requests to <bug-xorriso@gnu.org>."; echo
}
system_area=auto
mkimage_extra_arg=
# Check the arguments.
while test $# -gt 0
do
grub_process_install_options "$@"
case "$grub_process_install_options_consumed" in
1) shift; continue;;
2) shift; shift; continue;;
esac
option=$1
shift
case "$option" in
-h | --help)
usage
exit 0 ;;
-o | --output)
output_image=`argument $option "$@"`; shift ;;
--output=*)
output_image=`echo "$option" | sed 's/--output=//'` ;;
--rom-directory)
rom_directory=`argument $option "$@"`; shift ;;
--rom-directory=*)
rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;;
# 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=//'`" ;;
--sparc-boot)
system_area=sparc64 ;;
--arcs-boot)
system_area=arcs ;;
--product-name)
product_name=`argument $option "$@"`; shift ;;
--product-name=*)
product_name=`echo "$option" | sed 's/--product-name=//'` ;;
--product-version)
product_version=`argument $option "$@"`; shift ;;
--product-version=*)
product_version=`echo "$option" | sed 's/--product-version=//'` ;;
--grub-glue-efi)
grub_glue_efi=`argument $option "$@"`; shift ;;
--grub-glue-efi=*)
grub_glue_efi=`echo "$option" | sed 's/--grub-glue-efi=//'` ;;
--grub-render-label)
grub_render_label=`argument $option "$@"`; shift ;;
--grub-render-label=*)
grub_render_label=`echo "$option" | sed 's/--grub-render-label=//'` ;;
--label-font)
label_font=`argument $option "$@"`; shift ;;
--label-font=*)
label_font=`echo "$option" | sed 's/--label-font=//'` ;;
--label-color)
label_color=`argument $option "$@"`; shift ;;
--label-color=*)
label_color=`echo "$option" | sed 's/--label-color=//'` ;;
--label-bgcolor)
label_bgcolor=`argument $option "$@"`; shift ;;
--label-bgcolor=*)
label_bgcolor=`echo "$option" | sed 's/--label-bgcolor=//'` ;;
--xorriso)
xorriso=`argument $option "$@"`; shift ;;
--xorriso=*)
xorriso=`echo "${option}" | sed 's/--xorriso=//'` ;;
*)
source="${source} ${option} $@"; break ;;
esac
done
if [ "x${output_image}" = x ] ; then
gettext "output file must be specified" >&2
echo >&2
usage
exit 1
fi
set $grub_mkimage dummy
if test -f "$1"; then
:
else
gettext_printf "%s: Not found.\n" "$1" 1>&2
exit 1
fi
iso9660_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
mkdir -p ${iso9660_dir}/boot/grub
mkdir -p ${iso9660_dir}/boot/grub/roms
process_input_dir ()
{
grub_install_files "$1" "${iso9660_dir}/boot/grub" "$2"
}
make_image ()
{
source_directory="$1"
platform=$2
if ! test -e "${source_directory}"; then
return;
fi
gettext_printf "Enabling %s support ...\n" "$2"
load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`"
(cat << EOF
search --fs-uuid --set=root ${iso_uuid}
set prefix=(\${root})/boot/grub
EOF
for i in $(cat "${source_directory}/partmap.lst") ${modules} ; do
echo "insmod $i"
done ; ) > "${load_cfg}"
"$grub_mkimage" -O ${platform} -d "${source_directory}" -c "${load_cfg}" -o "$3" \
$grub_decompression_module search iso9660 $4
rm -rf "${load_cfg}"
}
make_image_fwdisk ()
{
source_directory="$1"
platform=$2
if ! test -e "${source_directory}"; then
return;
fi
gettext_printf "Enabling %s support ...\n" "$2"
"$grub_mkimage" -O ${platform} -d "${source_directory}" -p '()/boot/grub' -o "$3" \
$grub_decompression_module iso9660 $4
}
if [ "${source_directory}" = "" ] ; then
if [ "$system_area" = auto ]; then
if test -e "${pc_dir}" || test -e "${ppc_dir}" \
|| test -e "${efi32_dir}" || test -e "${efi64_dir}"; then
system_area=common;
elif test -e "${sparc64_dir}" ; then
system_area=sparc64;
elif test -e "${arcs_dir}" ; then
system_area=arcs;
fi
fi
if test -e "${multiboot_dir}" ; then
process_input_dir "${multiboot_dir}" i386-multiboot
fi
if test -e "${coreboot_dir}" ; then
process_input_dir "${coreboot_dir}" i386-coreboot
fi
if test -e "${qemu_dir}" ; then
process_input_dir "${qemu_dir}" i386-qemu
fi
if test -e "${pc_dir}" ; then
process_input_dir "${pc_dir}" i386-pc
fi
if test -e "${i386_ieee1275_dir}" ; then
process_input_dir "${i386_ieee1275_dir}" i386-ieee1275
fi
if test -e "${efi32_dir}" ; then
process_input_dir "${efi32_dir}" i386-efi
fi
if test -e "${efi64_dir}" ; then
process_input_dir "${efi64_dir}" x86_64-efi
fi
if test -e "${ia64_dir}" ; then
process_input_dir "${ia64_dir}" ia64-efi
fi
if test -e "${mips_qemu_dir}" ; then
process_input_dir "${mips_qemu_dir}" mips-qemu_mips
fi
if test -e "${mipsel_qemu_dir}" ; then
process_input_dir "${mipsel_qemu_dir}" mipsel-qemu_mips
fi
if test -e "${loongson_dir}" ; then
process_input_dir "${loongson_dir}" mipsel-loongson
fi
if test -e "${ppc_dir}" ; then
process_input_dir "${ppc_dir}" powerpc-ieee1275
fi
if test -e "${sparc64_dir}" ; then
process_input_dir "${sparc64_dir}" sparc64-ieee1275
fi
if test -e "${arcs_dir}" ; then
process_input_dir "${arcs_dir}" mips-arc
fi
if test -e "${arc_dir}" ; then
process_input_dir "${arc_dir}" mipsel-arc
fi
else
. "${source_directory}"/modinfo.sh
process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform}
multiboot_dir=
pc_dir=
efi32_dir=
efi64_dir=
ia64_dir=
coreboot_dir=
qemu_dir=
mipsel_qemu_dir=
mips_qemu_dir=
loongson_dir=
ppc_dir=
i386_ieee1275_dir=
sparc64_dir=
arcs_dir=
arc_dir=
case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
i386-multiboot) multiboot_dir="${source_directory}" ;;
i386-coreboot) coreboot_dir="${source_directory}" ;;
i386-qemu) qemu_dir="${source_directory}" ;;
i386-pc) pc_dir="${source_directory}"; system_area=common;;
i386-efi) efi32_dir="${source_directory}"; system_area=common ;;
x86_64-efi) efi64_dir="${source_directory}"; system_area=common ;;
ia64-efi) ia64_dir="${source_directory}" ;;
mipsel-qemu_mips) mipsel_qemu_dir="${source_directory}" ;;
mipsel-loongson) loongson_dir="${source_directory}" ;;
mips-qemu_mips) mips_qemu_dir="${source_directory}" ;;
powerpc-ieee1275) ppc_dir="${source_directory}"; system_area=common ;;
sparc64-ieee1275) sparc64_dir="${source_directory}"; system_area=sparc64 ;;
mips-arc) arcs_dir="${source_directory}"; system_area=arcs ;;
mipsel-arc) arc_dir="${source_directory}" ;;
i386-ieee1275) i386_ieee1275_dir="${source_directory}" ;;
esac
fi
# obtain date-based UUID
iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00)
grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)"
# build BIOS core.img
if test -e "${pc_dir}" ; then
gettext_printf "Enabling %s support ...\n" "BIOS"
load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`"
core_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
(for i in $(cat "${pc_dir}/partmap.lst") ${modules} ; do
echo "insmod $i"
done ;) > "${load_cfg}"
"$grub_mkimage" -O i386-pc -d "${pc_dir}/" -o "${core_img}" -c "$load_cfg" --prefix=/boot/grub \
$grub_decompression_module iso9660 biosdisk
cat "${pc_dir}/cdboot.img" "${core_img}" > "${iso9660_dir}/boot/grub/i386-pc/eltorito.img"
grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table"
if [ "$system_area" = common ]; then
if "${xorriso}" -as mkisofs -help 2>&1 | fgrep "grub2-boot-info" >/dev/null; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} --grub2-boot-info --grub2-mbr ${pc_dir}/boot_hybrid.img"
else
gettext "Your xorriso doesn't support \`--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later."
echo
sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
cat "${pc_dir}/boot.img" "${core_img}" > "${sysarea_img}"
if [ "$(wc -c "${sysarea_img}" | awk '{ print $1; }')" -gt 32768 ]; then
gettext "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."
echo
else
grub_mkisofs_arguments="${grub_mkisofs_arguments} -G ${sysarea_img}"
fi
fi
fi
rm -f "${core_img}"
fi
# build multiboot core.img
make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/grub/i386-multiboot/core.elf" "pata ahci at_keyboard"
make_image_fwdisk "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/grub/ofwx86.elf" ""
if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; then
efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
mkdir -p "${efi_dir}/efi/boot"
# build bootia64.efi
make_image_fwdisk "${ia64_dir}" ia64-efi "${efi_dir}"/efi/boot/bootia64.efi ""
# build bootx64.efi
make_image_fwdisk "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi ""
# build bootia32.efi
make_image_fwdisk "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi ""
if [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
# For old macs. Suggested by Peter Jones.
cp "${efi_dir}"/efi/boot/bootia32.efi "${efi_dir}"/efi/boot/boot.efi
fi
if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] || [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
mkdir -p "${iso9660_dir}"/System/Library/CoreServices
fi
if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] && [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
"$grub_glue_efi" -6 "${efi_dir}"/efi/boot/bootx64.efi -3 "${efi_dir}"/efi/boot/bootia32.efi -o "${iso9660_dir}"/System/Library/CoreServices/boot.efi
elif [ -e "${efi_dir}"/efi/boot/bootx64.efi ]; then
cp "${efi_dir}"/efi/boot/bootx64.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi
elif [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
cp "${efi_dir}"/efi/boot/bootia32.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi
fi
mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img ::
mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/
rm -rf ${efi_dir}
grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img -efi-boot-part --efi-boot-image"
fi
make_image_fwdisk "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ""
if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ]; then
mkdir -p "${iso9660_dir}"/System/Library/CoreServices
touch "${iso9660_dir}/mach_kernel"
cat > "${iso9660_dir}/System/Library/CoreServices/SystemVersion.plist" <<EOF
<plist version="1.0">
<dict>
<key>ProductBuildVersion</key>
<string></string>
<key>ProductName</key>
<string>${product_name}</string>
<key>ProductVersion</key>
<string>${product_version}</string>
</dict>
</plist>
EOF
"$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label"
echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails"
if [ "$system_area" = common ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -apm-block-size 2048 -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label"
fi
fi
if [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ] ; then
cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX
mkdir -p "${iso9660_dir}"/ppc/chrp
cp "${ppc_dir}/bootinfo.txt" "${iso9660_dir}"/ppc/bootinfo.txt
grub_mkisofs_arguments="${grub_mkisofs_arguments} /System/Library/CoreServices/grub.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf /boot/grub/powerpc.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf"
# FIXME: add PreP
if [ "$system_area" = common ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices"
fi
grub_mkisofs_arguments="${grub_mkisofs_arguments} -sysid PPC"
fi
if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] && [ "$system_area" = common ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfs-bless-by i /System/Library/CoreServices/boot.efi"
fi
make_image_fwdisk "${sparc64_dir}" sparc64-ieee1275-cdcore "${iso9660_dir}/boot/grub/sparc64-ieee1275/core.img" ""
if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_area" = sparc64 ]; then
sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
dd if=/dev/zero count=1 bs=512 | cat - "${sparc64_dir}"/cdboot.img > "$sysarea_img"
grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img"
fi
make_image_fwdisk "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sash=${iso9660_dir}/boot/grub/mips-arc/core.img"
fi
if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arcs ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/sash -mips-boot /boot/grub/mips-arc/grub"
fi
make_image_fwdisk "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "pata"
if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf"
fi
make_image "${loongson_dir}" mipsel-loongson-elf "${iso9660_dir}/boot/grub/loongson.elf" "pata -C xz"
if [ -e "${iso9660_dir}/boot/grub/loongson.elf" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/loongson.elf" "${rom_directory}/mipsel-loongson.elf"
fi
make_image "${loongson_dir}" mipsel-yeeloong-flash "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "pata -C xz"
if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "${rom_directory}/mipsel-yeeloong.bin"
fi
make_image "${loongson_dir}" mipsel-fuloong2f-flash "${iso9660_dir}/boot/grub/roms/mipsel-fuloong2f.bin" "pata -C xz"
if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" "${rom_directory}/mipsel-fulong.bin"
fi
make_image "${mips_qemu_dir}" mips-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "pata"
if [ -e "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "${rom_directory}/mips-qemu_mips.elf"
fi
make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/grub/roms/qemu.img" "pata at_keyboard"
if [ -e "${iso9660_dir}/boot/grub/roms/qemu.img" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/qemu.img" "${rom_directory}/qemu.img"
fi
make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/grub/roms/coreboot.elf" "pata ahci at_keyboard"
if [ -e "${iso9660_dir}/boot/grub/roms/coreboot.elf" ] && [ -d "${rom_directory}" ]; then
cp "${iso9660_dir}/boot/grub/roms/coreboot.elf" "${rom_directory}/coreboot.elf"
fi
# build iso image
"${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o "${output_image}" -r "${iso9660_dir}" --sort-weight 0 / --sort-weight 1 /boot ${source}
rm -rf "${iso9660_dir}"
rm -f "${sysarea_img}"
exit 0

372
util/grub-mkstandalone.c Normal file
View file

@ -0,0 +1,372 @@
/*
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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/config.h>
#include <argp.h>
#include <string.h>
static grub_compression_t compression;
static char *output_image;
static char **files;
static int nfiles;
const struct grub_install_image_target_desc *format;
static FILE *memdisk;
enum
{
OPTION_OUTPUT = 'o',
OPTION_FORMAT = 'C',
OPTION_COMPRESION = 'C'
};
static struct argp_option options[] = {
GRUB_INSTALL_OPTIONS,
{"output", 'o', N_("FILE"),
0, N_("save output in FILE [required]"), 2},
{"format", 'O', N_("FILE"), 0, 0, 2},
{"compression", 'C', N_("xz|none|auto"),
0, N_("choose the compression to use for core image"), 2},
{0, 0, 0, 0, 0, 0}
};
static char *
help_filter (int key, const char *text, void *input __attribute__ ((unused)))
{
switch (key)
{
case 'O':
{
char *formats = grub_install_get_image_targets_string (), *ret;
ret = xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
_("available formats:"), formats);
free (formats);
return ret;
}
default:
return grub_install_help_filter (key, text, input);
}
}
static error_t
argp_parser (int key, char *arg, struct argp_state *state)
{
if (grub_install_parse (key, arg))
return 0;
switch (key)
{
case 'o':
if (output_image)
free (output_image);
output_image = xstrdup (arg);
break;
case 'O':
{
format = grub_install_get_image_target (arg);
if (!format)
{
printf (_("unknown target format %s\n"), arg);
argp_usage (state);
exit (1);
}
break;
}
case 'C':
if (grub_strcmp (arg, "xz") == 0)
{
#ifdef HAVE_LIBLZMA
compression = GRUB_COMPRESSION_XZ;
#else
grub_util_error ("%s",
_("grub-mkimage is compiled without XZ support"));
#endif
}
else if (grub_strcmp (arg, "none") == 0)
compression = GRUB_COMPRESSION_NONE;
else if (grub_strcmp (arg, "auto") == 0)
compression = GRUB_COMPRESSION_AUTO;
else
grub_util_error (_("Unknown compression format %s"), arg);
break;
case ARGP_KEY_ARG:
files[nfiles++] = xstrdup (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
struct argp argp = {
options, argp_parser, N_("[OPTION] SOURCE..."),
N_("Generate a standalone image (containing all modules) in the selected format")"\v"N_("Graft point syntax (E.g. /boot/grub/grub.cfg=./grub.cfg) is accepted"),
NULL, help_filter, NULL
};
/* tar support */
#define MAGIC "ustar"
struct head
{
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
char pad[12];
} __attribute__ ((packed));
static void
write_zeros (unsigned rsz)
{
char buf[512];
memset (buf, 0, 512);
fwrite (buf, 1, rsz, memdisk);
}
static void
write_pad (unsigned sz)
{
write_zeros ((~sz + 1) & 511);
}
static void
set_tar_value (char *field, grub_uint32_t val,
unsigned len)
{
unsigned i;
for (i = 0; i < len - 1; i++)
field[len - 2 - i] = '0' + ((val >> (3 * i)) & 7);
}
static void
compute_checksum (struct head *hd)
{
unsigned int chk = 0;
unsigned char *ptr;
memset (hd->chksum, ' ', 8);
for (ptr = (unsigned char *) hd; ptr < (unsigned char *) (hd + 1); ptr++)
chk += *ptr;
set_tar_value (hd->chksum, chk, 8);
}
static void
add_tar_file (const char *from,
const char *to)
{
char *tcn;
const char *iptr;
char *optr;
struct head hd;
grub_util_fd_t in;
ssize_t r;
grub_uint32_t mtime = 0;
grub_uint32_t size;
COMPILE_TIME_ASSERT (sizeof (hd) == 512);
if (grub_util_is_special_file (from))
return;
mtime = grub_util_get_mtime (from);
optr = tcn = xmalloc (strlen (to) + 1);
for (iptr = to; *iptr == '/'; iptr++);
for (; *iptr; iptr++)
if (!(iptr[0] == '/' && iptr[1] == '/'))
*optr++ = *iptr;
*optr = '\0';
if (grub_util_is_directory (from))
{
grub_util_fd_dir_t d;
grub_util_fd_dirent_t de;
d = grub_util_fd_opendir (from);
while ((de = grub_util_fd_readdir (d)))
{
char *fp, *tfp;
if (strcmp (de->d_name, ".") == 0)
continue;
if (strcmp (de->d_name, "..") == 0)
continue;
fp = grub_util_path_concat (2, from, de->d_name);
tfp = xasprintf ("%s/%s", to, de->d_name);
add_tar_file (fp, tfp);
free (fp);
}
grub_util_fd_closedir (d);
free (tcn);
return;
}
if (optr - tcn > 99)
{
memset (&hd, 0, sizeof (hd));
memcpy (hd.name, tcn, 99);
memcpy (hd.mode, "0000600", 7);
memcpy (hd.uid, "0001750", 7);
memcpy (hd.gid, "0001750", 7);
set_tar_value (hd.size, optr - tcn, 12);
set_tar_value (hd.mtime, mtime, 12);
hd.typeflag = 'L';
memcpy (hd.magic, "ustar ", 7);
memcpy (hd.uname, "grub", 4);
memcpy (hd.gname, "grub", 4);
compute_checksum (&hd);
fwrite (&hd, 1, sizeof (hd), memdisk);
fwrite (tcn, 1, optr - tcn, memdisk);
write_pad (optr - tcn);
}
in = grub_util_fd_open (from, GRUB_UTIL_FD_O_RDONLY);
if (!GRUB_UTIL_FD_IS_VALID (in))
grub_util_error (_("cannot open `%s': %s"), from, grub_util_fd_strerror ());
if (!grub_install_copy_buffer)
grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
size = grub_util_get_fd_size (in, from, NULL);
memset (&hd, 0, sizeof (hd));
memcpy (hd.name, tcn, optr - tcn < 99 ? optr - tcn : 99);
memcpy (hd.mode, "0000600", 7);
memcpy (hd.uid, "0001750", 7);
memcpy (hd.gid, "0001750", 7);
set_tar_value (hd.size, size, 12);
set_tar_value (hd.mtime, mtime, 12);
hd.typeflag = '0';
memcpy (hd.magic, "ustar ", 7);
memcpy (hd.uname, "grub", 4);
memcpy (hd.gname, "grub", 4);
compute_checksum (&hd);
fwrite (&hd, 1, sizeof (hd), memdisk);
while (1)
{
r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
if (r <= 0)
break;
fwrite (grub_install_copy_buffer, 1, r, memdisk);
}
grub_util_fd_close (in);
write_pad (size);
}
int
main (int argc, char *argv[])
{
const char *pkglibdir;
int i;
grub_util_host_init (&argc, &argv);
files = xmalloc ((argc + 1) * sizeof (files[0]));
argp_parse (&argp, argc, argv, 0, 0, 0);
pkglibdir = grub_util_get_pkglibdir ();
if (!output_image)
grub_util_error ("%s", _("output file must be specified"));
if (!format)
grub_util_error ("%s", _("Target format not specified (use the -O option)."));
if (!grub_install_source_directory)
grub_install_source_directory = grub_util_path_concat (2, pkglibdir, grub_util_get_target_dirname (format));
enum grub_install_plat plat = grub_install_get_target (grub_install_source_directory);
char *memdisk_dir = grub_util_make_temporary_dir ();
char *boot_grub = grub_util_path_concat (3, memdisk_dir, "boot", "grub");
grub_install_copy_files (grub_install_source_directory,
boot_grub, plat);
char *memdisk_img = grub_util_make_temporary_file ();
memdisk = grub_util_fopen (memdisk_img, "wb");
add_tar_file (memdisk_dir, "");
for (i = 0; i < nfiles; i++)
{
char *eq = grub_strchr (files[i], '=');
char *from, *to;
if (!eq)
{
from = files[i];
to = files[i];
}
else
{
*eq = '\0';
to = files[i];
from = eq + 1;
}
while (*to == '/')
to++;
add_tar_file (from, to);
}
write_zeros (512);
fclose (memdisk);
grub_util_unlink_recursive (memdisk_dir);
grub_install_push_module ("memdisk");
grub_install_push_module ("tar");
grub_install_make_image_wrap (grub_install_source_directory,
"(memdisk)/boot/grub", output_image,
memdisk_img, NULL,
grub_util_get_target_name (format), 0,
compression);
grub_util_unlink (memdisk_img);
return 0;
}

View file

@ -1,130 +0,0 @@
#!/bin/sh
# Make GRUB rescue image
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 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/>.
# Initialize some variables.
compression=auto
format=
source=
# Usage: usage
# Print the usage.
usage () {
formats="i386-coreboot i386-multiboot i386-pc i386-pc-pxe i386-efi i386-ieee1275 i386-qemu x86_64-efi mipsel-yeeloong-flash mipsel-fuloong2f-flash mipsel-loongson-elf powerpc-ieee1275 sparc64-ieee1275-raw sparc64-ieee1275-aout ia64-efi mips-arc mipsel-qemu_mips-elf mips-qemu_mips-flash mipsel-qemu_mips-flash mips-qemu_mips-elf"
gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self"
gettext "Generate a standalone image (containing all modules) in the selected format"
echo
print_option_help "-h, --help" "$(gettext "print this message and exit")"
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "save output in FILE [required]")"
print_option_help "-O, --format=$(gettext "FORMAT")" "$(gettext "generate an image in FORMAT")"; echo
print_option_help "" "$(gettext "available formats:") $formats"
echo
print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use for core image")"
grub_print_install_files_help
echo
gettext "Report bugs to <bug-grub@gnu.org>."; echo
}
# Check the arguments.
while test $# -gt 0
do
grub_process_install_options "$@"
case "$grub_process_install_options_consumed" in
1) shift; continue;;
2) shift; shift; continue;;
esac
option=$1
shift
case "$option" in
-h | --help)
usage
exit 0 ;;
-o | --output)
output_image=`argument $option "$@"`; shift ;;
--output=*)
output_image=`echo "$option" | sed 's/--output=//'` ;;
--compression | -C)
compression=`argument $option "$@"`; shift ;;
--compression=*)
compression=`echo "${option}" | sed 's/--compression=//'` ;;
--format | -O)
format=`argument $option "$@"`; shift ;;
--format=*)
format=`echo "${option}" | sed 's/--format=//'` ;;
*)
source="${source} ${option} $@"; break ;;
esac
done
if [ "x${output_image}" = x ] ; then
gettext "output file must be specified" >&2
echo >&2
usage
exit 1
fi
if [ "x${format}" = x ] ; then
gettext "Target format not specified (use the -O option)." >&2
echo >&2
exit 1
fi
if [ "x$source_directory" = x ] ; then
cpu="`echo $format | awk -F - '{ print $1; }'`"
platform="`echo $format | awk -F - '{ print $2; }'`"
case "$platform" in
yeeloong | fuloong | fuloong2f | fuloong2e)
platform=loongson ;;
esac
case "$cpu-$platform" in
mips-loongson)
cpu=mipsel ;;
esac
source_directory="${libdir}/@PACKAGE@/$cpu-$platform"
fi
. "${source_directory}"/modinfo.sh
set $grub_mkimage dummy
if test -f "$1"; then
:
else
echo "$1: Not found." 1>&2
exit 1
fi
memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
grub_install_files "${source_directory}" "${memdisk_dir}"/boot/grub "${grub_modinfo_target_cpu}-${grub_modinfo_platform}"
for file in $source; do
cp -f "$file" "${memdisk_dir}"/"$file";
done
memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
(cd "${memdisk_dir}"; tar -cf - * $source) > "${memdisk_img}"
rm -rf "${memdisk_dir}"
"$grub_mkimage" -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $grub_decompression_module $modules
rm -rf "${memdisk_img}"
exit 0

View file

@ -155,135 +155,6 @@ probe_raid_level (grub_disk_t disk)
return ((struct grub_diskfilter_lv *) disk->data)->segments->type; return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
} }
/* Since OF path names can have "," characters in them, and GRUB
internally uses "," to indicate partitions (unlike OF which uses
":" for this purpose) we escape such commas. */
static char *
escape_of_path (const char *orig_path)
{
char *new_path, *d, c;
const char *p;
if (!strchr (orig_path, ','))
return (char *) xstrdup (orig_path);
new_path = xmalloc (strlen (orig_path) * 2 + 1);
p = orig_path;
d = new_path;
while ((c = *p++) != '\0')
{
if (c == ',')
*d++ = '\\';
*d++ = c;
}
*d = 0;
return new_path;
}
static char *
guess_bios_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("hd%d", num);
}
if (ptr[0] == 'f' && ptr[1] == 'd')
{
int num = atoi (ptr + 2);
free (canon);
return xasprintf ("fd%d", num);
}
free (canon);
return NULL;
}
static char *
guess_efi_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("hd%d", num);
}
if (ptr[0] == 'f' && ptr[1] == 'd')
{
int num = atoi (ptr + 2);
free (canon);
return xasprintf ("fd%d", num);
}
free (canon);
return NULL;
}
static char *
guess_baremetal_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if (ptr[0] == 'h' && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("ata%d", num);
}
if (ptr[0] == 's' && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("ahci%d", num);
}
free (canon);
return NULL;
}
static void
print_full_name (const char *drive, grub_device_t dev)
{
char *dname = escape_of_path (drive);
if (dev->disk->partition)
{
char *pname = grub_partition_get_name (dev->disk->partition);
printf ("%s,%s", dname, pname);
free (pname);
}
else
printf ("%s", dname);
free (dname);
}
static void static void
probe_abstraction (grub_disk_t disk) probe_abstraction (grub_disk_t disk)
{ {
@ -513,34 +384,34 @@ probe (const char *path, char **device_names, char delim)
p = grub_stpcpy (tmp, "ieee1275/"); p = grub_stpcpy (tmp, "ieee1275/");
strcpy (p, ofpath); strcpy (p, ofpath);
printf ("--hint-ieee1275='"); printf ("--hint-ieee1275='");
print_full_name (tmp, dev); grub_util_fprint_full_disk_name (stdout, tmp, dev);
printf ("' "); printf ("' ");
free (tmp); free (tmp);
} }
biosname = guess_bios_drive (*curdev); biosname = grub_util_guess_bios_drive (*curdev);
if (biosname) if (biosname)
{ {
printf ("--hint-bios="); printf ("--hint-bios=");
print_full_name (biosname, dev); grub_util_fprint_full_disk_name (stdout, biosname, dev);
printf (" "); printf (" ");
} }
free (biosname); free (biosname);
efi = guess_efi_drive (*curdev); efi = grub_util_guess_efi_drive (*curdev);
if (efi) if (efi)
{ {
printf ("--hint-efi="); printf ("--hint-efi=");
print_full_name (efi, dev); grub_util_fprint_full_disk_name (stdout, efi, dev);
printf (" "); printf (" ");
} }
free (efi); free (efi);
bare = guess_baremetal_drive (*curdev); bare = grub_util_guess_baremetal_drive (*curdev);
if (bare) if (bare)
{ {
printf ("--hint-baremetal="); printf ("--hint-baremetal=");
print_full_name (bare, dev); grub_util_fprint_full_disk_name (stdout, bare, dev);
printf (" "); printf (" ");
} }
free (bare); free (bare);
@ -551,7 +422,7 @@ probe (const char *path, char **device_names, char delim)
if (map) if (map)
{ {
printf ("--hint='"); printf ("--hint='");
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
printf ("' "); printf ("' ");
} }
if (curdrive[1]) if (curdrive[1])
@ -568,7 +439,7 @@ probe (const char *path, char **device_names, char delim)
|| print == PRINT_EFI_HINT || print == PRINT_ARC_HINT) || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
&& dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID) && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
{ {
print_full_name (dev->disk->name, dev); grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev);
putchar (delim); putchar (delim);
continue; continue;
} }
@ -580,16 +451,16 @@ probe (const char *path, char **device_names, char delim)
map = grub_util_biosdisk_get_compatibility_hint (dev->disk); map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
if (map) if (map)
{ {
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
putchar (delim); putchar (delim);
grub_device_close (dev); grub_device_close (dev);
/* Compatibility hint is one device only. */ /* Compatibility hint is one device only. */
break; break;
} }
biosname = guess_bios_drive (*curdev); biosname = grub_util_guess_bios_drive (*curdev);
if (biosname) if (biosname)
{ {
print_full_name (biosname, dev); grub_util_fprint_full_disk_name (stdout, biosname, dev);
putchar (delim); putchar (delim);
} }
free (biosname); free (biosname);
@ -603,10 +474,10 @@ probe (const char *path, char **device_names, char delim)
if (print == PRINT_BIOS_HINT) if (print == PRINT_BIOS_HINT)
{ {
char *biosname; char *biosname;
biosname = guess_bios_drive (*curdev); biosname = grub_util_guess_bios_drive (*curdev);
if (biosname) if (biosname)
{ {
print_full_name (biosname, dev); grub_util_fprint_full_disk_name (stdout, biosname, dev);
putchar (delim); putchar (delim);
} }
free (biosname); free (biosname);
@ -622,7 +493,7 @@ probe (const char *path, char **device_names, char delim)
map = grub_util_biosdisk_get_compatibility_hint (dev->disk); map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
if (map) if (map)
{ {
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
putchar (delim); putchar (delim);
} }
@ -632,7 +503,7 @@ probe (const char *path, char **device_names, char delim)
char *p; char *p;
p = grub_stpcpy (tmp, "ieee1275/"); p = grub_stpcpy (tmp, "ieee1275/");
strcpy (p, ofpath); strcpy (p, ofpath);
print_full_name (tmp, dev); grub_util_fprint_full_disk_name (stdout, tmp, dev);
free (tmp); free (tmp);
putchar (delim); putchar (delim);
} }
@ -644,17 +515,17 @@ probe (const char *path, char **device_names, char delim)
{ {
char *biosname; char *biosname;
const char *map; const char *map;
biosname = guess_efi_drive (*curdev); biosname = grub_util_guess_efi_drive (*curdev);
map = grub_util_biosdisk_get_compatibility_hint (dev->disk); map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
if (map) if (map)
{ {
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
putchar (delim); putchar (delim);
} }
if (biosname) if (biosname)
{ {
print_full_name (biosname, dev); grub_util_fprint_full_disk_name (stdout, biosname, dev);
putchar (delim); putchar (delim);
} }
@ -668,17 +539,17 @@ probe (const char *path, char **device_names, char delim)
char *biosname; char *biosname;
const char *map; const char *map;
biosname = guess_baremetal_drive (*curdev); biosname = grub_util_guess_baremetal_drive (*curdev);
map = grub_util_biosdisk_get_compatibility_hint (dev->disk); map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
if (map) if (map)
{ {
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
putchar (delim); putchar (delim);
} }
if (biosname) if (biosname)
{ {
print_full_name (biosname, dev); grub_util_fprint_full_disk_name (stdout, biosname, dev);
putchar (delim); putchar (delim);
} }
@ -694,7 +565,7 @@ probe (const char *path, char **device_names, char delim)
map = grub_util_biosdisk_get_compatibility_hint (dev->disk); map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
if (map) if (map)
{ {
print_full_name (map, dev); grub_util_fprint_full_disk_name (stdout, map, dev);
putchar (delim); putchar (delim);
} }

View file

@ -40,7 +40,7 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/script_sh.h> #include <grub/script_sh.h>
#include <grub/osdep/hostfile.h> #include <grub/emu/hostfile.h>
#define ENABLE_RELOCATABLE 0 #define ENABLE_RELOCATABLE 0
#ifdef GRUB_BUILD #ifdef GRUB_BUILD
@ -256,15 +256,3 @@ void
grub_register_exported_symbols (void) grub_register_exported_symbols (void)
{ {
} }
#ifdef GRUB_UTIL
void
grub_util_init_nls (void)
{
#if (defined(ENABLE_NLS) && ENABLE_NLS)
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
}
#endif

View file

@ -66,7 +66,7 @@ struct grub_install_image_target_desc
IMAGE_I386_IEEE1275, IMAGE_I386_IEEE1275,
IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
} id; } id;
enum enum
{ {
@ -174,6 +174,22 @@ static const struct grub_install_image_target_desc image_targets[] =
.link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
.default_compression = GRUB_COMPRESSION_LZMA .default_compression = GRUB_COMPRESSION_LZMA
}, },
{
.dirname = "i386-pc",
.names = { "i386-pc-eltorito", NULL },
.voidp_sizeof = 4,
.bigendian = 0,
.id = IMAGE_I386_PC_ELTORITO,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
.total_module_size = TARGET_NO_FIELD,
.decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
.decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
.decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
.default_compression = GRUB_COMPRESSION_LZMA
},
{ {
.dirname = "i386-efi", .dirname = "i386-efi",
.names = { "i386-efi", NULL }, .names = { "i386-efi", NULL },
@ -826,6 +842,12 @@ grub_util_get_target_dirname (const struct grub_install_image_target_desc *t)
return t->dirname; return t->dirname;
} }
const char *
grub_util_get_target_name (const struct grub_install_image_target_desc *t)
{
return t->names[0];
}
char * char *
grub_install_get_image_targets_string (void) grub_install_get_image_targets_string (void)
{ {
@ -874,7 +896,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
comp = image_target->default_compression; comp = image_target->default_compression;
if (image_target->id == IMAGE_I386_PC if (image_target->id == IMAGE_I386_PC
|| image_target->id == IMAGE_I386_PC_PXE) || image_target->id == IMAGE_I386_PC_PXE
|| image_target->id == IMAGE_I386_PC_ELTORITO)
comp = GRUB_COMPRESSION_LZMA; comp = GRUB_COMPRESSION_LZMA;
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
@ -1105,7 +1128,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
decompress_img = grub_util_read_image (decompress_path); decompress_img = grub_util_read_image (decompress_path);
if ((image_target->id == IMAGE_I386_PC if ((image_target->id == IMAGE_I386_PC
|| image_target->id == IMAGE_I386_PC_PXE) || image_target->id == IMAGE_I386_PC_PXE
|| image_target->id == IMAGE_I386_PC_ELTORITO)
&& decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
grub_util_error ("%s", _("Decompressor is too big")); grub_util_error ("%s", _("Decompressor is too big"));
@ -1149,6 +1173,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
{ {
case IMAGE_I386_PC: case IMAGE_I386_PC:
case IMAGE_I386_PC_PXE: case IMAGE_I386_PC_PXE:
case IMAGE_I386_PC_ELTORITO:
if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
|| (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
|| (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)) || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
@ -1185,6 +1210,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
{ {
case IMAGE_I386_PC: case IMAGE_I386_PC:
case IMAGE_I386_PC_PXE: case IMAGE_I386_PC_PXE:
case IMAGE_I386_PC_ELTORITO:
{ {
unsigned num; unsigned num;
char *boot_path, *boot_img; char *boot_path, *boot_img;
@ -1219,6 +1245,21 @@ grub_install_generate_image (const char *dir, const char *prefix,
} }
} }
if (image_target->id == IMAGE_I386_PC_ELTORITO)
{
char *eltorito_path, *eltorito_img;
size_t eltorito_size;
eltorito_path = grub_util_get_path (dir, "cdboot.img");
eltorito_size = grub_util_get_image_size (eltorito_path);
eltorito_img = grub_util_read_image (eltorito_path);
grub_util_write_image (eltorito_img, eltorito_size, out,
outname);
free (eltorito_img);
free (eltorito_path);
}
boot_path = grub_util_get_path (dir, "diskboot.img"); boot_path = grub_util_get_path (dir, "diskboot.img");
boot_size = grub_util_get_image_size (boot_path); boot_size = grub_util_get_image_size (boot_path);
if (boot_size != GRUB_DISK_SECTOR_SIZE) if (boot_size != GRUB_DISK_SECTOR_SIZE)
@ -1764,6 +1805,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
grub_util_write_image (core_img, core_size, out, outname); grub_util_write_image (core_img, core_size, out, outname);
free (core_img); free (core_img);
free (kernel_path); free (kernel_path);
free (rel_section);
while (path_list) while (path_list)
{ {

172
util/probe.c Normal file
View file

@ -0,0 +1,172 @@
/* grub-probe.c - probe device information for a given path */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2006,2007,2008,2009,2010,2013 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/types.h>
#include <grub/emu/misc.h>
#include <grub/util/misc.h>
#include <grub/device.h>
#include <grub/disk.h>
#include <grub/file.h>
#include <grub/fs.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/gpt_partition.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/term.h>
#include <grub/env.h>
#include <grub/diskfilter.h>
#include <grub/i18n.h>
#include <grub/emu/misc.h>
#include <grub/util/ofpath.h>
#include <grub/crypto.h>
#include <grub/cryptodisk.h>
#include <string.h>
/* Since OF path names can have "," characters in them, and GRUB
internally uses "," to indicate partitions (unlike OF which uses
":" for this purpose) we escape such commas. */
static char *
escape_of_path (const char *orig_path)
{
char *new_path, *d, c;
const char *p;
if (!strchr (orig_path, ','))
return (char *) xstrdup (orig_path);
new_path = xmalloc (strlen (orig_path) * 2 + 1);
p = orig_path;
d = new_path;
while ((c = *p++) != '\0')
{
if (c == ',')
*d++ = '\\';
*d++ = c;
}
*d = 0;
return new_path;
}
char *
grub_util_guess_bios_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("hd%d", num);
}
if (ptr[0] == 'f' && ptr[1] == 'd')
{
int num = atoi (ptr + 2);
free (canon);
return xasprintf ("fd%d", num);
}
free (canon);
return NULL;
}
char *
grub_util_guess_efi_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("hd%d", num);
}
if (ptr[0] == 'f' && ptr[1] == 'd')
{
int num = atoi (ptr + 2);
free (canon);
return xasprintf ("fd%d", num);
}
free (canon);
return NULL;
}
char *
grub_util_guess_baremetal_drive (const char *orig_path)
{
char *canon;
char *ptr;
canon = canonicalize_file_name (orig_path);
if (!canon)
return NULL;
ptr = strrchr (orig_path, '/');
if (ptr)
ptr++;
else
ptr = canon;
if (ptr[0] == 'h' && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("ata%d", num);
}
if (ptr[0] == 's' && ptr[1] == 'd')
{
int num = ptr[2] - 'a';
free (canon);
return xasprintf ("ahci%d", num);
}
free (canon);
return NULL;
}
void
grub_util_fprint_full_disk_name (FILE *f,
const char *drive, grub_device_t dev)
{
char *dname = escape_of_path (drive);
if (dev->disk->partition)
{
char *pname = grub_partition_get_name (dev->disk->partition);
fprintf (f, "%s,%s", dname, pname);
free (pname);
}
else
fprintf (f, "%s", dname);
free (dname);
}