3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 BDS Lib functions which relate with create or process the boot
22 #include "Performance.h"
24 BOOLEAN mEnumBootDevice
= FALSE
;
28 IN BDS_COMMON_OPTION
*Option
34 Boot the legacy system with the boot option
38 Option - The legacy boot option which have BBS device path
42 EFI_UNSUPPORTED - There is no legacybios protocol, do not support
45 EFI_STATUS - Return the status of LegacyBios->LegacyBoot ().
50 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
52 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, &LegacyBios
);
53 if (EFI_ERROR (Status
)) {
55 // If no LegacyBios protocol we do not support legacy boot
57 return EFI_UNSUPPORTED
;
60 // Notes: if we seperate the int 19, then we don't need to refresh BBS
62 BdsRefreshBbsTableForBoot (Option
);
65 // Write boot to OS performance data to a file
68 WriteBootToOsPerformanceData ();
72 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Legacy Boot: %S\n", Option
->Description
));
73 return LegacyBios
->LegacyBoot (
75 (BBS_BBS_DEVICE_PATH
*) Option
->DevicePath
,
76 Option
->LoadOptionsSize
,
82 BdsLibBootViaBootOption (
83 IN BDS_COMMON_OPTION
* Option
,
84 IN EFI_DEVICE_PATH_PROTOCOL
* DevicePath
,
85 OUT UINTN
*ExitDataSize
,
86 OUT CHAR16
**ExitData OPTIONAL
92 Process the boot option follow the EFI 1.1 specification and
93 special treat the legacy boot option with BBS_DEVICE_PATH.
97 Option - The boot option need to be processed
99 DevicePath - The device path which describe where to load
100 the boot image or the legcy BBS device path
101 to boot the legacy OS
103 ExitDataSize - Returned directly from gBS->StartImage ()
105 ExitData - Returned directly from gBS->StartImage ()
109 EFI_SUCCESS - Status from gBS->StartImage (),
110 or BdsBootByDiskSignatureAndPartition ()
112 EFI_NOT_FOUND - If the Device Path is not found in the system
118 EFI_HANDLE ImageHandle
;
119 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
120 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
121 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
122 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
123 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
127 // Record the performance data for End of BDS
129 PERF_END (0, BDS_TOK
, NULL
, 0);
135 // Notes: put EFI64 ROM Shadow Solution
137 EFI64_SHADOW_ALL_LEGACY_ROM ();
140 // Notes: this code can be remove after the s3 script table
141 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
142 // EFI_EVENT_SIGNAL_LEGACY_BOOT
144 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, &AcpiS3Save
);
145 if (!EFI_ERROR (Status
)) {
146 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
149 // If it's Device Path that starts with a hard drive path,
150 // this routine will do the booting.
152 Status
= BdsBootByDiskSignatureAndPartition (
154 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
155 Option
->LoadOptionsSize
,
160 if (!EFI_ERROR (Status
)) {
162 // If we found a disk signature and partition device path return success
167 // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event
169 EfiSignalEventReadyToBoot ();
176 &gEfiGlobalVariableGuid
,
177 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
182 if ((DevicePathType (Option
->DevicePath
) == BBS_DEVICE_PATH
) &&
183 (DevicePathSubType (Option
->DevicePath
) == BBS_BBS_DP
)
186 // Check to see if we should legacy BOOT. If yes then do the legacy boot
188 return BdsLibDoLegacyBoot (Option
);
191 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Booting EFI 1.1 way %S\n", Option
->Description
));
193 Status
= gBS
->LoadImage (
203 // If we didn't find an image, we may need to load the default
204 // boot behavior for the device.
206 if (EFI_ERROR (Status
)) {
208 // Find a Simple File System protocol on the device path. If the remaining
209 // device path is set to end then no Files are being specified, so try
210 // the removable media file name.
212 TempDevicePath
= DevicePath
;
213 Status
= gBS
->LocateDevicePath (
214 &gEfiSimpleFileSystemProtocolGuid
,
218 if (!EFI_ERROR (Status
) && IsDevicePathEnd (TempDevicePath
)) {
219 FilePath
= FileDevicePath (Handle
, EFI_REMOVABLE_MEDIA_FILE_NAME
);
222 // Issue a dummy read to the device to check for media change.
223 // When the removable media is changed, any Block IO read/write will
224 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
225 // returned. After the Block IO protocol is reinstalled, subsequent
226 // Block IO read/write will success.
228 Status
= gBS
->HandleProtocol (
230 &gEfiBlockIoProtocolGuid
,
233 if (!EFI_ERROR (Status
)) {
234 Buffer
= AllocatePool (BlkIo
->Media
->BlockSize
);
235 if (Buffer
!= NULL
) {
238 BlkIo
->Media
->MediaId
,
240 BlkIo
->Media
->BlockSize
,
243 gBS
->FreePool (Buffer
);
247 Status
= gBS
->LoadImage (
255 if (EFI_ERROR (Status
)) {
257 // The DevicePath failed, and it's not a valid
258 // removable media device.
264 Status
= EFI_NOT_FOUND
;
268 if (EFI_ERROR (Status
)) {
270 // It there is any error from the Boot attempt exit now.
275 // Provide the image with it's load options
277 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
278 ASSERT_EFI_ERROR (Status
);
280 if (Option
->LoadOptionsSize
!= 0) {
281 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
282 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
285 // Before calling the image, enable the Watchdog Timer for
286 // the 5 Minute period
288 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
290 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
291 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
294 // Clear the Watchdog Timer after the image returns
296 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
300 // Clear Boot Current
304 &gEfiGlobalVariableGuid
,
305 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
314 BdsBootByDiskSignatureAndPartition (
315 IN BDS_COMMON_OPTION
* Option
,
316 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
317 IN UINT32 LoadOptionsSize
,
318 IN VOID
*LoadOptions
,
319 OUT UINTN
*ExitDataSize
,
320 OUT CHAR16
**ExitData OPTIONAL
326 Check to see if a hard ware device path was passed in. If it was then search
327 all the block IO devices for the passed in hard drive device path.
331 Option - The current processing boot option.
333 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
336 LoadOptionsSize - Passed into gBS->StartImage ()
337 via the loaded image protocol.
339 LoadOptions - Passed into gBS->StartImage ()
340 via the loaded image protocol.
342 ExitDataSize - returned directly from gBS->StartImage ()
344 ExitData - returned directly from gBS->StartImage ()
348 EFI_SUCCESS - Status from gBS->StartImage (),
349 or BootByDiskSignatureAndPartition ()
351 EFI_NOT_FOUND - If the Device Path is not found in the system
356 UINTN BlockIoHandleCount
;
357 EFI_HANDLE
*BlockIoBuffer
;
358 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
359 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
360 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
361 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
362 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
364 BOOLEAN DevicePathMatch
;
365 HARDDRIVE_DEVICE_PATH
*TempPath
;
370 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
371 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
374 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
377 return EFI_NOT_FOUND
;
380 // The boot device have already been connected
382 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
383 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
385 // If there was an error or there are no device handles that support
386 // the BLOCK_IO Protocol, then return.
388 return EFI_NOT_FOUND
;
391 // Loop through all the device handles that support the BLOCK_IO Protocol
393 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
395 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
396 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
400 // Make PreviousDevicePath == the device path node before the end node
402 DevicePath
= BlockIoDevicePath
;
403 BlockIoHdDevicePath
= NULL
;
406 // find HardDriver device path node
408 while (!IsDevicePathEnd (DevicePath
)) {
409 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
410 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
412 BlockIoHdDevicePath
= DevicePath
;
416 DevicePath
= NextDevicePathNode (DevicePath
);
419 if (BlockIoHdDevicePath
== NULL
) {
423 // See if the harddrive device path in blockio matches the orig Hard Drive Node
425 DevicePathMatch
= FALSE
;
427 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
428 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
431 // Only several fields will be checked. NOT whole NODE
433 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
434 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
435 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
436 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
438 // Get the matched device path
440 DevicePathMatch
= TRUE
;
443 // Only do the boot, when devicepath match
445 if (DevicePathMatch
) {
447 // Combine the Block IO and Hard Drive Device path together and try
450 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
451 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
454 // Recursive boot with new device path
456 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
457 if (!EFI_ERROR (Status
)) {
463 gBS
->FreePool (BlockIoBuffer
);
468 BdsLibDeleteOptionFromHandle (
475 Delete the boot option associated with the handle passed in
479 Handle - The handle which present the device path to create boot option
483 EFI_SUCCESS - Delete the boot option success
485 EFI_NOT_FOUND - If the Device Path is not found in the system
487 EFI_OUT_OF_RESOURCES - Lack of memory resource
489 Other - Error return value from SetVariable()
494 UINT8
*BootOptionVar
;
496 UINTN BootOptionSize
;
499 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
500 UINTN DevicePathSize
;
501 UINTN OptionDevicePathSize
;
502 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
503 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
507 Status
= EFI_SUCCESS
;
511 BootOrder
= BdsLibGetVariableAndSize (
513 &gEfiGlobalVariableGuid
,
516 if (NULL
== BootOrder
) {
517 return EFI_NOT_FOUND
;
520 DevicePath
= DevicePathFromHandle (Handle
);
521 if (DevicePath
== NULL
) {
522 return EFI_NOT_FOUND
;
524 DevicePathSize
= GetDevicePathSize (DevicePath
);
527 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
528 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
529 BootOptionVar
= BdsLibGetVariableAndSize (
531 &gEfiGlobalVariableGuid
,
534 if (NULL
== BootOptionVar
) {
535 gBS
->FreePool (BootOrder
);
536 return EFI_OUT_OF_RESOURCES
;
539 TempPtr
= BootOptionVar
;
540 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
541 Description
= (CHAR16
*) TempPtr
;
542 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
543 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
544 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
547 // Check whether the device path match
549 if ((OptionDevicePathSize
== DevicePathSize
) &&
550 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
551 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
552 gBS
->FreePool (BootOptionVar
);
556 gBS
->FreePool (BootOptionVar
);
560 Status
= gRT
->SetVariable (
562 &gEfiGlobalVariableGuid
,
563 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
568 gBS
->FreePool (BootOrder
);
574 BdsDeleteAllInvalidEfiBootOption (
581 Delete all invalid EFI boot options. The probable invalid boot option could
582 be Removable media or Network boot device.
590 EFI_SUCCESS - Delete all invalid boot option success
592 EFI_NOT_FOUND - Variable "BootOrder" is not found
594 EFI_OUT_OF_RESOURCES - Lack of memory resource
596 Other - Error return value from SetVariable()
601 UINT8
*BootOptionVar
;
603 UINTN BootOptionSize
;
607 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
608 UINTN OptionDevicePathSize
;
609 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
610 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
611 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
617 Status
= EFI_SUCCESS
;
621 BootOrder
= BdsLibGetVariableAndSize (
623 &gEfiGlobalVariableGuid
,
626 if (NULL
== BootOrder
) {
627 return EFI_NOT_FOUND
;
631 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
632 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
633 BootOptionVar
= BdsLibGetVariableAndSize (
635 &gEfiGlobalVariableGuid
,
638 if (NULL
== BootOptionVar
) {
639 gBS
->FreePool (BootOrder
);
640 return EFI_OUT_OF_RESOURCES
;
643 TempPtr
= BootOptionVar
;
644 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
645 Description
= (CHAR16
*) TempPtr
;
646 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
647 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
648 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
651 // Skip legacy boot option (BBS boot device)
653 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
654 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
655 gBS
->FreePool (BootOptionVar
);
660 TempDevicePath
= OptionDevicePath
;
661 LastDeviceNode
= OptionDevicePath
;
662 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
663 LastDeviceNode
= TempDevicePath
;
664 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
667 // Skip the boot option that point to a file, since the device path in
668 // removable media boot option doesn't contains a file name.
670 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
671 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
673 // Skip boot option for internal Shell, it's always valid
675 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
676 gBS
->FreePool (BootOptionVar
);
683 // Check if it's a valid boot option for removable media
685 TempDevicePath
= OptionDevicePath
;
686 Status
= gBS
->LocateDevicePath (
687 &gEfiSimpleFileSystemProtocolGuid
,
691 if (!EFI_ERROR (Status
)) {
695 // Check if it's a valid boot option for network boot device
697 TempDevicePath
= OptionDevicePath
;
698 Status
= gBS
->LocateDevicePath (
699 &gEfiLoadFileProtocolGuid
,
703 if (!EFI_ERROR (Status
)) {
709 // Delete this invalid boot option "Boot####"
711 Status
= gRT
->SetVariable (
713 &gEfiGlobalVariableGuid
,
714 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
719 // Mark this boot option in boot order as deleted
721 BootOrder
[Index
] = 0xffff;
724 gBS
->FreePool (BootOptionVar
);
729 // Adjust boot order array
732 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
733 if (BootOrder
[Index
] != 0xffff) {
734 BootOrder
[Index2
] = BootOrder
[Index
];
738 Status
= gRT
->SetVariable (
740 &gEfiGlobalVariableGuid
,
741 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
742 Index2
* sizeof (UINT16
),
746 gBS
->FreePool (BootOrder
);
752 BdsLibEnumerateAllBootOption (
753 IN OUT LIST_ENTRY
*BdsBootOptionList
759 This function will enumerate all possible boot device in the system,
760 it will only excute once of every boot.
764 BdsBootOptionList - The header of the link list which indexed all
769 EFI_SUCCESS - Finished all the boot device enumerate and create
770 the boot option base on that boot device
775 UINT16 BootOptionNumber
;
776 UINTN NumberFileSystemHandles
;
777 EFI_HANDLE
*FileSystemHandles
;
778 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
780 UINTN NumberLoadFileHandles
;
781 EFI_HANDLE
*LoadFileHandles
;
782 VOID
*ProtocolInstance
;
783 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
785 EFI_HANDLE
*FvHandleBuffer
;
786 EFI_FV_FILETYPE Type
;
788 EFI_FV_FILE_ATTRIBUTES Attributes
;
789 UINT32 AuthenticationStatus
;
790 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
791 EFI_HANDLE ImageHandle
;
792 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
795 BootOptionNumber
= 0;
798 // If the boot device enumerate happened, just get the boot
799 // device from the boot order variable
801 if (mEnumBootDevice
) {
802 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
806 // Notes: this dirty code is to get the legacy boot option from the
807 // BBS table and create to variable as the EFI boot option, it should
808 // be removed after the CSM can provide legacy boot option directly
810 REFRESH_LEGACY_BOOT_OPTIONS
;
813 // Delete invalid boot option
815 BdsDeleteAllInvalidEfiBootOption ();
817 // Parse removable media
819 gBS
->LocateHandleBuffer (
821 &gEfiSimpleFileSystemProtocolGuid
,
823 &NumberFileSystemHandles
,
826 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
827 Status
= gBS
->HandleProtocol (
828 FileSystemHandles
[Index
],
829 &gEfiBlockIoProtocolGuid
,
832 if (!EFI_ERROR (Status
)) {
833 if (!BlkIo
->Media
->RemovableMedia
) {
835 // If the file system handle supports a BlkIo protocol,
836 // skip the removable media devices
843 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
844 // machinename is ia32, ia64, x64, ...
846 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
848 Status
= gBS
->LoadImage (
856 if (!EFI_ERROR(Status
)) {
858 // Verify the image is a EFI application (and not a driver)
860 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
861 ASSERT (!EFI_ERROR(Status
));
863 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
870 // No such file or the file is not a EFI application, delete this boot option
872 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
874 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
879 if (NumberFileSystemHandles
) {
880 gBS
->FreePool (FileSystemHandles
);
883 // Parse Network Boot Device
885 gBS
->LocateHandleBuffer (
887 &gEfiSimpleNetworkProtocolGuid
,
889 &NumberLoadFileHandles
,
892 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
893 Status
= gBS
->HandleProtocol (
894 LoadFileHandles
[Index
],
895 &gEfiLoadFileProtocolGuid
,
896 (VOID
**) &ProtocolInstance
898 if (EFI_ERROR (Status
)) {
902 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
906 if (NumberLoadFileHandles
) {
907 gBS
->FreePool (LoadFileHandles
);
910 // Check if we have on flash shell
912 gBS
->LocateHandleBuffer (
914 &gEfiFirmwareVolumeProtocolGuid
,
919 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
920 gBS
->HandleProtocol (
921 FvHandleBuffer
[Index
],
922 &gEfiFirmwareVolumeProtocolGuid
,
926 Status
= Fv
->ReadFile (
933 &AuthenticationStatus
935 if (EFI_ERROR (Status
)) {
937 // Skip if no shell file in the FV
942 // Build the shell boot option
944 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
949 gBS
->FreePool (FvHandleBuffer
);
952 // Make sure every boot only have one time
953 // boot device enumerate
955 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
956 mEnumBootDevice
= TRUE
;
962 BdsLibBuildOptionFromHandle (
963 IN EFI_HANDLE Handle
,
964 IN LIST_ENTRY
*BdsBootOptionList
970 Build the boot option with the handle parsed in
974 Handle - The handle which present the device path to create boot option
976 BdsBootOptionList - The header of the link list which indexed all current
985 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
988 DevicePath
= DevicePathFromHandle (Handle
);
989 TempString
= DevicePathToStr (DevicePath
);
992 // Create and register new boot option
994 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
998 BdsLibBuildOptionFromShell (
999 IN EFI_HANDLE Handle
,
1000 IN OUT LIST_ENTRY
*BdsBootOptionList
1004 Routine Description:
1006 Build the on flash shell boot option with the handle parsed in
1010 Handle - The handle which present the device path to create on flash shell
1013 BdsBootOptionList - The header of the link list which indexed all current
1022 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1023 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1025 DevicePath
= DevicePathFromHandle (Handle
);
1028 // Build the shell device path
1030 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1031 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1034 // Create and register the shell boot option
1036 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1046 Routine Description:
1048 Boot from the EFI1.1 spec defined "BootNext" variable
1063 BDS_COMMON_OPTION
*BootOption
;
1064 LIST_ENTRY TempList
;
1069 // Init the boot option name buffer and temp link list
1071 InitializeListHead (&TempList
);
1072 ZeroMem (Buffer
, sizeof (Buffer
));
1074 BootNext
= BdsLibGetVariableAndSize (
1076 &gEfiGlobalVariableGuid
,
1081 // Clear the boot next variable first
1083 if (BootNext
!= NULL
) {
1086 &gEfiGlobalVariableGuid
,
1087 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1093 // Start to build the boot option and try to boot
1095 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1096 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1097 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1098 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);