]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Implement grub_file tool and use it to implement generating of config
authorVladimir Serbinenko <phcoder@gmail.com>
Tue, 17 Dec 2013 13:39:48 +0000 (14:39 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Tue, 17 Dec 2013 13:39:48 +0000 (14:39 +0100)
in separate root.

26 files changed:
ChangeLog
Makefile.util.def
configure.ac
docs/man/grub-file.h2m [new file with mode: 0644]
grub-core/Makefile.core.def
grub-core/commands/file.c [new file with mode: 0644]
grub-core/commands/file32.c [new file with mode: 0644]
grub-core/commands/file64.c [new file with mode: 0644]
grub-core/commands/fileXX.c [new file with mode: 0644]
grub-core/io/xzio.c
grub-core/loader/i386/linux.c
grub-core/loader/i386/xen_file.c
include/grub/elf.h
include/grub/fileid.h [new file with mode: 0644]
util/grub-file.c [new file with mode: 0644]
util/grub-mkconfig.in
util/grub-mkconfig_lib.in
util/grub-pe2elf.c
util/grub.d/00_header.in
util/grub.d/10_hurd.in
util/grub.d/10_illumos.in
util/grub.d/10_kfreebsd.in
util/grub.d/10_linux.in
util/grub.d/10_netbsd.in
util/grub.d/10_xnu.in
util/grub.d/20_linux_xen.in

index b24b9eb352444fed934e1cef0ef0e99ce0972bce..d84b0aca399c068719d6006d495d2c49f09213a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Implement grub_file tool and use it to implement generating of config
+       in separate root.
+
 2013-12-17  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Change to v1 xen grants.
index 4701917006c1588dbd7394ebcf4a3be1b0c855e2..2720f6bd3c63d5c9f10587e80321c44bc105339b 100644 (file)
@@ -154,6 +154,7 @@ library = {
   common = grub-core/script/script.c;
   common = grub-core/script/argv.c;
   common = grub-core/io/gzio.c;
+  common = grub-core/io/xzio.c;
   common = grub-core/io/lzopio.c;
   common = grub-core/kern/ia64/dl_helper.c;
   common = grub-core/kern/arm/dl_helper.c;
@@ -422,49 +423,42 @@ script = {
   name = '10_hurd';
   common = util/grub.d/10_hurd.in;
   installdir = grubconf;
-  condition = COND_HOST_HURD;
 };
 
 script = {
   name = '10_kfreebsd';
   common = util/grub.d/10_kfreebsd.in;
   installdir = grubconf;
-  condition = COND_HOST_KFREEBSD;
 };
 
 script = {
   name = '10_illumos';
   common = util/grub.d/10_illumos.in;
   installdir = grubconf;
-  condition = COND_HOST_ILLUMOS;
 };
 
 script = {
   name = '10_netbsd';
   common = util/grub.d/10_netbsd.in;
   installdir = grubconf;
-  condition = COND_HOST_NETBSD;
 };
 
 script = {
   name = '10_linux';
   common = util/grub.d/10_linux.in;
   installdir = grubconf;
-  condition = COND_HOST_LINUX;
 };
 
 script = {
   name = '10_xnu';
   common = util/grub.d/10_xnu.in;
   installdir = grubconf;
-  condition = COND_HOST_XNU;
 };
 
 script = {
   name = '20_linux_xen';
   common = util/grub.d/20_linux_xen.in;
   installdir = grubconf;
-  condition = COND_HOST_LINUX;
 };
 
 script = {
@@ -1255,3 +1249,32 @@ program = {
   ldadd = grub-core/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
+
+program = {
+  name = grub-file;
+  mansection = 1;
+
+  common = util/grub-file.c;
+  common = util/render-label.c;
+  common = grub-core/commands/file.c;
+  common = grub-core/commands/file32.c;
+  common = grub-core/commands/file64.c;
+  common = grub-core/loader/i386/xen_file.c;
+  common = grub-core/loader/i386/xen_file32.c;
+  common = grub-core/loader/i386/xen_file64.c;
+  common = grub-core/io/offset.c;
+  common = grub-core/kern/elf.c;
+  common = grub-core/loader/lzss.c;
+  common = grub-core/loader/macho.c;
+  common = grub-core/loader/macho32.c;
+  common = grub-core/loader/macho64.c;
+  common = grub-core/kern/emu/hostfs.c;
+  common = grub-core/disk/host.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+};
index e803b2a1a8c36fdb26bdb9470b0660d73cfbf407..dfb4f69ce3b731d1413cdcb4ef6592e4f6846891 100644 (file)
@@ -69,6 +69,7 @@ grub_TRANSFORM([grub-script-check])
 grub_TRANSFORM([grub-set-default])
 grub_TRANSFORM([grub-sparc64-setup])
 grub_TRANSFORM([grub-render-label])
+grub_TRANSFORM([grub-file])
 
 # Optimization flag.  Allow user to override.
 if test "x$TARGET_CFLAGS" = x; then
@@ -1608,13 +1609,7 @@ AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
 AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
 AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
 
-AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
-AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
-AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd])
 AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows])
-AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd])
-AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu])
-AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos])
 
 AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x])
 AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes])
