grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] grub EFI disk device enumberating


From: bibo,mao
Subject: [PATCH 3/3] grub EFI disk device enumberating
Date: Tue, 24 Oct 2006 15:19:54 +0800
User-agent: Thunderbird 1.5.0.7 (Windows/20060909)

Hi,
 On EFI platform, every partition is regarded as one block device and
responding EFI device path. EFI device patch has the same hierarchical
relationship with the partition. This patch will search root EFI device
path by current device patch, but not parent device path.
 Original grub can not find efi disk when grub.efi is executed on
logical partition.

 Previously I posted this patch, now I repost again.
 Any suggestion is welcome.

thanks
bibo,mao

diff -Nruap grub2.org/disk/efi/efidisk.c grub2/disk/efi/efidisk.c
--- grub2.org/disk/efi/efidisk.c        2006-10-24 13:23:42.000000000 +0800
+++ grub2/disk/efi/efidisk.c    2006-10-24 14:10:32.000000000 +0800
@@ -87,6 +87,52 @@ find_last_device_path (const grub_efi_de
  return p;
}

+static int compare_ancestor_path(const grub_efi_device_path_t *parent,
+                const grub_efi_device_path_t *dp2)
+{
+  /* Return non-zero.  */
+  if (! parent || ! dp2)
+    return 1;
+
+  while (1)
+    {
+      grub_efi_uint8_t type1, type2;
+      grub_efi_uint8_t subtype1, subtype2;
+      grub_efi_uint16_t len1, len2;
+      int ret;
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH(parent))
+       break;
+
+      type1 = GRUB_EFI_DEVICE_PATH_TYPE (parent);
+      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+
+      if (type1 != type2)
+       return (int) type2 - (int) type1;
+
+      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (parent);
+      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+
+      if (subtype1 != subtype2)
+       return (int) subtype1 - (int) subtype2;
+
+      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (parent);
+      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+
+      if (len1 != len2)
+       return (int) len1 - (int) len2;
+
+      ret = grub_memcmp (parent, dp2, len1);
+      if (ret != 0)
+       return ret;
+
+      parent = (grub_efi_device_path_t *) ((char *) parent + len1);
+      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+    }
+
+  return 0;
+}
+
/* Compare device paths.  */
static int
compare_device_paths (const grub_efi_device_path_t *dp1,
@@ -197,44 +243,6 @@ make_devices (void)
  return devices;
}

-/* Find the parent device.  */
-static struct grub_efidisk_data *
-find_parent_device (struct grub_efidisk_data *devices,
-                   struct grub_efidisk_data *d)
-{
-  grub_efi_device_path_t *dp, *ldp;
-  struct grub_efidisk_data *parent;
- - dp = duplicate_device_path (d->device_path);
-  if (! dp)
-    return 0;
-
-  ldp = find_last_device_path (dp);
-  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-  ldp->length[0] = sizeof (*ldp);
-  ldp->length[1] = 0;
-
-  for (parent = devices; parent; parent = parent->next)
-    {
-      /* Ignore itself.  */
-      if (parent == d)
-       continue;
- - if (compare_device_paths (parent->device_path, dp) == 0)
-       {
-         /* Found.  */
-         if (! parent->last_device_path)
-           parent = 0;
- - break;
-       }
-    }
-
-  grub_free (dp);
-  return parent;
-}
-
static int
iterate_child_devices (struct grub_efidisk_data *devices,
                       struct grub_efidisk_data *d,
@@ -301,107 +309,36 @@ add_device (struct grub_efidisk_data **d
}

/* Name the devices.  */
-static void
-name_devices (struct grub_efidisk_data *devices)
-{
+static void name_devices (struct grub_efidisk_data *devices){
  struct grub_efidisk_data *d;
- - /* First, identify devices by media device paths. */
-  for (d = devices; d; d = d->next)
-    {
-      grub_efi_device_path_t *dp;
-
-      dp = d->last_device_path;
-      if (! dp)
-       continue;
- - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
-       {
-         int is_hard_drive = 0;
- - switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
-           {
-           case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
-             is_hard_drive = 1;
-             /* Fall through by intention.  */
-           case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
-             {
-               struct grub_efidisk_data *parent;
-
-               parent = find_parent_device (devices, d);
-               if (parent)
-                 {
-                   if (is_hard_drive)
-                     {
-#if 0
-                       grub_printf ("adding a hard drive by a partition: ");
-                       grub_print_device_path (parent->device_path);
-#endif
-                       add_device (&hd_devices, parent);
-                     }
-                   else
-                     {
-#if 0
-                       grub_printf ("adding a cdrom by a partition: ");
-                       grub_print_device_path (parent->device_path);
-#endif
-                       add_device (&cd_devices, parent);
-                     }
- - /* Mark the parent as used. */
-                   parent->last_device_path = 0;
-                 }
-             }
-             /* Mark itself as used.  */
-             d->last_device_path = 0;
-             break;
-
-           default:
-             /* For now, ignore the others.  */
-             break;
-           }
-       }
-    }

  /* Let's see what can be added more.  */
  for (d = devices; d; d = d->next)
    {
      grub_efi_device_path_t *dp;
      grub_efi_block_io_media_t *m;
- +
      dp = d->last_device_path;
      if (! dp)
        continue;

      m = d->block_io->media;
-      if (m->logical_partition)
+      if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE)
        {
-         /* Only one partition in a non-media device. Assume that this
-            is a floppy drive.  */
-#if 0
-         grub_printf ("adding a floppy by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&fd_devices, d);
-       }
-      else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
-       {
-         /* This check is too heuristic, but assume that this is a
-            CDROM drive.  */
-#if 0
-         grub_printf ("adding a cdrom by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&cd_devices, d);
+         if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
+           {
+             grub_printf("adding a cd by guessing\n");
+             add_device (&cd_devices, d);
+           } else
+           {
+             grub_printf("adding a hd by guessing\n");
+             add_device (&hd_devices, d);
+           }
        }
-      else
+      if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE)
        {
-         /* The default is a hard drive.  */
-#if 0
-         grub_printf ("adding a hard drive by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&hd_devices, d);
+         grub_printf ("adding a floppy by guessing\n");
+         add_device (&fd_devices, d);
        }
    }
}
@@ -734,7 +671,6 @@ grub_efidisk_get_device_name (grub_efi_h
      grub_disk_t parent = 0;
      char *partition_name = 0;
      char *device_name;
-      grub_efi_device_path_t *dup_dp, *dup_ldp;
      grub_efi_hard_drive_device_path_t hd;
      auto int find_parent_disk (const char *name);
      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
@@ -753,7 +689,7 @@ grub_efidisk_get_device_name (grub_efi_h
              struct grub_efidisk_data *d;
d = disk->data;
-             if (compare_device_paths (d->device_path, dup_dp) == 0)
+             if (compare_ancestor_path(d->device_path, dp) == 0)
                {
                  parent = disk;
                  return 1;
@@ -778,20 +714,7 @@ grub_efidisk_get_device_name (grub_efi_h
          return 0;
        }

-      /* It is necessary to duplicate the device path so that GRUB
-        can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
-      if (! dup_dp)
-       return 0;
-
-      dup_ldp = find_last_device_path (dup_dp);
-      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-      dup_ldp->length[0] = sizeof (*dup_ldp);
-      dup_ldp->length[1] = 0;
-
      grub_efidisk_iterate (find_parent_disk);
-      grub_free (dup_dp);

      if (! parent)
        return 0;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]