From: "bibo,mao" <bibo.mao@intel.com>
To: grub-devel@gnu.org
Subject: [PATCH 3/3] grub EFI disk device enumberating
Date: Tue, 24 Oct 2006 15:19:54 +0800 [thread overview]
Message-ID: <453DBE9A.7040300@intel.com> (raw)
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;
next reply other threads:[~2006-10-24 7:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-24 7:19 bibo,mao [this message]
2006-10-24 13:11 ` [PATCH 3/3] grub EFI disk device enumberating Johan Rydberg
2006-10-24 14:05 ` Johan Rydberg
2006-10-25 5:43 ` bibo,mao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=453DBE9A.7040300@intel.com \
--to=bibo.mao@intel.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.