diff --git a/docs/man/grub-file.h2m b/docs/man/grub-file.h2m
new file mode 100644 (file)
index 0000000..e09bb4d
--- /dev/null
@@ -0,0 +1,2 @@
+[NAME]
+grub-file \- check file type
index e7e38a8533726152ca9385d26668180a12525439..3d70d0241ff067ea515d7ffe8a24d25c990da8cf 100644 (file)
@@ -1659,10 +1659,6 @@ module = {
   name = linux;
   x86 = loader/i386/linux.c;
   xen = loader/i386/xen.c;
-  xen = loader/i386/xen_file.c;
-  xen = loader/i386/xen_file32.c;
-  xen = loader/i386/xen_file64.c;
-  extra_dist = loader/i386/xen_fileXX.c;
   xen_cppflags    = '$(CPPFLAGS_XEN)';
   i386_pc = lib/i386/pc/vesa_modes_table.c;
   mips = loader/mips/linux.c;
@@ -1680,16 +1676,21 @@ module = {
   name = xnu;
   x86 = loader/xnu_resume.c;
   x86 = loader/i386/xnu.c;
-  x86 = loader/macho32.c;
-  x86 = loader/macho64.c;
-  x86 = loader/macho.c;
   x86 = loader/xnu.c;
-  x86 = loader/lzss.c;
 
-  extra_dist = loader/machoXX.c;
   enable = x86;
 };
 
+module = {
+  name = macho;
+
+  common = loader/macho.c;
+  common = loader/macho32.c;
+  common = loader/macho64.c;
+  common = loader/lzss.c;
+  extra_dist = loader/machoXX.c;
+};
+
 module = {
   name = appleldr;
   common = loader/efi/appleloader.c;
@@ -2269,3 +2270,15 @@ module = {
   name = progress;
   common = lib/progress.c;
 };
+
+module = {
+  name = file;
+  common = commands/file.c;
+  common = commands/file32.c;
+  common = commands/file64.c;
+  extra_dist = commands/fileXX.c;
+  common = loader/i386/xen_file.c;
+  common = loader/i386/xen_file32.c;
+  common = loader/i386/xen_file64.c;
+  extra_dist = loader/i386/xen_fileXX.c;
+};
diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c
new file mode 100644 (file)
index 0000000..c27df0c
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ *  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/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/file.h>
+#include <grub/elf.h>
+#include <grub/xen_file.h>
+#include <grub/efi/pe32.h>
+#include <grub/i386/linux.h>
+#include <grub/xnu.h>
+#include <grub/machoload.h>
+#include <grub/fileid.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const struct grub_arg_option options[] = {
+  {"is-i386-xen-pae-domu", 0, 0,
+   N_("Check if FILE can be booted as i386 PAE xen unprivilegied guest"),
+   0, 0},
+  {"is-x86_64-xen-domu", 0, 0,
+   N_("Check if FILE can be booted as x86_64 xen unprivilegied guest"), 0, 0},
+  {"is-x86-xen-dom0", 0, 0,
+   N_("Check if FILE can be used as xen x86 privilegied guest kernel"), 0, 0},
+  {"is-x86-multiboot", 0, 0,
+   N_("Check if FILE can be used as x86 multiboot kernel"), 0, 0},
+  {"is-x86-multiboot2", 0, 0,
+   N_("Check if FILE can be used as x86 multiboot2 kernel"), 0, 0},
+  {"is-arm-linux", 0, 0,
+   N_("Check if FILE is ARM linux"), 0, 0},
+  {"is-ia64-linux", 0, 0,
+   N_("Check if FILE is IA64 linux"), 0, 0},
+  {"is-mips-linux", 0, 0,
+   N_("Check if FILE is MIPS linux"), 0, 0},
+  {"is-mipsel-linux", 0, 0,
+   N_("Check if FILE is MIPSEL linux"), 0, 0},
+  {"is-sparc64-linux", 0, 0,
+   N_("Check if FILE is SPARC64 linux"), 0, 0},
+  {"is-powerpc-linux", 0, 0,
+   N_("Check if FILE is POWERPC linux"), 0, 0},
+  {"is-x86-linux", 0, 0,
+   N_("Check if FILE is x86 linux"), 0, 0},
+  {"is-x86-linux32", 0, 0,
+   N_("Check if FILE is x86 linux supporting 32-bit protocol"), 0, 0},
+  {"is-x86-kfreebsd", 0, 0,
+   N_("Check if FILE is x86 kfreebsd"), 0, 0},
+  {"is-i386-kfreebsd", 0, 0,
+   N_("Check if FILE is i386 kfreebsd"), 0, 0},
+  {"is-x86_64-kfreebsd", 0, 0,
+   N_("Check if FILE is x86_64 kfreebsd"), 0, 0},
+
+  {"is-x86-knetbsd", 0, 0,
+   N_("Check if FILE is x86 knetbsd"), 0, 0},
+  {"is-i386-knetbsd", 0, 0,
+   N_("Check if FILE is i386 knetbsd"), 0, 0},
+  {"is-x86_64-knetbsd", 0, 0,
+   N_("Check if FILE is x86_64 knetbsd"), 0, 0},
+
+  {"is-i386-efi", 0, 0,
+   N_("Check if FILE is i386 EFI file"), 0, 0},
+  {"is-x86_64-efi", 0, 0,
+   N_("Check if FILE is x86-64 EFI file"), 0, 0},
+  {"is-ia64-efi", 0, 0,
+   N_("Check if FILE is IA64 EFI file"), 0, 0},
+  {"is-arm-efi", 0, 0,
+   N_("Check if FILE is ARM EFI file"), 0, 0},
+  {"is-hibernated-hiberfil", 0, 0,
+   N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0},
+  {"is-x86_64-xnu", 0, 0,
+   N_("Check if FILE is x86_64 xnu (Mac OS X kernel)"), 0, 0},
+  {"is-i386-xnu", 0, 0,
+   N_("Check if FILE is i386 xnu (Mac OS X kernel)"), 0, 0},
+  {"is-xnu-hibr", 0, 0,
+   N_("Check if FILE is xnu (Mac OS X kernel) hibernated image"), 0, 0},
+  {"is-x86-bios-bootsector", 0, 0,
+   N_("Check if FILE is BIOS bootsector"), 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
+enum
+{
+  IS_PAE_DOMU,
+  IS_64_DOMU,
+  IS_DOM0,
+  IS_MULTIBOOT,
+  IS_MULTIBOOT2,
+  IS_ARM_LINUX,
+  IS_IA64_LINUX,
+  IS_MIPS_LINUX,
+  IS_MIPSEL_LINUX,
+  IS_SPARC64_LINUX,
+  IS_POWERPC_LINUX,
+  IS_X86_LINUX,
+  IS_X86_LINUX32,
+  IS_X86_KFREEBSD,
+  IS_X86_KFREEBSD32,
+  IS_X86_KFREEBSD64,
+  IS_X86_KNETBSD,
+  IS_X86_KNETBSD32,
+  IS_X86_KNETBSD64,
+  IS_32_EFI,
+  IS_64_EFI,
+  IS_IA_EFI,
+  IS_ARM_EFI,
+  IS_HIBERNATED,
+  IS_XNU64,
+  IS_XNU32,
+  IS_XNU_HIBR,
+  IS_BIOS_BOOTSECTOR,
+  OPT_TYPE_MIN = IS_PAE_DOMU,
+  OPT_TYPE_MAX = IS_BIOS_BOOTSECTOR
+};
+
+
+static grub_err_t
+grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
+{
+  grub_file_t file = 0;
+  grub_elf_t elf = 0;
+  grub_err_t err;
+  int type = -1, i;
+  int ret = 0;
+  grub_macho_t macho = 0;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+  for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++)
+    if (ctxt->state[i].set)
+      {
+       if (type == -1)
+         {
+           type = i;
+           continue;
+         }
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple types specified");
+      }
+  if (type == -1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified");
+
+  file = grub_file_open (args[0]);
+  if (!file)
+    return grub_errno;
+  switch (type)
+    {
+    case IS_BIOS_BOOTSECTOR:
+      {
+       grub_uint16_t sig;
+       if (grub_file_size (file) != 512)
+         break;
+       if (grub_file_seek (file, 510) == (grub_size_t) -1)
+         break;
+       if (grub_file_read (file, &sig, 2) != 2)
+         break;
+       if (sig != grub_cpu_to_le16_compile_time (0xaa55))
+         break;
+       ret = 1;
+       break;
+      }
+    case IS_IA64_LINUX:
+      {
+       Elf64_Ehdr ehdr;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
+           || ehdr.e_ident[EI_DATA] != ELFDATA2LSB
+           || ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_IA_64))
+         break;
+
+       ret = 1;
+
+       break;
+      }
+
+    case IS_SPARC64_LINUX:
+      {
+       Elf64_Ehdr ehdr;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
+           || ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
+         break;
+
+       if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_SPARCV9)
+           || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
+         break;
+
+       ret = 1;
+
+       break;
+      }
+
+    case IS_POWERPC_LINUX:
+      {
+       Elf32_Ehdr ehdr;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
+           || (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC)
+               && ehdr.e_machine !=
+               grub_cpu_to_le16_compile_time (EM_PPC64)))
+         break;
+
+       if (ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)
+           && ehdr.e_type != grub_cpu_to_be16_compile_time (ET_DYN))
+         break;
+
+       ret = 1;
+
+       break;
+      }
+
+    case IS_MIPS_LINUX:
+      {
+       Elf32_Ehdr ehdr;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
+           || ehdr.e_machine != grub_cpu_to_be16_compile_time (EM_MIPS)
+           || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
+         break;
+
+       ret = 1;
+
+       break;
+      }
+
+    case IS_X86_KNETBSD:
+    case IS_X86_KNETBSD32:
+    case IS_X86_KNETBSD64:
+      {
+       int is32, is64;
+
+       elf = grub_elf_file (file, file->name);
+
+       if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
+           || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB)
+         break;
+
+       is32 = grub_elf_is_elf32 (elf);
+       is64 = grub_elf_is_elf64 (elf);
+       if (!is32 && !is64)
+         break;
+       if (!is32 && type == IS_X86_KNETBSD32)
+         break;
+       if (!is64 && type == IS_X86_KNETBSD64)
+         break;
+       if (is64)
+         ret = grub_file_check_netbsd64 (elf);
+       if (is32)
+         ret = grub_file_check_netbsd32 (elf);
+       break;
+      }
+
+    case IS_X86_KFREEBSD:
+    case IS_X86_KFREEBSD32:
+    case IS_X86_KFREEBSD64:
+      {
+       Elf32_Ehdr ehdr;
+       int is32, is64;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
+           || ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
+         break;
+
+       if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
+         break;
+
+       is32 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_386)
+               && ehdr.e_ident[EI_CLASS] == ELFCLASS32);
+       is64 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_X86_64)
+               && ehdr.e_ident[EI_CLASS] == ELFCLASS64);
+       if (!is32 && !is64)
+         break;
+       if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32))
+         break;
+       if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64))
+         break;
+       ret = 1;
+
+       break;
+      }
+
+
+    case IS_MIPSEL_LINUX:
+      {
+       Elf32_Ehdr ehdr;
+
+       if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
+         break;
+
+       if (ehdr.e_ident[EI_MAG0] != ELFMAG0
+           || ehdr.e_ident[EI_MAG1] != ELFMAG1
+           || ehdr.e_ident[EI_MAG2] != ELFMAG2
+           || ehdr.e_ident[EI_MAG3] != ELFMAG3
+           || ehdr.e_ident[EI_VERSION] != EV_CURRENT
+           || ehdr.e_version != EV_CURRENT)
+         break;
+
+       if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_MIPS)
+           || ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC))
+         break;
+
+       ret = 1;
+
+       break;
+      }
+    case IS_ARM_LINUX:
+      {
+       grub_uint32_t sig;
+       if (grub_file_seek (file, 0x24) == (grub_size_t) -1)
+         break;
+       if (grub_file_read (file, &sig, 4) != 4)
+         break;
+       if (sig != grub_cpu_to_le32_compile_time (0x016f2818))
+         break;
+       ret = 1;
+       break;
+      }
+    case IS_PAE_DOMU ... IS_DOM0:
+      {
+       struct grub_xen_file_info xen_inf;
+       elf = grub_xen_file (file);
+       if (!elf)
+         break;
+       err = grub_xen_get_info (elf, &xen_inf);
+       if (err)
+         break;
+       /* Unfortuntely no way to check if kernel supports dom0.  */
+       if (type == IS_DOM0)
+         ret = 1;
+       if (type == IS_PAE_DOMU)
+         ret = (xen_inf.arch == GRUB_XEN_FILE_I386_PAE
+                || xen_inf.arch == GRUB_XEN_FILE_I386_PAE_BIMODE);
+       if (type == IS_64_DOMU)
+         ret = (xen_inf.arch == GRUB_XEN_FILE_X86_64);
+       break;
+      }
+    case IS_MULTIBOOT:
+    case IS_MULTIBOOT2:
+      {
+       grub_uint32_t *buffer;
+       grub_ssize_t len;
+       grub_size_t search_size;
+       grub_uint32_t *header;
+       grub_uint32_t magic;
+       grub_size_t step;
+
+       if (type == IS_MULTIBOOT2)
+         {
+           search_size = 32768;
+           magic = grub_cpu_to_le32_compile_time (0xe85250d6);
+           step = 2;
+         }
+       else
+         {
+           search_size = 8192;
+           magic = grub_cpu_to_le32_compile_time (0x1BADB002);
+           step = 1;
+         }
+
+       buffer = grub_malloc (search_size);
+       if (!buffer)
+         break;
+
+       len = grub_file_read (file, buffer, search_size);
+       if (len < 32)
+         {
+           grub_free (buffer);
+           break;
+         }
+
+       /* Look for the multiboot header in the buffer.  The header should
+          be at least 12 bytes and aligned on a 4-byte boundary.  */
+       for (header = buffer;
+            ((char *) header <=
+             (char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12))
+            || (header = 0); header += step)
+         {
+           if (header[0] == magic
+               && !(grub_le_to_cpu32 (header[0])
+                    + grub_le_to_cpu32 (header[1])
+                    + grub_le_to_cpu32 (header[2])
+                    + (type == IS_MULTIBOOT2
+                       ? grub_le_to_cpu32 (header[3]) : 0)))
+             break;
+         }
+
+       if (header != 0)
+         ret = 1;
+       grub_free (buffer);
+       break;
+      }
+    case IS_X86_LINUX32:
+    case IS_X86_LINUX:
+      {
+       struct linux_kernel_header lh;
+       if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+         break;
+       if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
+         break;
+
+       if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+         break;
+
+       /* FIXME: some really old kernels (< 1.3.73) will fail this.  */
+       if (lh.header !=
+           grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
+           || grub_le_to_cpu16 (lh.version) < 0x0200)
+         break;
+
+       if (type == IS_X86_LINUX)
+         {
+           ret = 1;
+           break;
+         }
+
+       /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
+          still not support 32-bit boot.  */
+       if (lh.header !=
+           grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
+           || grub_le_to_cpu16 (lh.version) < 0x0203)
+         break;
+
+       if (!(lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
+         break;
+       ret = 1;
+       break;
+      }
+    case IS_HIBERNATED:
+      {
+       grub_uint8_t hibr_file_magic[4];
+       if (grub_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic))
+           != sizeof (hibr_file_magic))
+         break;
+       if (grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) ==
+           0
+           || grub_memcmp ("HIBR", hibr_file_magic,
+                           sizeof (hibr_file_magic)) == 0)
+         ret = 1;
+       break;
+      }
+    case IS_XNU64:
+    case IS_XNU32:
+      {
+       macho = grub_macho_open (args[0], (type == IS_XNU64));
+       if (!macho)
+         break;
+       /* FIXME: more checks?  */
+       ret = 1;
+       break;
+      }
+    case IS_XNU_HIBR:
+      {
+       struct grub_xnu_hibernate_header hibhead;
+       if (grub_file_read (file, &hibhead, sizeof (hibhead))
+           != sizeof (hibhead))
+         break;
+       if (hibhead.magic !=
+           grub_cpu_to_le32_compile_time (GRUB_XNU_HIBERNATE_MAGIC))
+         break;
+       ret = 1;
+       break;
+      }
+    case IS_32_EFI:
+    case IS_64_EFI:
+    case IS_IA_EFI:
+    case IS_ARM_EFI:
+      {
+       char signature[4];
+       grub_uint32_t pe_offset;
+       struct grub_pe32_coff_header coff_head;
+
+       if (grub_file_read (file, signature, 2) != 2)
+         break;
+       if (signature[0] != 'M' || signature[1] != 'Z')
+         break;
+       if ((grub_ssize_t) grub_file_seek (file, 0x3c) == -1)
+         break;
+       if (grub_file_read (file, &pe_offset, 4) != 4)
+         break;
+       if ((grub_ssize_t) grub_file_seek (file, grub_le_to_cpu32 (pe_offset))
+           == -1)
+         break;
+       if (grub_file_read (file, signature, 4) != 4)
+         break;
+       if (signature[0] != 'P' || signature[1] != 'E'
+           || signature[2] != '\0' || signature[3] != '\0')
+         break;
+
+       if (grub_file_read (file, &coff_head, sizeof (coff_head))
+           != sizeof (coff_head))
+         break;
+       if (type == IS_32_EFI
+           && coff_head.machine !=
+           grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_I386))
+         break;
+       if (type == IS_64_EFI
+           && coff_head.machine !=
+           grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_X86_64))
+         break;
+       if (type == IS_IA_EFI
+           && coff_head.machine !=
+           grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_IA64))
+         break;
+       if (type == IS_ARM_EFI
+           && coff_head.machine !=
+           grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED))
+         break;
+       if (type == IS_64_EFI || type == IS_64_EFI)
+         {
+           struct grub_pe64_optional_header o64;
+           if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
+             break;
+           if (o64.magic !=
+               grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC))
+             break;
+           if (o64.subsystem !=
+               grub_cpu_to_le16_compile_time
+               (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
+             break;
+           ret = 1;
+           break;
+         }
+       if (type == IS_32_EFI || type == IS_ARM_EFI)
+         {
+           struct grub_pe32_optional_header o32;
+           if (grub_file_read (file, &o32, sizeof (o32)) != sizeof (o32))
+             break;
+           if (o32.magic !=
+               grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC))
+             break;
+           if (o32.subsystem !=
+               grub_cpu_to_le16_compile_time
+               (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
+             break;
+           ret = 1;
+           break;
+         }
+       break;
+      }
+    }
+
+  if (elf)
+    grub_elf_close (elf);
+  else if (macho)
+    grub_macho_close (macho);
+  else if (file)
+    grub_file_close (file);
+
+  if (!ret && (grub_errno == GRUB_ERR_BAD_OS || grub_errno == GRUB_ERR_NONE))
+    /* TRANSLATORS: it's a standalone boolean value,
+       opposite of "true".  */
+    grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
+  return grub_errno;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(file)
+{
+  cmd = grub_register_extcmd ("file", grub_cmd_file, 0,
+                             "OPTIONS FILE",
+                             N_("Check if FILE is of specified type."),
+                             options);
+}
+
+GRUB_MOD_FINI(file)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/file32.c b/grub-core/commands/file32.c
new file mode 100644 (file)
index 0000000..0861c45
--- /dev/null
@@ -0,0 +1,5 @@
+#define GRUB_TARGET_WORDSIZE 32
+#define XX             32
+#define ehdrXX ehdr32
+#define grub_file_check_netbsdXX grub_file_check_netbsd32
+#include "fileXX.c"
diff --git a/grub-core/commands/file64.c b/grub-core/commands/file64.c
new file mode 100644 (file)
index 0000000..90890d4
--- /dev/null
@@ -0,0 +1,5 @@
+#define GRUB_TARGET_WORDSIZE 64
+#define XX             64
+#define ehdrXX ehdr64
+#define grub_file_check_netbsdXX grub_file_check_netbsd64
+#include "fileXX.c"
diff --git a/grub-core/commands/fileXX.c b/grub-core/commands/fileXX.c
new file mode 100644 (file)
index 0000000..4d5c9d7
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  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/fileid.h>
+#include <grub/elfload.h>
+
+int
+grub_file_check_netbsdXX (grub_elf_t elf)
+{
+  Elf_Shdr *s, *s0;
+
+  grub_size_t shnum = elf->ehdr.ehdrXX.e_shnum;
+  grub_size_t shentsize = elf->ehdr.ehdrXX.e_shentsize;
+  grub_size_t shsize = shnum * shentsize;
+  grub_off_t stroff;
+
+  if (!shnum || !shentsize)
+    return 0;
+
+  s0 = grub_malloc (shsize);
+  if (!s0)
+    return 0;
+
+  if (grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_shoff) == (grub_off_t) -1)
+    return 0;
+
+  if (grub_file_read (elf->file, s0, shsize) != (grub_ssize_t) shsize)
+    return 0;
+
+  s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize);
+  stroff = s->sh_offset;
+
+  for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize);
+       s = (Elf_Shdr *) ((char *) s + shentsize))
+    {
+      char name[sizeof(".note.netbsd.ident")];
+      grub_memset (name, 0, sizeof (name));
+      if (grub_file_seek (elf->file, stroff + s->sh_name) == (grub_off_t) -1)
+       return grub_errno;
+
+      if (grub_file_read (elf->file, name, sizeof (name)) != (grub_ssize_t) sizeof (name))
+       {
+         if (grub_errno)
+           return grub_errno;
+         continue;
+       }
+      if (grub_memcmp (name, ".note.netbsd.ident",
+                      sizeof(".note.netbsd.ident")) != 0)
+       continue;
+      return 1;
+    }
+  return 0;
+}
index bcce242903a1a74a5dcc01a977a87c0597f65a31..e57f8019e83085358c38f70f976939eaf33cdc0f 100644 (file)
@@ -74,15 +74,15 @@ static grub_ssize_t
 read_vli (grub_file_t file, grub_uint64_t *num)
 {
   grub_uint8_t buf[VLI_MAX_DIGITS];
-  grub_ssize_t read;
+  grub_ssize_t read_bytes;
   grub_size_t dec;
 
-  read = grub_file_read (file, buf, VLI_MAX_DIGITS);
-  if (read < 0)
+  read_bytes = grub_file_read (file, buf, VLI_MAX_DIGITS);
+  if (read_bytes < 0)
     return -1;
 
-  dec = decode_vli (buf, read, num);
-  grub_file_seek (file, file->offset - (read - dec));
+  dec = decode_vli (buf, read_bytes, num);
+  grub_file_seek (file, file->offset - (read_bytes - dec));
   return dec;
 }
 
