From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id CF6CD211B76AB for ; Wed, 16 Jan 2019 01:03:01 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AB8BE8667E; Wed, 16 Jan 2019 09:03:00 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-172.rdu2.redhat.com [10.10.120.172]) by smtp.corp.redhat.com (Postfix) with ESMTP id C00395D779; Wed, 16 Jan 2019 09:02:58 +0000 (UTC) To: Gary Lin Cc: edk2-devel@lists.01.org, Ruiyu Ni , Hao Wu , Star Zeng References: <20190115094548.10214-1-glin@suse.com> <9497b88c-7025-e3bc-8f69-0a20a550930a@redhat.com> <20190116021601.GI3972@GaryWorkstation> From: Laszlo Ersek Message-ID: <3e8fbef5-c21f-d763-f1a6-61d503bee2ee@redhat.com> Date: Wed, 16 Jan 2019 10:02:57 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20190116021601.GI3972@GaryWorkstation> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 16 Jan 2019 09:03:00 +0000 (UTC) Subject: Re: [PATCH] MdeModulePkg/UefiBootManagerLib: Match the nested partitions X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2019 09:03:02 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 01/16/19 03:16, Gary Lin wrote: > On Tue, Jan 15, 2019 at 12:58:10PM +0100, Laszlo Ersek wrote: >> On 01/15/19 10:45, Gary Lin wrote: >>> In some cases, such as MD RAID1 in Linux, the bootloader may be in a >>> nested EFI system partition partition. For example, sda1 and sdb1 are >>> combined as md0 and the first partition of md0, md0p1, is an EFI system >>> partition. Then, the bootloader can be located by the following device >>> paths: >>> >>> PCI()/SATA(sda)/Partition(sda1)/Partition(md0p1)/File(bootloader.efi) >>> PCI()/SATA(sdb)/Partition(sdb1)/Partition(md0p1)/File(bootloader.efi) >> >> How does edk2 recognize the nested partition md0p1 in the first place? >> >> I would assume that the "outer" partitions (sda1, sdb1) start with some >> kind of MD RAID1 header that allows Linux to combine sda1 and sdb1 into >> md0p1. How does edk2 get past that header? >> >> Hmmm... based on >> , does >> Linux use "footers" instead of "headers"? >> > See the "Sub-versions of the version-1 superblock" section: > > > For MD 0.9 and 1.0, the metadata is stored in the end of the disk, and > those partitions, nested or not, are just like the normal partitions, so > the firmare can see them without the knowledge of MD metadata. MD 1.1 > and 1.2 would be a different story because those two use "headers". > > Anyway, I have tested RAID1 with MD 1.0 and OVMF actually appended md0p1 > in the device path. I only need to iterate the nested partitions in the > match function to make my boot option work. Thanks for the explanation! I'll let Ray review the change. Laszlo >>> >>> To make the boot option more resilient, we may create a boot option with >>> the short-form device path like "Partition(md0p1)/File(bootloader.efi)". >>> >>> However, BmMatchPartitionDevicePathNode() only matched the first >>> partition node and ignored the nested partitions, so the firmware would >>> refuse to load bootloader.efi since "Partition(md0p1)" doesn't match >>> either "Partition(sda1)" or "Partition(sda2)". >>> >>> This commit modifies BmMatchPartitionDevicePathNode() to iterate all >>> nested partitions so that the above boot option could work. >>> >>> Cc: Ruiyu Ni >>> Cc: Star Zeng >>> Cc: Jian J Wang >>> Cc: Hao Wu >>> Contributed-under: TianoCore Contribution Agreement 1.1 >>> Signed-off-by: Gary Lin >>> --- >>> .../Library/UefiBootManagerLib/BmBoot.c | 37 ++++++++++++------- >>> 1 file changed, 23 insertions(+), 14 deletions(-) >>> >>> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c >>> index 6a23477eb873..8354c2af674b 100644 >>> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c >>> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c >>> @@ -1995,21 +1995,30 @@ BmMatchPartitionDevicePathNode ( >>> return FALSE; >>> } >>> >>> - // >>> - // See if the harddrive device path in blockio matches the orig Hard Drive Node >>> - // >>> - Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath; >>> + do { >>> + // >>> + // See if the harddrive device path in blockio matches the orig Hard Drive Node >>> + // >>> + Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath; >>> >>> - // >>> - // Match Signature and PartitionNumber. >>> - // Unused bytes in Signature are initiaized with zeros. >>> - // >>> - return (BOOLEAN) ( >>> - (Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) && >>> - (Node->MBRType == HardDriveDevicePath->MBRType) && >>> - (Node->SignatureType == HardDriveDevicePath->SignatureType) && >>> - (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0) >>> - ); >>> + // >>> + // Match Signature and PartitionNumber. >>> + // Unused bytes in Signature are initiaized with zeros. >>> + // >>> + if ((Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) && >>> + (Node->MBRType == HardDriveDevicePath->MBRType) && >>> + (Node->SignatureType == HardDriveDevicePath->SignatureType) && >>> + (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)) { >>> + return TRUE; >>> + } >>> + >>> + // See if a nested partition exists >>> + BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath); >>> + } while (!IsDevicePathEnd (BlockIoDevicePath) && >>> + (DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) && >>> + (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP)); >>> + >>> + return FALSE; >>> } >>> >>> /** >>> >> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel >>