From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1G8sNS-0003gk-75 for mharc-grub-devel@gnu.org; Fri, 04 Aug 2006 01:37:42 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1G8sNQ-0003eO-Ti for grub-devel@gnu.org; Fri, 04 Aug 2006 01:37:40 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1G8sNQ-0003dz-5v for grub-devel@gnu.org; Fri, 04 Aug 2006 01:37:40 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1G8sNQ-0003dw-1E for grub-devel@gnu.org; Fri, 04 Aug 2006 01:37:40 -0400 Received: from [134.134.136.20] (helo=orsmga101-1.jf.intel.com) by monty-python.gnu.org with esmtp (Exim 4.52) id 1G8sQu-0002e8-EB for grub-devel@gnu.org; Fri, 04 Aug 2006 01:41:16 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101-1.jf.intel.com with ESMTP; 03 Aug 2006 22:37:34 -0700 Received: from unknown (HELO [10.239.25.49]) ([10.239.25.49]) by orsmga001.jf.intel.com with ESMTP; 03 Aug 2006 22:26:40 -0700 X-IronPort-AV: i="4.07,209,1151910000"; d="scan'208"; a="102324188:sNHT20958304472" Message-ID: <44D2DA8F.7030300@intel.com> Date: Fri, 04 Aug 2006 13:26:39 +0800 From: "bibo,mao" User-Agent: Thunderbird 1.5.0.4 (Windows/20060516) MIME-Version: 1.0 To: grub-devel@gnu.org Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Subject: EFI disk probing problem 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: Fri, 04 Aug 2006 05:37:41 -0000 hi, My hard disk is MBR partition type, there is FAT partition in my logical partition, bootloader grub.efi is in this partition. When grub efi bootloader starts up, it cannot probe my hard disk. It is because that parent device_path of current logical partition is extended partition, but not my hard disk's device path. Here I wrote one patch to solve this problem, I discarded the device whose type is not GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, added devices whose type is GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE as hard-disk or cdrom disk. Any suggestion is welcome:) I sent email to grub mailing list, but there is no response, I do not know why. thanks bibo,mao --- grub-1.94.org/disk/efi/efidisk.c 2006-05-01 05:09:37.000000000 +0800 +++ grub-1.94/disk/efi/efidisk.c 2006-07-26 13:00:09.000000000 +0800 @@ -87,6 +87,51 @@ 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) +{ + if (! parent || ! dp2) + /* Return non-zero. */ + 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, @@ -301,109 +346,34 @@ add_device (struct grub_efidisk_data **d } /* Name the 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; +static void name_devices (struct grub_efidisk_data *devices){ + struct grub_efidisk_data *d; - 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) - { - /* 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); - } - else - { - /* 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); + /* 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 (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE){ + 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); + } + } + if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE){ + grub_printf ("adding a floppy by guessing\n"); + add_device (&fd_devices, d); + } } - } } static void @@ -751,7 +721,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; @@ -776,20 +746,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;