index cbd17eb37a4a46a3759e9111d16807f551b5f798..a32c88e97981bf2f6184c05e45f522d8dbd70b2e 100644 (file)
@@ -707,7 +707,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       goto fail;
     }
 
-  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+  if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
     {
       grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
       goto fail;
index fb7f692b2da279bcb4a41615e6133ed047a344b8..ebbf6aa11babdeed00217b495fdc713a07e6cda5 100644 (file)
@@ -77,12 +77,17 @@ grub_xen_get_info (grub_elf_t elf, struct grub_xen_file_info * xi)
 {
   grub_memset (xi, 0, sizeof (*xi));
 
-  if (grub_elf_is_elf64 (elf))
+  if (grub_elf_is_elf64 (elf)
+      && elf->ehdr.ehdr64.e_machine
+      == grub_cpu_to_le16_compile_time (EM_X86_64)
+      && elf->ehdr.ehdr64.e_ident[EI_DATA] == ELFDATA2LSB)
     {
       xi->arch = GRUB_XEN_FILE_X86_64;
       return grub_xen_get_info64 (elf, xi);
     }
-  if (grub_elf_is_elf32 (elf))
+  if (grub_elf_is_elf32 (elf)
+      && elf->ehdr.ehdr32.e_machine == grub_cpu_to_le16_compile_time (EM_386)
+      && elf->ehdr.ehdr32.e_ident[EI_DATA] == ELFDATA2LSB)
     {
       xi->arch = GRUB_XEN_FILE_I386;
       return grub_xen_get_info32 (elf, xi);
index 79f56c67bb0d26b04e3a4b66d8385ba27fa8f801..caa79639082e249f115f98d79abb4a891b6a6760 100644 (file)
@@ -2467,7 +2467,7 @@ typedef Elf32_Addr Elf32_Conflict;
 
 #define R_X86_64_NUM           24
 
-#ifndef GRUB_UTIL
+#ifdef GRUB_TARGET_WORDSIZE
 #if GRUB_TARGET_WORDSIZE == 32
 
 typedef Elf32_Addr Elf_Addr;
diff --git a/include/grub/fileid.h b/include/grub/fileid.h
new file mode 100644 (file)
index 0000000..ae75b69
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  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_FILEID_HEADER
+#define GRUB_FILEID_HEADER     1
+
+#include <grub/elfload.h>
+
+int
+grub_file_check_netbsd32 (grub_elf_t elf);
+int
+grub_file_check_netbsd64 (grub_elf_t elf);
+
+#endif
diff --git a/util/grub-file.c b/util/grub-file.c
new file mode 100644 (file)
index 0000000..2591ecd
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010,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/misc.h>
+#include <grub/i18n.h>
+#include <grub/term.h>
+#include <grub/font.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/color.h>
+#include <grub/util/install.h>
+#include <grub/command.h>
+#include <grub/env.h>
+
+#define _GNU_SOURCE    1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <argp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "progname.h"
+
+void grub_file_init (void);
+void grub_host_init (void);
+void grub_hostfs_init (void);
+
+int
+main (int argc, char *argv[])
+{
+  char **argv2;
+  int i;
+  int had_file = 0, had_separator = 0;
+  grub_command_t cmd;
+  grub_err_t err;
+
+  grub_util_host_init (&argc, &argv);
+
+  argv2 = xmalloc (argc * sizeof (argv));
+
+  if (argc == 2 && strcmp (argv[1], "--version") == 0)
+    {
+      printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
+    }
+
+  for (i = 1; i < argc; i++)
+    {
+      if (argv[i][0] == '-' && argv[i][1] == '-'
+         && argv[i][2] == '\0' && !had_separator)
+       {
+         had_separator = 1;
+         argv2[i - 1] = xstrdup (argv[i]);
+         continue;
+       }
+      if (argv[i][0] == '-' && !had_separator)
+       {
+         argv2[i - 1] = xstrdup (argv[i]);
+         continue;
+       }
+      if (had_file)
+       grub_util_error ("multiple files specified");
+      argv2[i - 1] = canonicalize_file_name (argv[i]);
+      if (!argv2[i - 1])
+       {
+         grub_util_error (_("cannot open `%s': %s"), argv[i],
+                          strerror (errno));
+       }
+      had_file = 1;
+    }
+  argv2[i - 1] = NULL;
+
+  /* Initialize all modules. */
+  grub_init_all ();
+  grub_file_init ();
+  grub_hostfs_init ();
+  grub_host_init ();
+
+  grub_env_set ("root", "host");
+
+  cmd = grub_command_find ("file");
+  if (! cmd)
+    grub_util_error (_("can't find command `%s'"), "file");
+
+  err = (cmd->func) (cmd, argc - 1, argv2);
+  if (err && err != GRUB_ERR_TEST_FAILURE)
+    grub_print_error ();
+  return err;
+}
index 3390ba90fcb2d45db3e8d7bc316316fe70c27167..0ca0db1897d0f8539571bd54fb619c95c2197d85 100644 (file)
@@ -39,6 +39,7 @@ grub_mkconfig_dir="${sysconfdir}"/grub.d
 self=`basename $0`
 
 grub_probe="${sbindir}/@grub_probe@"
+grub_file="${bindir}/@grub_file@"
 grub_editenv="${bindir}/@grub_editenv@"
 grub_script_check="${bindir}/@grub_script_check@"
 
@@ -54,6 +55,7 @@ usage () {
     gettext "Generate a grub config file"; echo
     echo
     print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")"
+    print_option_help "-r, --root-directory=$(gettext DIR)" "$(gettext "use DIR as root directory [default=/]")"
     print_option_help "-h, --help" "$(gettext "print this message and exit")"
     print_option_help "-v, --version" "$(gettext "print the version information and exit")"
     echo
@@ -71,6 +73,8 @@ argument () {
   echo $1
 }
 
+GRUB_ROOT=
+
 # Check the arguments.
 while test $# -gt 0
 do
@@ -89,6 +93,11 @@ do
     --output=*)
        grub_cfg=`echo "$option" | sed 's/--output=//'`
        ;;
+    -r | --root-directory)
+       GRUB_ROOT=`argument $option "$@"`; shift;;
+    --root-directory=*)
+       GRUB_ROOT=`echo "$option" | sed 's/--output=//'`
+       ;;
     -*)
        gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
        usage
