X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=IntelFrameworkModulePkg%2FLibrary%2FGenericBdsLib%2FBdsBoot.c;h=a903ad08d6f2676c449a2397e5780040c3318bcf;hb=d46f36324fa86c08386f57c2675c45e4c1e888ec;hp=0cb21c169235820025f8f867bc505b9d895d05d1;hpb=07d97279a370e6e66dc1ae9b848fbd5f4eca202e;p=mirror_edk2.git diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c index 0cb21c1692..a903ad08d6 100644 --- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c +++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c @@ -79,7 +79,6 @@ BdsLibDoLegacyBoot ( @retval FALSE If not. **/ - BOOLEAN IsBootOptionValidNVVarialbe ( IN BDS_COMMON_OPTION *OptionToCheck @@ -221,7 +220,7 @@ BdsLibBootViaBootOption ( // // If the boot option point to Internal FV shell, make sure it is valid // - Status = BdsLibUpdateFvFileDevicePath (&DevicePath, &gEfiShellFileGuid); + Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile)); if (!EFI_ERROR(Status)) { if (Option->DevicePath != NULL) { FreePool(Option->DevicePath); @@ -248,7 +247,7 @@ BdsLibBootViaBootOption ( Status = gBS->LocateProtocol ( &gEfiSecurityArchProtocolGuid, NULL, - &SecurityProtocol + (VOID**) &SecurityProtocol ); if (!EFI_ERROR (Status)) { Status = SecurityProtocol->FileAuthenticationState (SecurityProtocol, 0, DevicePath); @@ -756,8 +755,7 @@ BdsLibDeleteOptionFromHandle ( /** - Delete all invalid EFI boot options. The probable invalid boot option could - be Removable media or Network boot device. + Delete all invalid EFI boot options. @retval EFI_SUCCESS Delete all invalid boot option success @retval EFI_NOT_FOUND Variable "BootOrder" is not found @@ -780,6 +778,7 @@ BdsDeleteAllInvalidEfiBootOption ( UINT16 BootOption[BOOT_OPTION_MAX_CHAR]; EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; UINT8 *TempPtr; + CHAR16 *Description; Status = EFI_SUCCESS; BootOrder = NULL; @@ -812,6 +811,7 @@ BdsDeleteAllInvalidEfiBootOption ( TempPtr = BootOptionVar; TempPtr += sizeof (UINT32) + sizeof (UINT16); + Description = (CHAR16 *) TempPtr; TempPtr += StrSize ((CHAR16 *) TempPtr); OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; @@ -825,7 +825,7 @@ BdsDeleteAllInvalidEfiBootOption ( continue; } - if (!BdsLibIsValidEFIBootOptDevicePath (OptionDevicePath, FALSE)) { + if (!BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) { // // Delete this invalid boot option "Boot####" // @@ -871,15 +871,48 @@ BdsDeleteAllInvalidEfiBootOption ( /** - This function will enumerate all possible boot device in the system, - it will only execute once of every boot. - + For EFI boot option, BDS separate them as six types: + 1. Network - The boot option points to the SimpleNetworkProtocol device. + Bds will try to automatically create this type boot option when enumerate. + 2. Shell - The boot option points to internal flash shell. + Bds will try to automatically create this type boot option when enumerate. + 3. Removable BlockIo - The boot option only points to the removable media + device, like USB flash disk, DVD, Floppy etc. + These device should contain a *removable* blockIo + protocol in their device handle. + Bds will try to automatically create this type boot option + when enumerate. + 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device, + like HardDisk. + These device should contain a *fixed* blockIo + protocol in their device handle. + BDS will skip fixed blockIo devices, and NOT + automatically create boot option for them. But BDS + will help to delete those fixed blockIo boot option, + whose description rule conflict with other auto-created + boot options. + 5. Non-BlockIo Simplefile - The boot option points to a device whose handle + has SimpleFileSystem Protocol, but has no blockio + protocol. These devices do not offer blockIo + protocol, but BDS still can get the + \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem + Protocol. + 6. File - The boot option points to a file. These boot options are usually + created by user manually or OS loader. BDS will not delete or modify + these boot options. + + This function will enumerate all possible boot device in the system, and + automatically create boot options for Network, Shell, Removable BlockIo, + and Non-BlockIo Simplefile devices. + It will only execute once of every boot. + @param BdsBootOptionList The header of the link list which indexed all current boot options @retval EFI_SUCCESS Finished all the boot device enumerate and create the boot option base on that boot device + @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list **/ EFI_STATUS EFIAPI @@ -892,6 +925,7 @@ BdsLibEnumerateAllBootOption ( UINT16 CdromNumber; UINT16 UsbNumber; UINT16 MiscNumber; + UINT16 ScsiNumber; UINT16 NonBlockNumber; UINTN NumberBlockIoHandles; EFI_HANDLE *BlockIoHandles; @@ -905,8 +939,8 @@ BdsLibEnumerateAllBootOption ( UINTN Size; EFI_FV_FILE_ATTRIBUTES Attributes; UINT32 AuthenticationStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN DevicePathType; CHAR16 Buffer[40]; EFI_HANDLE *FileSystemHandles; @@ -920,6 +954,7 @@ BdsLibEnumerateAllBootOption ( CdromNumber = 0; UsbNumber = 0; MiscNumber = 0; + ScsiNumber = 0; ZeroMem (Buffer, sizeof (Buffer)); // @@ -927,8 +962,8 @@ BdsLibEnumerateAllBootOption ( // device from the boot order variable // if (mEnumBootDevice) { - BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); - return EFI_SUCCESS; + Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); + return Status; } // @@ -973,52 +1008,36 @@ BdsLibEnumerateAllBootOption ( switch (DevicePathType) { case BDS_EFI_ACPI_FLOPPY_BOOT: - if (FloppyNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy %d", FloppyNumber); - } + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_FLOPPY_NUM, FloppyNumber); BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); FloppyNumber++; break; - + + // + // Assume a removable SATA device should be the DVD/CD device + // case BDS_EFI_MESSAGE_ATAPI_BOOT: - if (CdromNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM %d", CdromNumber); - } + case BDS_EFI_MESSAGE_SATA_BOOT: + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_DVD_NUM, CdromNumber); BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); CdromNumber++; break; case BDS_EFI_MESSAGE_USB_DEVICE_BOOT: - if (UsbNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device %d", UsbNumber); - } + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_USB_NUM, UsbNumber); BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); UsbNumber++; break; case BDS_EFI_MESSAGE_SCSI_BOOT: - if (UsbNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device %d", UsbNumber); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - UsbNumber++; + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_SCSI_NUM, ScsiNumber); + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + ScsiNumber++; break; case BDS_EFI_MESSAGE_MISC_BOOT: - if (MiscNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device %d", MiscNumber); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_MISC_NUM, MiscNumber); + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); MiscNumber++; break; @@ -1079,11 +1098,7 @@ BdsLibEnumerateAllBootOption ( // BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]); } else { - if (NonBlockNumber == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber); - } + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NON_BLOCK_NUM, NonBlockNumber); BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer); NonBlockNumber++; } @@ -1103,12 +1118,9 @@ BdsLibEnumerateAllBootOption ( &NumberSimpleNetworkHandles, &SimpleNetworkHandles ); + for (Index = 0; Index < NumberSimpleNetworkHandles; Index++) { - if (Index == 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network"); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network %d", Index); - } + UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NETWORK_NUM, Index); BdsLibBuildOptionFromHandle (SimpleNetworkHandles[Index], BdsBootOptionList, Buffer); } @@ -1135,7 +1147,7 @@ BdsLibEnumerateAllBootOption ( Status = Fv->ReadFile ( Fv, - &gEfiShellFileGuid, + PcdGetPtr(PcdShellFile), NULL, &Size, &Type, @@ -1161,10 +1173,10 @@ BdsLibEnumerateAllBootOption ( // Make sure every boot only have one time // boot device enumerate // - BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); + Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); mEnumBootDevice = TRUE; - return EFI_SUCCESS; + return Status; } /** @@ -1187,7 +1199,7 @@ BdsLibBuildOptionFromHandle ( { EFI_DEVICE_PATH_PROTOCOL *DevicePath; - DevicePath = DevicePathFromHandle (Handle); + DevicePath = DevicePathFromHandle (Handle); // // Create and register new boot option @@ -1220,7 +1232,7 @@ BdsLibBuildOptionFromShell ( // // Build the shell device path // - EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid); + EfiInitializeFwVolDevicepathNode (&ShellNode, PcdGetPtr(PcdShellFile)); DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode); @@ -1291,9 +1303,9 @@ BdsLibBootNext ( Second, check whether the device path point to a device which support SimpleFileSystemProtocol, Third, detect the the default boot file in the Media, and return the removable Media handle. - @param DevicePath Device Path to a bootable device + @param DevicePath Device Path to a bootable device - @retval NULL The media on the DevicePath is not bootable + @return The bootable media handle. If the media on the DevicePath is not bootable, NULL will return. **/ EFI_HANDLE @@ -1597,6 +1609,8 @@ BdsGetBootTypeFromDevicePath ( return BDS_EFI_MESSAGE_USB_DEVICE_BOOT; } else if (DevicePathSubType(TempDevicePath) == MSG_SCSI_DP) { return BDS_EFI_MESSAGE_SCSI_BOOT; + } else if (DevicePathSubType(TempDevicePath) == MSG_SATA_DP) { + return BDS_EFI_MESSAGE_SATA_BOOT; } return BDS_EFI_MESSAGE_MISC_BOOT; default: @@ -1608,6 +1622,41 @@ BdsGetBootTypeFromDevicePath ( return BDS_EFI_UNSUPPORT; } + +/** + Check whether the descriptionis is conflict with the description reserved for + auto-created boot options. + + @param Description The Description in a boot option + + @retval TRUE The description is conflict with the description reserved for + auto-created boot options. + @retval FALSE The description is not conflict with the description reserved. + +**/ +BOOLEAN +EFIAPI +CheckDescritptionConflict ( + IN CHAR16 *Description + ) +{ + if (Description == NULL) { + return FALSE; + } + if ((CompareMem (Description, DESCRIPTION_FLOPPY, StrLen (DESCRIPTION_FLOPPY) * sizeof (CHAR16)) == 0) || + (CompareMem (Description, DESCRIPTION_DVD, StrLen (DESCRIPTION_DVD) * sizeof (CHAR16)) == 0) || + (CompareMem (Description, DESCRIPTION_USB, StrLen (DESCRIPTION_USB) * sizeof (CHAR16)) == 0) || + (CompareMem (Description, DESCRIPTION_SCSI, StrLen (DESCRIPTION_SCSI) * sizeof (CHAR16)) == 0) || + (CompareMem (Description, DESCRIPTION_MISC, StrLen (DESCRIPTION_MISC) * sizeof (CHAR16)) == 0) || + (CompareMem (Description, DESCRIPTION_NETWORK, StrLen (DESCRIPTION_NETWORK) * sizeof (CHAR16)) == 0)|| + (CompareMem (Description, DESCRIPTION_NON_BLOCK, StrLen (DESCRIPTION_NON_BLOCK) * sizeof (CHAR16)) == 0)) { + return TRUE; + } + + return FALSE; +} + + /** Check whether the Device path in a boot option point to a valid bootable device, And if CheckMedia is true, check the device is ready to boot now. @@ -1625,6 +1674,32 @@ BdsLibIsValidEFIBootOptDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevPath, IN BOOLEAN CheckMedia ) +{ + return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL); +} + +/** + Check whether the Device path in a boot option point to a valid bootable device, + And if CheckMedia is true, check the device is ready to boot now. + If Description is not NULL and the device path point to a fixed BlockIo + device, check the description whether conflict with other auto-created + boot options. + + @param DevPath the Device path in a boot option + @param CheckMedia if true, check the device is ready to boot now. + @param Description the description in a boot option + + @retval TRUE the Device path is valid + @retval FALSE the Device path is invalid . + +**/ +BOOLEAN +EFIAPI +BdsLibIsValidEFIBootOptDevicePathExt ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath, + IN BOOLEAN CheckMedia, + IN CHAR16 *Description + ) { EFI_STATUS Status; EFI_HANDLE Handle; @@ -1692,7 +1767,7 @@ BdsLibIsValidEFIBootOptDevicePath ( // If the boot option point to Internal FV shell, make sure it is valid // TempDevicePath = DevPath; - Status = BdsLibUpdateFvFileDevicePath (&TempDevicePath, &gEfiShellFileGuid); + Status = BdsLibUpdateFvFileDevicePath (&TempDevicePath, PcdGetPtr(PcdShellFile)); if (Status == EFI_ALREADY_STARTED) { return TRUE; } else { @@ -1704,7 +1779,9 @@ BdsLibIsValidEFIBootOptDevicePath ( } // - // If the boot option point to a blockIO device, no matter whether or not it is a removeable device, it is a valid EFI boot option + // If the boot option point to a blockIO device: + // if it is a removable blockIo device, it is valid. + // if it is a fixed blockIo device, check its description confliction. // TempDevicePath = DevPath; Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle); @@ -1725,6 +1802,20 @@ BdsLibIsValidEFIBootOptDevicePath ( if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); if (!EFI_ERROR (Status)) { + if (!BlockIo->Media->RemovableMedia) { + // + // For the Fixed block devices, check its description whether conflict + // with other auto-created boot options. BDS permit a boot option point to + // Fixed block device, but not permit it use the description reserved for + // auto-created boot options. + // The check is to cover the bug, that replace a removable BlockIo device + // with a fixed BlockIo device at the same port, but the removable device's + // boot option can not be automatically deleted. + // + if (CheckDescritptionConflict (Description)) { + return FALSE; + } + } if (CheckMedia) { // // Test if it is ready to boot now