]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Initial integration of hints
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 17:19:16 +0000 (18:19 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 17:19:16 +0000 (18:19 +0100)
Makefile.util.def
grub-core/commands/search_wrap.c
grub-core/disk/ieee1275/ofdisk.c
grub-core/kern/emu/hostdisk.c
grub-core/normal/main.c
include/grub/emu/hostdisk.h
util/grub-install.in
util/grub-mkconfig.in
util/grub-mkconfig_lib.in
util/grub-probe.c
util/ieee1275/devicemap.c [deleted file]

index 829b16facabf0f51096d5e7f4aa6dfd19030c239..8812a783c2aa4dd84e64fa080e88bf4efe55318a 100644 (file)
@@ -242,10 +242,7 @@ program = {
 
   common = util/grub-mkdevicemap.c;
   common = util/deviceiter.c;
-  nosparc64 = util/devicemap.c;
-
-  sparc64_ieee1275 = util/ieee1275/ofpath.c;
-  sparc64_ieee1275 = util/ieee1275/devicemap.c;
+  common = util/devicemap.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubkern.a;
@@ -258,6 +255,7 @@ program = {
   installdir = sbin;
   mansection = 8;
   common = util/grub-probe.c;
+  common = util/ieee1275/ofpath.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubkern.a;
index 7b0a99565cf1f51e2c127ff07cc369a7f98f9e3e..35c5ee3196eab178bc5199a0d6f3628a03f15e27 100644 (file)
@@ -42,6 +42,21 @@ static const struct grub_arg_option options[] =
     {"hint",           'h', GRUB_ARG_OPTION_REPEATABLE,
      N_("First try the device HINT. If HINT ends in comma, "
        "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
+    {"hint-ieee1275",   0, GRUB_ARG_OPTION_REPEATABLE,
+     N_("First try the device HINT if on IEEE1275. If HINT ends in comma, "
+       "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
+    {"hint-bios",   0, GRUB_ARG_OPTION_REPEATABLE,
+     N_("First try the device HINT if on BIOS. If HINT ends in comma, "
+       "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
+    {"hint-baremetal",   0, GRUB_ARG_OPTION_REPEATABLE,
+     N_("First try the device HINT. If HINT ends in comma, "
+       "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
+    {"hint-efi",   0, GRUB_ARG_OPTION_REPEATABLE,
+     N_("First try the device HINT if on EFI. If HINT ends in comma, "
+       "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
+    {"hint-arc",   0, GRUB_ARG_OPTION_REPEATABLE,
+     N_("First try the device HINT if on ARC. If HINT ends in comma, "
+       "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -52,7 +67,12 @@ enum options
     SEARCH_FS_UUID,
     SEARCH_SET,
     SEARCH_NO_FLOPPY,
-    SEARCH_HINT
+    SEARCH_HINT,
+    SEARCH_HINT_IEEE1275,
+    SEARCH_HINT_BIOS,
+    SEARCH_HINT_BAREMETAL,
+    SEARCH_HINT_EFI,
+    SEARCH_HINT_ARC,
  };
 
 static grub_err_t
@@ -60,27 +80,98 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
 {
   struct grub_arg_list *state = ctxt->state;
   const char *var = 0;
-  int nhints = 0;
+  int i = 0, j = 0, nhints = 0;
+  char **hints = NULL;
 
   if (state[SEARCH_HINT].set)
-    while (state[SEARCH_HINT].args[nhints])
+    for (i = 0; state[SEARCH_HINT].args[i]; i++)
       nhints++;
 
-  if (argc == 0)
+#ifdef GRUB_MACHINE_IEEE1275
+  if (state[SEARCH_HINT_IEEE1275].set)
+    for (i = 0; state[SEARCH_HINT_IEEE1275].args[i]; i++)
+      nhints++;
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+  if (state[SEARCH_HINT_EFI].set)
+    for (i = 0; state[SEARCH_HINT_EFI].args[i]; i++)
+      nhints++;
+#endif
+
+#ifdef GRUB_MACHINE_PCBIOS
+  if (state[SEARCH_HINT_BIOS].set)
+    for (i = 0; state[SEARCH_HINT_BIOS].args[i]; i++)
+      nhints++;
+#endif
+
+#ifdef GRUB_MACHINE_ARC
+  if (state[SEARCH_HINT_ARC].set)
+    for (i = 0; state[SEARCH_HINT_ARC].args[i]; i++)
+      nhints++;
+#endif
+
+  if (state[SEARCH_HINT_BAREMETAL].set)
+    for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
+      nhints++;
+
+  hints = grub_malloc (sizeof (hints[0]) * nhints);
+  if (!hints)
+    return grub_errno;
+  j = 0;
+
+  if (state[SEARCH_HINT].set)
+    for (i = 0; state[SEARCH_HINT].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT].args[i];
+
+#ifdef GRUB_MACHINE_IEEE1275
+  if (state[SEARCH_HINT_IEEE1275].set)
+    for (i = 0; state[SEARCH_HINT_IEEE1275].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT_IEEE1275].args[i];
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+  if (state[SEARCH_HINT_EFI].set)
+    for (i = 0; state[SEARCH_HINT_EFI].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT_EFI].args[i];
+#endif
+
+#ifdef GRUB_MACHINE_ARC
+  if (state[SEARCH_HINT_ARC].set)
+    for (i = 0; state[SEARCH_HINT_ARC].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT_ARC].args[i];
+#endif
+
+#ifdef GRUB_MACHINE_PCBIOS
+  if (state[SEARCH_HINT_BIOS].set)
+    for (i = 0; state[SEARCH_HINT_BIOS].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT_BIOS].args[i];
+#endif
+
+  if (state[SEARCH_HINT_BAREMETAL].set)
+    for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
+      hints[j++] = state[SEARCH_HINT_BAREMETAL].args[i];
+
+  /* Skip hints for future platforms.  */
+  for (j = 0; j < argc; j++)
+    if (grub_memcmp (args[j], "--hint-", sizeof ("--hint-") - 1) != 0)
+      break;
+
+  if (argc == j)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
 
   if (state[SEARCH_SET].set)
     var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root";
 
   if (state[SEARCH_LABEL].set)
-    grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set, 
-                      state[SEARCH_HINT].args, nhints);
+    grub_search_label (args[j], var, state[SEARCH_NO_FLOPPY].set, 
+                      hints, nhints);
   else if (state[SEARCH_FS_UUID].set)
-    grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set,
-                        state[SEARCH_HINT].args, nhints);
+    grub_search_fs_uuid (args[j], var, state[SEARCH_NO_FLOPPY].set,
+                        hints, nhints);
   else if (state[SEARCH_FILE].set)
-    grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set, 
-                        state[SEARCH_HINT].args, nhints);
+    grub_search_fs_file (args[j], var, state[SEARCH_NO_FLOPPY].set, 
+                        hints, nhints);
   else
     return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
 
@@ -92,7 +183,8 @@ static grub_extcmd_t cmd;
 GRUB_MOD_INIT(search)
 {
   cmd =
-    grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_EXTRACTOR,
+    grub_register_extcmd ("search", grub_cmd_search,
+                         GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
                          N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
                             " NAME"),
                          N_("Search devices by file, filesystem label"
index 0a935d5c2b8e5db3d955e28988b63c2a38cab3d3..7d1e81b30642a0d02b16a17f07948cdc95f247fb 100644 (file)
@@ -193,8 +193,14 @@ grub_ofdisk_iterate (int (*hook) (const char *name))
          if (grub_strncmp (ent->shortest, "cdrom", 5) == 0)
            continue;
 
-         if (hook (ent->shortest))
-           return 1;
+         {
+           char buffer[sizeof ("ieee1275/") + grub_strlen (env->shortest)];
+           char *ptr;
+           ptr = grub_stpcpy (buffer, "ieee1275/");
+           grub_strcpy (ptr, env->shortest);
+           if (hook (buffer))
+             return 1;
+         }
        }
     }    
   return 0;
@@ -236,7 +242,10 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
   char prop[64];
   grub_ssize_t actual;
 
-  devpath = compute_dev_path (name);
+  if (grub_strncmp (devpath, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                        "not IEEE1275 device");
+  devpath = compute_dev_path (name + sizeof ("ieee1275/") - 1);
   if (! devpath)
     return grub_errno;
 
index d3db7e6be8630dcd5699fd758906da7d6b648fa5..8f30c8a09e8b2348c48d162020ac70bea9678c0f 100644 (file)
@@ -132,6 +132,7 @@ struct
 {
   char *drive;
   char *device;
+  int device_map;
 } map[256];
 
 struct grub_util_biosdisk_data
@@ -140,6 +141,7 @@ struct grub_util_biosdisk_data
   int access_mode;
   int fd;
   int is_disk;
+  int device_map;
 };
 
 #ifdef __linux__
@@ -242,6 +244,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
   data->access_mode = 0;
   data->fd = -1;
   data->is_disk = 0;
+  data->device_map = map[drive].device_map;
 
   /* Get the size.  */
 #if defined(__MINGW32__)
@@ -1015,6 +1018,12 @@ read_device_map (const char *dev_map)
       grub_util_error ("%s:%d: %s", dev_map, lineno, msg);
     }
 
+  if (dev_map[0] == '\0')
+    {
+      grub_util_info (_("no device.map"));
+      return;
+    }
+
   fp = fopen (dev_map, "r");
   if (! fp)
     {
@@ -1055,6 +1064,7 @@ read_device_map (const char *dev_map)
       map[drive].drive = xmalloc (p - e + sizeof ('\0'));
       strncpy (map[drive].drive, e, p - e + sizeof ('\0'));
       map[drive].drive[p - e] = '\0';
+      map[drive].device_map = 1;
 
       p++;
       /* Skip leading spaces.  */
@@ -1623,7 +1633,10 @@ find_system_device (const char *os_dev, struct stat *st, int convert, int add)
     grub_util_error (_("device count exceeds limit"));
 
   map[i].device = os_disk;
-  map[i].drive = xstrdup (os_disk);
+  map[i].drive = xmalloc (sizeof ("hostdisk/") + strlen (os_disk));
+  strcpy (map[i].drive, "hostdisk/");
+  strcpy (map[i].drive + sizeof ("hostdisk/") - 1, os_disk);
+  map[i].device_map = 0;
 
   return i;
 }
@@ -1818,6 +1831,14 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
 #endif
 }
 
+const char *
+grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk)
+{
+  if (disk->dev != &grub_util_biosdisk_dev || map[disk->id].device_map)
+    return disk->name;
+  return 0;
+}
+
 const char *
 grub_util_biosdisk_get_osdev (grub_disk_t disk)
 {
index f372b6798f1ec3953e9c46ad49d6b6be735504c3..2527d8fe989d5d9aef7658e6720a3a634c041104 100644 (file)
@@ -474,7 +474,7 @@ static grub_command_t cmd_clear;
 
 static void (*grub_xputs_saved) (const char *str);
 static const char *features[] = {
-  "feature_chainloader_bpb", "feature_ntldr"
+  "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint"
 };
 
 GRUB_MOD_INIT(normal)
index 842dff496f8c4462694c70ffa6f5084d38d0b523..b44a573e16f5bc5a23b360df4cd83ae2f32f4e06 100644 (file)
@@ -28,6 +28,8 @@ char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
 const char *grub_util_biosdisk_get_osdev (grub_disk_t disk);
 int grub_util_biosdisk_is_present (const char *name);
 int grub_util_biosdisk_is_floppy (grub_disk_t disk);
+const char *
+grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk);
 grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk);
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
index db3a4db98a1381c502deb6a9fbf4b94185cad2bd..bf654f741ecfb3a4d0c34512b2b032f645fad6f4 100644 (file)
@@ -50,7 +50,6 @@ modules=
 install_device=
 no_floppy=
 force_lba=
-recheck=no
 debug=no
 debug_image=
 
@@ -106,7 +105,6 @@ Install GRUB on your drive.
   --no-floppy             do not probe any floppy drive
   --allow-floppy          Make the drive also bootable as floppy 
                           (default for fdX devices). May break on some BIOSes.
-  --recheck               probe a device map even if it already exists
   --force                 install even if problems are detected
 EOF
 if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
@@ -218,7 +216,7 @@ do
     --no-floppy)
        no_floppy="--no-floppy" ;;
     --recheck)
-       recheck=yes ;;
+           ;;
     --removable)
        removable=yes ;;
 
@@ -408,27 +406,17 @@ fi
 # Create the GRUB directory if it is not present.
 mkdir -p "$grubdir" || exit 1
 
-# If --recheck is specified, remove the device map, if present.
-if test $recheck = yes; then
-    rm -f "$device_map"
-fi
-
 # Create the device map file if it is not present.
 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
+       echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+       exit 1
+    fi
 else
-    # Create a safe temporary file.
-    test -n "$mklog" && log_file=`$mklog`
-
-    "$grub_mkdevicemap" "--device-map=$device_map" $no_floppy || exit 1
-fi
-
-# 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
-    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
-    exit 1
+    device_map=
 fi
 
 # Copy the GRUB images to the GRUB directory.
@@ -536,7 +524,22 @@ if [ "x${devabstraction_module}" = "x" ] ; then
              
           exit 1
         fi
-        echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg"
+
+       if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
+            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+       elif [ x"$platform" = xpc ]; then
+            hints="`"$grub_probe" --device-map="${device_map}" --target=bios_hints --device "${grub_device}"`"
+       elif [ x"$platform" = xefi ]; then
+            hints="`"$grub_probe" --device-map="${device_map}" --target=efi_hints --device "${grub_device}"`"
+       elif [ x"$platform" = xieee1275 ]; then
+            hints="`"$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device "${grub_device}"`"
+       elif [ x"$platform" = xloongson ] || [ x"$platform" = xqemu ] || [ x"$platform" = xcoreboot ] || [ x"$platform" = xmultiboot ] || [ x"$platform" = xqemu-mips ]; then
+            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+       else
+            echo "No hints available for your platform. Expect reduced performance"
+           hints=
+        fi
+        echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/load.cfg"
        echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg"
        config_opt="-c ${grubdir}/load.cfg "
         modules="$modules search_fs_uuid"
index afc66f886b416ab5063c320ea8696343baa45df0..1917da7a1c0aedb1afc33579b4c79186db32830e 100644 (file)
@@ -36,7 +36,6 @@ grub_mkconfig_dir=${sysconfdir}/grub.d
 
 self=`basename $0`
 
-grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed "${transform}"`
 grub_probe=${sbindir}/`echo grub-probe | sed "${transform}"`
 grub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`"
 
@@ -118,14 +117,6 @@ if [ "$EUID" != 0 ] ; then
   fi
 fi
 
-set $grub_mkdevicemap dummy
-if test -f "$1"; then
-    :
-else
-    echo "$1: Not found." 1>&2
-    exit 1
-fi
-
 set $grub_probe dummy
 if test -f "$1"; then
     :
@@ -136,10 +127,6 @@ fi
 
 mkdir -p ${GRUB_PREFIX}
 
-if test -e ${GRUB_PREFIX}/device.map ; then : ; else
-  ${grub_mkdevicemap}
-fi
-
 # Device containing our userland.  Typically used for root= parameter.
 GRUB_DEVICE="`${grub_probe} --target=device /`"
 GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
index 2c5fd8c6f51f460a9a54b4453040386c14f9b35f..8303edd86427b4f8905d97eb0edea4f014730326 100644 (file)
@@ -128,9 +128,14 @@ prepare_grub_to_access_device ()
 
   # If there's a filesystem UUID that GRUB is capable of identifying, use it;
   # otherwise set root as per value in device.map.
-  echo "set root='`"${grub_probe}" --device "${device}" --target=drive`'"
+  echo "set root='`"${grub_probe}" --device "${device}" --target=compatibility_hint`'"
   if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then
-    echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}"
+    hints="`"${grub_probe}" --device "${device}" --target=hints_string 2> /dev/null`"
+    echo "if [ x$feature_platform_search_hint = xy ]; then"
+    echo "  search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
+    echo "else"
+    echo "  search --no-floppy --fs-uuid --set=root ${fs_uuid}"
+    echo "fi"
   fi
 }
 
index 0d5dac9021df260df50884d2271f1445c2b8155b..b486a82e58dc7f13e0d9854e69fab4811774c20a 100644 (file)
@@ -34,6 +34,8 @@
 #include <grub/env.h>
 #include <grub/raid.h>
 #include <grub/i18n.h>
+#include <grub/emu/misc.h>
+#include <grub/util/ofpath.h>
 
 #include <stdio.h>
 #include <unistd.h>
@@ -54,6 +56,13 @@ enum {
   PRINT_DEVICE,
   PRINT_PARTMAP,
   PRINT_ABSTRACTION,
+  PRINT_HINT_STR,
+  PRINT_BIOS_HINT,
+  PRINT_IEEE1275_HINT,
+  PRINT_BAREMETAL_HINT,
+  PRINT_EFI_HINT,
+  PRINT_ARC_HINT,
+  PRINT_COMPATIBILITY_HINT
 };
 
 int print = PRINT_FS;
@@ -88,6 +97,131 @@ probe_raid_level (grub_disk_t disk)
   return ((struct grub_raid_array *) disk->data)->level;
 }
 
+/* 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 *) orig_path;
+
+  new_path = xmalloc (strlen (orig_path) * 2 + sizeof ("ieee1275/"));
+
+  p = orig_path;
+  grub_strcpy (new_path, "ieee1275/");
+  d = new_path + sizeof ("ieee1275/") - 1;
+  while ((c = *p++) != '\0')
+    {
+      if (c == ',')
+       *d++ = '\\';
+      *d++ = c;
+    }
+
+  free ((char *) orig_path);
+
+  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)
+{
+  if (dev->disk->partition)
+    printf ("%s,%s", drive, grub_partition_get_name (dev->disk->partition));
+  else
+    printf ("%s", drive);
+} 
+
 static void
 probe (const char *path, char *device_name)
 {
@@ -134,6 +268,173 @@ probe (const char *path, char *device_name)
   if (! dev)
     grub_util_error ("%s", grub_errmsg);
 
+  if (print == PRINT_HINT_STR)
+    {
+      const char *orig_path = grub_util_devname_to_ofpath (device_name);
+      char *ofpath = escape_of_path (orig_path);
+      char *biosname, *bare, *efi;
+      const char *map;
+
+      printf ("--hint-ieee1275=");
+      print_full_name (ofpath, dev);
+      printf (" ");
+      free (ofpath);
+
+      biosname = guess_bios_drive (device_name);
+      if (biosname)
+       {
+         printf ("--hint-bios=");
+         print_full_name (biosname, dev);
+         printf (" ");
+       }
+      free (biosname);
+
+      efi = guess_efi_drive (device_name);
+      if (efi)
+       {
+         printf ("--hint-efi=");
+         print_full_name (efi, dev);
+         printf (" ");
+       }
+      free (efi);
+
+      bare = guess_baremetal_drive (device_name);
+      if (bare)
+       {
+         printf ("--hint-baremetal=");
+         print_full_name (bare, dev);
+         printf (" ");
+       }
+      free (biosname);
+
+      /* FIXME: Add ARC hint.  */
+
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf ("--hint=");
+         print_full_name (map, dev);
+         printf (" ");
+       }
+      printf ("\n");
+
+      goto end;
+    }
+
+  if (print == PRINT_COMPATIBILITY_HINT)
+    {
+      const char *map;
+      char *biosname;
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf ("%s\n", map);
+         goto end;
+       }
+      biosname = guess_bios_drive (device_name);
+      if (biosname)
+       print_full_name (biosname, dev);
+      printf ("\n");
+      free (biosname);
+      goto end;
+    }
+
+  if (print == PRINT_BIOS_HINT)
+    {
+      char *biosname;
+      biosname = guess_bios_drive (device_name);
+      if (biosname)
+       print_full_name (biosname, dev);
+      printf ("\n");
+      free (biosname);
+      goto end;
+    }
+  if (print == PRINT_IEEE1275_HINT)
+    {
+      const char *orig_path = grub_util_devname_to_ofpath (device_name);
+      char *ofpath = escape_of_path (orig_path);
+      const char *map;
+
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf (" ");
+         print_full_name (map, dev);
+       }
+
+      printf (" ");
+      print_full_name (ofpath, dev);
+
+      printf ("\n");
+      free (ofpath);
+      goto end;
+    }
+  if (print == PRINT_EFI_HINT)
+    {
+      char *biosname;
+      char *name;
+      const char *map;
+      biosname = guess_efi_drive (device_name);
+
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf (" ");
+         print_full_name (map, dev);
+       }
+      if (biosname)
+       {
+         printf (" ");
+         print_full_name (biosname, dev);
+       }
+
+      printf ("\n");
+      free (biosname);
+      goto end;
+    }
+
+  if (print == PRINT_BAREMETAL_HINT)
+    {
+      char *biosname;
+      char *name;
+      const char *map;
+
+      biosname = guess_baremetal_drive (device_name);
+
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf (" ");
+         print_full_name (map, dev);
+       }
+      if (biosname)
+       {
+         printf (" ");
+         print_full_name (biosname, dev);
+       }
+
+      printf ("\n");
+      free (biosname);
+      goto end;
+    }
+
+  if (print == PRINT_ARC_HINT)
+    {
+      const char *map;
+
+      map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+      if (map)
+       {
+         printf (" ");
+         print_full_name (map, dev);
+       }
+      printf ("\n");
+
+      /* FIXME */
+
+      goto end;
+    }
+
   if (print == PRINT_ABSTRACTION)
     {
       grub_disk_memberlist_t list = NULL, tmp;
@@ -348,6 +649,20 @@ main (int argc, char *argv[])
              print = PRINT_PARTMAP;
            else if (!strcmp (optarg, "abstraction"))
              print = PRINT_ABSTRACTION;
+           else if (!strcmp (optarg, "hints_string"))
+             print = PRINT_HINT_STR;
+           else if (!strcmp (optarg, "bios_hints"))
+             print = PRINT_BIOS_HINT;
+           else if (!strcmp (optarg, "ieee1275_hints"))
+             print = PRINT_IEEE1275_HINT;
+           else if (!strcmp (optarg, "baremetal_hints"))
+             print = PRINT_BAREMETAL_HINT;
+           else if (!strcmp (optarg, "efi_hints"))
+             print = PRINT_EFI_HINT;
+           else if (!strcmp (optarg, "arc_hints"))
+             print = PRINT_ARC_HINT;
+           else if (!strcmp (optarg, "compatibility_hint"))
+             print = PRINT_COMPATIBILITY_HINT;
            else
              usage (1);
            break;
diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c
deleted file mode 100644 (file)
index 19ab746..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <grub/types.h>
-#include <grub/util/deviceiter.h>
-#include <grub/util/ofpath.h>
-#include <grub/util/misc.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 *) orig_path;
-
-  new_path = xmalloc (strlen (orig_path) * 2);
-
-  p = orig_path;
-  d = new_path;
-  while ((c = *p++) != '\0')
-    {
-      if (c == ',')
-       *d++ = '\\';
-      *d++ = c;
-    }
-
-  free ((char *) orig_path);
-
-  return new_path;
-}
-
-void
-grub_util_emit_devicemap_entry (FILE *fp, char *name,
-                               int is_floppy __attribute__((unused)),
-                               int *num_fd __attribute__((unused)),
-                               int *num_hd __attribute__((unused)))
-{
-  const char *orig_path = grub_util_devname_to_ofpath (name);
-  char *ofpath = escape_of_path (orig_path);
-
-  fprintf(fp, "(%s)\t%s\n", ofpath, name);
-
-  free (ofpath);
-}