@@ -128,19 +137,19 @@ else
 fi
 
 # Device containing our userland.  Typically used for root= parameter.
-GRUB_DEVICE="`${grub_probe} --target=device /`"
+GRUB_DEVICE="`${grub_probe} --target=device "$GRUB_ROOT"/`"
 GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
 
 # Device containing our /boot partition.  Usually the same as GRUB_DEVICE.
-GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
+GRUB_DEVICE_BOOT="`${grub_probe} --target=device "$GRUB_ROOT"/boot`"
 GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
 
 # Filesystem for the device containing our userland.  Used for stuff like
 # choosing Hurd filesystem module.
 GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
 
-if [ x"$GRUB_FS" = xunknown ]; then
-    GRUB_FS="$(stat -f --printf=%T / || echo unknown)"
+if [ x"$GRUB_FS" = x ] || [ x"$GRUB_FS" = xunknown ]; then
+    GRUB_FS="$(stat -f --printf=%T "$GRUB_ROOT"/ || echo unknown)"
 fi
 
 if test -f ${sysconfdir}/default/grub ; then
@@ -177,6 +186,7 @@ if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub
 # These are defined in this script, export them here so that user can
 # override them.
 export GRUB_DEVICE \
+  GRUB_ROOT \
   GRUB_DEVICE_UUID \
   GRUB_DEVICE_BOOT \
   GRUB_DEVICE_BOOT_UUID \
