From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1GcGZw-0007AK-R2 for mharc-grub-devel@gnu.org; Tue, 24 Oct 2006 03:20:04 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1GcGZv-00079e-GI for grub-devel@gnu.org; Tue, 24 Oct 2006 03:20:03 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1GcGZs-00077w-Vs for grub-devel@gnu.org; Tue, 24 Oct 2006 03:20:02 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GcGZs-00077s-QI for grub-devel@gnu.org; Tue, 24 Oct 2006 03:20:00 -0400 Received: from [143.182.124.21] (helo=mga03.intel.com) by monty-python.gnu.org with esmtp (Exim 4.52) id 1GcGZs-00065V-Bp for grub-devel@gnu.org; Tue, 24 Oct 2006 03:20:00 -0400 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by mga03.intel.com with ESMTP; 24 Oct 2006 00:19:59 -0700 Received: from bmao-mobl.ccr.corp.intel.com (HELO [10.239.20.25]) ([10.239.20.25]) by azsmga001.ch.intel.com with ESMTP; 24 Oct 2006 00:19:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: i="4.09,348,1157353200"; d="scan'208"; a="135047016:sNHT25437272" Message-ID: <453DBE9A.7040300@intel.com> Date: Tue, 24 Oct 2006 15:19:54 +0800 From: "bibo,mao" User-Agent: Thunderbird 1.5.0.7 (Windows/20060909) MIME-Version: 1.0 To: grub-devel@gnu.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: [PATCH 3/3] grub EFI disk device enumberating X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Oct 2006 07:20:04 -0000 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;