@@ -243,18 +253,46 @@ cat << EOF
 #
 EOF
 
-for i in ${grub_mkconfig_dir}/* ; do
+
+for i in "${grub_mkconfig_dir}"/* ; do
   case "$i" in
+      "${grub_mkconfig_dir}"/00_header \
+      | "${grub_mkconfig_dir}"/30_os-prober \
+      | "${grub_mkconfig_dir}"/40_custom \
+      | "${grub_mkconfig_dir}"/41_custom)
+             echo
+              echo "### BEGIN $i ###"
+              "$i"
+              echo "### END $i ###"
+      ;;
     # emacsen backup files. FIXME: support other editors
     *~) ;;
     # emacsen autosave files. FIXME: support other editors
     */\#*\#) ;;
     *)
       if grub_file_is_not_garbage "$i" && test -x "$i" ; then
-        echo
-        echo "### BEGIN $i ###"
-        "$i"
-        echo "### END $i ###"
+         for platform in x86 i386-xen-pae x86_64-xen mips mipsel sparc64 powerpc ia64 arm; do
+             GRUB_PLATFORM=$platform
+             export GRUB_PLATFORM
+              buf="$($i)"
+             if [ x"$buf" != x ]; then
+                 echo
+                 echo "### BEGIN $i ($platform) ###"
+                 case x$platform in
+                     xx86)
+                         echo "if [ x\"\$grub_platform\" != xxen \\(  x\"\$grub_cpu\" = xi386 -o x\"\$grub_cpu\" = xx86_64 -o x\"\$grub_platform\" = x \\) ]; then" ;;
+                     xi386-xen-pae)
+                         echo "if [ x\"\$grub_cpu-\$grub_platform\" = xi386-xen -o x\"\$grub_cpu-\$grub_platform\" = x ]; then" ;;
+                     xx86_64-xen)
+                         echo "if [ x\"\$grub_cpu-\$grub_platform\" = xx86_64-xen -o x\"\$grub_cpu-\$grub_platform\" = x ]; then" ;;
+                     *)
+                         echo "if [ x\"\$grub_cpu\" = x$platform -o x\"\$grub_platform\" = x ]; then" ;;
+                 esac
+                 echo "$buf"
+                 echo "fi"
+                 echo "### END $i ($platform) ###"
+             fi
+         done
       fi
     ;;
   esac
index a9cf7fc554b1bcaa6303dfec7165237afe6375f4..14fadbcbbbdf1436cbd7f412e918e6b0351d81c0 100644 (file)
@@ -27,6 +27,9 @@ fi
 if test "x$grub_probe" = x; then
   grub_probe="${sbindir}/@grub_probe@"
 fi
+if test "x$grub_file" = x; then
+  grub_file="${bindir}/@grub_file@"
+fi
 if test "x$grub_mkrelpath" = x; then
   grub_mkrelpath="${bindir}/@grub_mkrelpath@"
 fi
index a48ef2395aa452dfa647af2459d10c70597daf51..f4abf70a3f3f989a0aa451f65ce6ca0f345fb50a 100644 (file)
 
 #if GRUB_TARGET_WORDSIZE == 64
 typedef Elf64_Rela elf_reloc_t;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-#define ELF_R_INFO ELF64_R_INFO
-#define ELF_ST_INFO ELF64_ST_INFO
 #define GRUB_PE32_MACHINE GRUB_PE32_MACHINE_X86_64
 #else
 typedef Elf32_Rel elf_reloc_t;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-#define ELF_R_INFO ELF32_R_INFO
-#define ELF_ST_INFO ELF32_ST_INFO
 #define GRUB_PE32_MACHINE GRUB_PE32_MACHINE_I386
 #endif
 
index d2e72520120dbd18ed7ba8cf334e806d22b19109..88ce5ac94ce1463eb7ab45d0e95660da4a6c529b 100644 (file)
@@ -152,7 +152,7 @@ if [ "x$gfxterm" = x1 ]; then
 if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT}"` ; then
 EOF
     else
-       for dir in "${pkgdatadir}" "`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`" /usr/share/grub ; do
+       for dir in "${pkgdatadir}" "`echo "$GRUB_ROOT"'/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`" "`echo "$GRUB_ROOT"'/usr/share/grub' | sed "s,//*,/,g"`" ; do
            for basename in unicode unifont ascii; do
                path="${dir}/${basename}.pf2"
                if is_path_readable_by_grub "${path}" > /dev/null ; then
index 82dfe193f36ecf66d9f9defc78b75897e15e0a50..da8069bd3394750d9e35addbdf231ab323a4a338 100644 (file)
@@ -21,6 +21,16 @@ prefix="@prefix@"
 exec_prefix="@exec_prefix@"
 datarootdir="@datarootdir@"
 
+if [ x$GRUB_PLATFORM = xx86 ]; then
+    check=--is-x86-multiboot
+elif [ x$GRUB_PLATFORM = xi386-xen-pae ]; then
+    check=--is-i386-xen-pae-domu
+elif [ x$GRUB_PLATFORM = xx86_64-xen ]; then
+    check=--is-x86_64-xen-domu
+else
+    exit 0
+fi
+
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
@@ -40,11 +50,11 @@ all_of_them=true
 
 # FIXME: add l4 here?
 kernel=
-for i in /boot/gnumach* ; do
-  if test -e $i ; then
-    basename=`basename $i`
-    dirname=`dirname $i`
-    rel_dirname=`make_system_path_relative_to_its_root $dirname`
+for i in "$GRUB_ROOT"/boot/gnumach* ; do
+  if test -f "$i" && "${grub_file}" $check "$i" ; then
+    basename=`basename "$i"`
+    dirname=`dirname "$i"`
+    rel_dirname=`make_system_path_relative_to_its_root "$dirname"`
     gettext_printf "Found GNU Mach: %s" "$i" >&2
     echo >&2
     kernels="${kernels} ${rel_dirname}/${basename}"
@@ -58,8 +68,8 @@ case "${GRUB_FS}" in
   *)   hurd_fs="${GRUB_FS}fs" ;;
 esac
 
-for i in /hurd/${hurd_fs}.static /hurd/exec ; do
-  if test -e "$i" ; then
+for i in "$GRUB_ROOT"/hurd/${hurd_fs}.static "$GRUB_ROOT"/hurd/exec ; do
+  if test -f "$i" ; then
     gettext_printf "Found Hurd module: %s" "$i" >&2
     echo >&2
     at_least_one=true
@@ -73,7 +83,7 @@ if ${at_least_one} ; then : ; else
   exit 0
 fi
 
-if ${all_of_them} && test -/lib/ld.so.1 ; then : ; else
+if ${all_of_them} && test -f "$GRUB_ROOT"/lib/ld.so.1 ; then : ; else
   gettext "Some Hurd stuff found, but not enough to boot." >&2
   echo >&2
   exit 1
index 0de616e8956b669687609c9cc789af018929defd..00f1d6816bb8edc1f56bc9e081c94f9956e2e9de 100644 (file)
@@ -27,6 +27,21 @@ export TEXTDOMAINDIR="@localedir@"
 
 CLASS="--class os"
 
+if [ x$GRUB_PLATFORM = xx86 ]; then
+    check=--is-x86-multiboot
+elif [ x$GRUB_PLATFORM = xi386-xen-pae ]; then
+    check=--is-i386-xen-pae-domu
+elif [ x$GRUB_PLATFORM = xx86_64-xen ]; then
+    check=--is-x86_64-xen-domu
+else
+    exit 0
+fi
+
+if ! test -f "$GRUB_ROOT"/platform/i86pc/kernel || ! "${grub_file}" $check "$GRUB_ROOT"/platform/i86pc/kernel; then
+    exit 0
+fi
+
+
 case "${GRUB_DISTRIBUTOR}" in
   *)
        OS="Illumos"
@@ -45,7 +60,7 @@ message="$(gettext_printf "Loading kernel of Illumos ...")"
        else
                ISADIR=
        fi
-       zfs-bootfs $($grub_mkrelpath /) ZFS_BOOTFS
+       zfs-bootfs $($grub_mkrelpath "$GRUB_ROOT"/) ZFS_BOOTFS
         echo '$(echo "$message" | grub_quote)'
        multiboot $($grub_mkrelpath /platform/i86pc/kernel)/\$ISADIR/unix /platform/i86pc/kernel/\$ISADIR/unix -B \$ZFS_BOOTFS,console=text
        module $($grub_mkrelpath /platform/i86pc)/\$ISADIR/boot_archive /platform/i86pc/\$ISADIR/boot_archive
index a524762fcdbe31c4ed99ad83aae5f144a5c7b5b3..f4aa450bb8f13630b964c7d5c86d512f0ba304bd 100644 (file)
@@ -27,6 +27,16 @@ export TEXTDOMAINDIR="@localedir@"
 
 CLASS="--class os"
 
+if [ x$GRUB_PLATFORM = xx86 ]; then
+    check=--is-x86-kfreebsd
+elif [ x$GRUB_PLATFORM = xi386-xen-pae ]; then
+    check=--is-i386-xen-pae-domu
+elif [ x$GRUB_PLATFORM = xx86_64-xen ]; then
+    check=--is-x86_64-xen-domu
+else
+    exit 0
+fi
+
 case "${GRUB_DISTRIBUTOR}" in
   Debian)
        OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD"
@@ -122,10 +132,10 @@ EOF
     zfs)
       load_kfreebsd_module opensolaris false
 
-      ls "/boot/zfs/zpool.cache" > /dev/null
+      ls "$GRUB_ROOT/boot/zfs/zpool.cache" > /dev/null
       printf '%s\n' "${prepare_boot_cache}"
       sed "s/^/$submenu_indentation/" << EOF
-       kfreebsd_module         $(make_system_path_relative_to_its_root /boot)/zfs/zpool.cache type=/boot/zfs/zpool.cache
+       kfreebsd_module         $(make_system_path_relative_to_its_root $GRUB_ROOT/boot)/zfs/zpool.cache type=/boot/zfs/zpool.cache
 EOF
     ;;
   esac
@@ -143,8 +153,8 @@ EOF
 EOF
 }
 
-list=`for i in /boot/kfreebsd-* /boot/kernel/kernel ; do
-        if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
+list=`for i in $GRUB_ROOT/boot/kfreebsd-* $GRUB_ROOT/boot/kernel/kernel ; do
+        if grub_file_is_not_garbage "$i" && ${grub_file} $check "$i"; then echo -n "$i " ; fi
       done`
 prepare_boot_cache=
 boot_device_id=
@@ -163,8 +173,8 @@ while [ "x$list" != "x" ] ; do
   dirname=`dirname $kfreebsd`
   rel_dirname=`make_system_path_relative_to_its_root $dirname`
 
-  if [ -f /boot/device.hints ] ; then
-    devices=/boot/device.hints
+  if [ -f "$GRUB_ROOT"/boot/device.hints ] ; then
+    devices="$GRUB_ROOT"/boot/device.hints
     devices_basename=`basename $devices`
     devices_dirname=`dirname $devices`
     devices_rel_dirname=`make_system_path_relative_to_its_root $devices_dirname`
@@ -181,14 +191,14 @@ while [ "x$list" != "x" ] ; do
                        # zpool name
                        kfreebsd_device=$(${grub_probe} -t fs_label --device ${GRUB_DEVICE})
                        # filesystem name (empty string for the main filesystem)
-                       kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")"
+                       kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} "$GRUB_ROOT"/ | sed -e "s,/*@$,,")"
     ;;
     *)
          kfreebsd_device=${kfreebsd_fs}id/${GRUB_DEVICE_UUID}
          # Debian GNU/kFreeBSD can't remount root if it's supplied as UUID but
          # as an UUID
          if [ "x${GRUB_DISTRIBUTOR}" = "xDebian" ] \
-             && ! (cat /etc/fstab | awk '!/^[[:space:]]*#/ && $2=="/" { print $1; }' \
+             && ! (cat "$GRUB_ROOT"/etc/fstab | awk '!/^[[:space:]]*#/ && $2=="/" { print $1; }' \
              | grep "${kfreebsd_fs}id/${GRUB_DEVICE_UUID}" > /dev/null); then
              kfreebsd_device=${GRUB_DEVICE} 
          fi
@@ -199,8 +209,8 @@ while [ "x$list" != "x" ] ; do
   alt_version=`echo $version | sed -e "s,\.old$,,g"`
 
   module_dir=
-  for i in "/lib/modules/${version}" "/lib/modules/${alt_version}" \
-      "/boot/kernel"; do
+  for i in "$GRUB_ROOT/lib/modules/${version}" "$GRUB_ROOT/lib/modules/${alt_version}" \
+      "$GRUB_ROOT/boot/kernel"; do
     if test -e "$i" ; then
       module_dir="$i"
       break
index 00d193159e9e9d0bd7d674e023cc51d041f3ee15..e904d1edf92fa0778a0e36c06935e0bcb22ebd1c 100644 (file)
@@ -26,6 +26,31 @@ datarootdir="@datarootdir@"
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
+if [ x$GRUB_PLATFORM = xx86 ]; then
+    check=--is-x86-linux32
+elif [ x$GRUB_PLATFORM = xi386-xen-pae ]; then
+    check=--is-i386-xen-pae-domu
+elif [ x$GRUB_PLATFORM = xx86_64-xen ]; then
+    check=--is-x86_64-xen-domu
+else
+    check=--is-${GRUB_PLATFORM}-linux
+fi
+
+case "x$GRUB_PLATFORM" in
+    xx86)
+       list=`for i in "$GRUB_ROOT"/boot/vmlinuz-* "$GRUB_ROOT"/vmlinuz-* "$GRUB_ROOT"/boot/kernel-* ; do
+                  if grub_file_is_not_garbage "$i" && "${grub_file}" $check "$i" ; then echo -n "$i " ; fi
+              done` ;;
+    *) 
+       list=`for i in "$GRUB_ROOT"/boot/vmlinuz-* "$GRUB_ROOT"/boot/vmlinux-* "$GRUB_ROOT"/vmlinuz-* "$GRUB_ROOT"/vmlinux-* "$GRUB_ROOT"/boot/kernel-* ; do
+                  if grub_file_is_not_garbage "$i" && "${grub_file}" $check "$i" ; then echo -n "$i " ; fi
+            done` ;;
+esac
+
+if [ x"$list" = x ]; then
+    exit 0
+fi
+
 CLASS="--class gnu-linux --class gnu --class os"
 
 if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
@@ -53,14 +78,14 @@ fi
 
 case x"$GRUB_FS" in
     xbtrfs)
-       rootsubvol="`make_system_path_relative_to_its_root /`"
+       rootsubvol="`make_system_path_relative_to_its_root "$GRUB_ROOT"/`"
        rootsubvol="${rootsubvol#/}"
        if [ "x${rootsubvol}" != x ]; then
            GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
        fi;;
     xzfs)
        rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
-       bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
+       bootfs="`make_system_path_relative_to_its_root "$GRUB_ROOT"/ | sed -e "s,@$,,"`"
        LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
        ;;
 esac
@@ -115,7 +140,7 @@ linux_entry ()
 
   echo "       insmod gzio" | sed "s/^/$submenu_indentation/"
 
-  if [ x$dirname = x/ ]; then
+  if [ x$dirname = x"$GRUB_ROOT"/ ]; then
     if [ -z "${prepare_root_cache}" ]; then
       prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
     fi
@@ -144,24 +169,12 @@ EOF
 EOF
 }
 
-machine=`uname -m`
-case "x$machine" in
-    xi?86 | xx86_64)
-       list=`for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
-                  if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
-              done` ;;
-    *) 
-       list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
-                  if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
-            done` ;;
-esac
-
-case "$machine" in
-    i?86) GENKERNEL_ARCH="x86" ;;
+case "$GRUB_PLATFORM" in
+    x86 | i386-xen-pae | x86_64-xen) GENKERNEL_ARCH="x86" ;;
     mips|mips64) GENKERNEL_ARCH="mips" ;;
     mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
     arm*) GENKERNEL_ARCH="arm" ;;
-    *) GENKERNEL_ARCH="$machine" ;;
+    *) GENKERNEL_ARCH="$GRUB_PLATFORM" ;;
 esac
 
 prepare_boot_cache=
@@ -200,7 +213,7 @@ while [ "x$list" != "x" ] ; do
   done
 
   config=
-  for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
+  for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "$GRUB_ROOT/etc/kernels/kernel-config-${version}" ; do
     if test -e "${i}" ; then
       config="${i}"
       break
index 29a0e41a9a51dd2af911113909da21cb287b6796..b1aba65c1ecf394a7702cd59e957b1000db48509 100644 (file)
@@ -22,6 +22,16 @@ exec_prefix="@exec_prefix@"
 datarootdir="@datarootdir@"
 . "@datadir@/@PACKAGE@/grub-mkconfig_lib"
 
+if [ x$GRUB_PLATFORM = xx86 ]; then
+    check=--is-x86-kfreebsd
+elif [ x$GRUB_PLATFORM = xi386-xen-pae ]; then
+    check=--is-i386-xen-pae-domu
+elif [ x$GRUB_PLATFORM = xx86_64-xen ]; then
+    check=--is-x86_64-xen-domu
+else
+    exit 0
+fi
+
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
@@ -36,19 +46,13 @@ netbsd_load_fs_module ()
   loader="$1"  # "knetbsd" or "multiboot"
   kernel="$2"  # absolute path to the kernel file
 
-  case $(zcat -f "${kernel}" | file -bL - | cut -d , -f 2 | tr -d ' ') in
-    Intel80386)
-      karch="i386"
-      ;;
-    x86-64)
+  if "${grub_file}" --is-x86_64-kfreebsd "${kernel}"; then
       karch="amd64"
-      ;;
-    *)
-      return
-      ;;
-  esac
+  else
+      karch="i386"
+  fi
 
-  case $(${grub_probe} --target=fs -d ${GRUB_DEVICE}) in
+  case $GRUB_FS in
     ext2)
       kmod="ext2fs"
       ;;
@@ -67,7 +71,7 @@ netbsd_load_fs_module ()
   esac
 
   kversion=$(zcat -f "${kernel}" | strings | sed -n -e '/^@(#)NetBSD/ { s/^@(#)NetBSD \([0-9\.]*\) .*$/\1/g ; p ; q ; }')
-  kmodule="/stand/${karch}/${kversion}/modules/${kmod}/${kmod}.kmod"
+  kmodule="$GRUB_ROOT/stand/${karch}/${kversion}/modules/${kmod}/${kmod}.kmod"
 
   if test -z "$karch" -o -z "$kversion" -o ! -f "${kmodule}"; then
     return
@@ -94,6 +98,10 @@ netbsd_entry ()
   type="$3"
   args="$4"    # extra arguments appended to loader command
 
+  if [ "x${loader}" = xmultiboot ] && [ x$GRUB_PLATFORM = xx86 ] && ! "$grub_file" --is-x86-multiboot "$kernel"; then
+      return
+  fi
+
   kroot_device="$(echo ${GRUB_DEVICE} | sed -e 's,^/dev/r,,')"
 
   if [ -z "$boot_device_id" ]; then
@@ -147,10 +155,13 @@ pattern="^ELF[^,]*executable.*statically linked"
 submenu_indentation=""
 
 is_top_level=true
-for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do
+for k in "$GRUB_ROOT"/netbsd $(ls -t "$GRUB_ROOT"/netbsd?* 2>/dev/null) ; do
   if ! grub_file_is_not_garbage "$k" ; then
     continue
   fi
+  if ! "$grub_file" $check "$k"; then
+    continue
+  fi
   if ! (zcat -f "$k" | file -bL - | grep -q "${pattern}") 2>/dev/null ; then
     continue
   fi
index 4270385f3d1785f6cd6631358ead6ff118c53b06..54c06135c02b5773869de6d0e6d9991c361d558a 100644 (file)
@@ -26,18 +26,28 @@ export TEXTDOMAINDIR="@localedir@"
 
 . "@datadir@/@PACKAGE@/grub-mkconfig_lib"
 
+if [ x$GRUB_PLATFORM != xx86 ]; then
+    exit 0
+fi
+
 osx_entry() {
     if [ x$2 = x32 ]; then
         # TRANSLATORS: it refers to kernel architecture (32-bit)
        bitstr="$(gettext "(32-bit)")"
+       if ! [ -f "$GRUB_ROOT"/mach_kernel ] || ! "${grub_file}" --is-i386-xnu  "$GRUB_ROOT"/mach_kernel; then
+           return;
+       fi
     else
         # TRANSLATORS: it refers to kernel architecture (64-bit)
        bitstr="$(gettext "(64-bit)")"
+       if ! [ -f "$GRUB_ROOT"/mach_kernel ] || ! "${grub_file}" --is-x86_64-xnu  "$GRUB_ROOT"/mach_kernel; then
+           return;
+       fi
     fi
     # TRANSLATORS: it refers on the OS residing on device %s
     onstr="$(gettext_printf "(on %s)" "${GRUB_DEVICE}")"
         cat << EOF
-menuentry '$(echo "Darwin/Mac OS X $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${GRUB_DEVICE}")'  {
+menuentry '$(echo "Darwin/Mac OS X $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'xnu-$2-$(grub_get_device_id "${GRUB_DEVICE}")'  {
 EOF
        save_default_entry | grub_add_tab
        prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab
@@ -50,7 +60,7 @@ EOF
            fi
         fi
         if [ \$do_resume = 0 ]; then
-           xnu_uuid ${OSXUUID} uuid
+           xnu_uuid ${GRUB_DEVICE_UUID} uuid
            if [ -f /Extra/DSDT.aml ]; then
               acpi -e /Extra/DSDT.aml
            fi
@@ -90,6 +100,5 @@ EOF
 EOF
 }
 
-OSXUUID="`${grub_probe} --target=fs_uuid --device ${GRUB_DEVICE} 2> /dev/null`"
 osx_entry xnu_kernel 32
 osx_entry xnu_kernel64 64
index a60843500edc08d4f9ae5f8969d8202b46a28fef..fbc1ce004ddb30d254a58b88cd66b5f795d126fd 100644 (file)
@@ -26,6 +26,10 @@ datarootdir="@datarootdir@"
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
+if [ x$GRUB_PLATFORM != xx86 ]; then
+    exit 0
+fi
+
 CLASS="--class gnu-linux --class gnu --class os --class xen"
 
 if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
@@ -61,14 +65,14 @@ fi
 
 case x"$GRUB_FS" in
     xbtrfs)
-       rootsubvol="`make_system_path_relative_to_its_root /`"
+       rootsubvol="`make_system_path_relative_to_its_root "$GRUB_ROOT"/`"
        rootsubvol="${rootsubvol#/}"
        if [ "x${rootsubvol}" != x ]; then
            GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
        fi;;
     xzfs)
        rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
-       bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
+       bootfs="`make_system_path_relative_to_its_root "$GRUB_ROOT"/ | sed -e "s,@$,,"`"
        LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
        ;;
 esac
@@ -137,19 +141,9 @@ EOF
 EOF
 }
 
-linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do
-    if grub_file_is_not_garbage "$i"; then
-       basename=$(basename $i)
-       version=$(echo $basename | sed -e "s,^[^0-9]*-,,g")
-       dirname=$(dirname $i)
-       config=
-       for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
-           if test -e "${j}" ; then
-               config="${j}"
-               break
-           fi
-       done
-        if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then echo -n "$i " ; fi
+linux_list=`for i in "$GRUB_ROOT"/boot/vmlinu[xz]-* "$GRUB_ROOT"/vmlinu[xz]-* "$GRUB_ROOT"/boot/kernel-*; do
+    if grub_file_is_not_garbage "$i" && "${grub_file}" --is-x86-xen-dom0 "$i"; then
+       echo -n "$i " ;
     fi
     done`
 if [ "x${linux_list}" = "x" ] ; then
@@ -165,8 +159,8 @@ file_is_not_sym () {
     esac
 }
 
-xen_list=`for i in /boot/xen*; do
-        if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then echo -n "$i " ; fi
+xen_list=`for i in "$GRUB_ROOT"/boot/xen*; do
+        if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" && ${grub_file} --is-x86-multiboot "$i"; then echo -n "$i " ; fi
       done`
 prepare_boot_cache=
 boot_device_id=