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
,
53 (void **)&LegacyBios
);
54 if (EFI_ERROR (Status
)) {
56 // If no LegacyBios protocol we do not support legacy boot
58 return EFI_UNSUPPORTED
;
61 // Notes: if we seperate the int 19, then we don't need to refresh BBS
63 BdsRefreshBbsTableForBoot (Option
);
66 // Write boot to OS performance data to a file
69 WriteBootToOsPerformanceData ();
73 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Legacy Boot: %S\n", Option
->Description
));
74 return LegacyBios
->LegacyBoot (
76 (BBS_BBS_DEVICE_PATH
*) Option
->DevicePath
,
77 Option
->LoadOptionsSize
,
83 BdsLibBootViaBootOption (
84 IN BDS_COMMON_OPTION
* Option
,
85 IN EFI_DEVICE_PATH_PROTOCOL
* DevicePath
,
86 OUT UINTN
*ExitDataSize
,
87 OUT CHAR16
**ExitData OPTIONAL
93 Process the boot option follow the EFI 1.1 specification and
94 special treat the legacy boot option with BBS_DEVICE_PATH.
98 Option - The boot option need to be processed
100 DevicePath - The device path which describe where to load
101 the boot image or the legcy BBS device path
102 to boot the legacy OS
104 ExitDataSize - Returned directly from gBS->StartImage ()
106 ExitData - Returned directly from gBS->StartImage ()
110 EFI_SUCCESS - Status from gBS->StartImage (),
111 or BdsBootByDiskSignatureAndPartition ()
113 EFI_NOT_FOUND - If the Device Path is not found in the system
119 EFI_HANDLE ImageHandle
;
120 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
121 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
122 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
123 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
124 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
131 // Notes: put EFI64 ROM Shadow Solution
133 EFI64_SHADOW_ALL_LEGACY_ROM ();
136 // Notes: this code can be remove after the s3 script table
137 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
138 // EFI_EVENT_SIGNAL_LEGACY_BOOT
140 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
,
141 (VOID
**)&AcpiS3Save
);
142 if (!EFI_ERROR (Status
)) {
143 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
146 // If it's Device Path that starts with a hard drive path,
147 // this routine will do the booting.
149 Status
= BdsBootByDiskSignatureAndPartition (
151 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
152 Option
->LoadOptionsSize
,
157 if (!EFI_ERROR (Status
)) {
159 // If we found a disk signature and partition device path return success
164 EfiSignalEventReadyToBoot ();
171 &gEfiGlobalVariableGuid
,
172 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
177 if ((DevicePathType (Option
->DevicePath
) == BBS_DEVICE_PATH
) &&
178 (DevicePathSubType (Option
->DevicePath
) == BBS_BBS_DP
)
181 // Check to see if we should legacy BOOT. If yes then do the legacy boot
183 return BdsLibDoLegacyBoot (Option
);
186 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Booting EFI 1.1 way %S\n", Option
->Description
));
188 Status
= gBS
->LoadImage (
198 // If we didn't find an image, we may need to load the default
199 // boot behavior for the device.
201 if (EFI_ERROR (Status
)) {
203 // Find a Simple File System protocol on the device path. If the remaining
204 // device path is set to end then no Files are being specified, so try
205 // the removable media file name.
207 TempDevicePath
= DevicePath
;
208 Status
= gBS
->LocateDevicePath (
209 &gEfiSimpleFileSystemProtocolGuid
,
213 if (!EFI_ERROR (Status
) && IsDevicePathEnd (TempDevicePath
)) {
214 FilePath
= FileDevicePath (Handle
, EFI_REMOVABLE_MEDIA_FILE_NAME
);
217 // Issue a dummy read to the device to check for media change.
218 // When the removable media is changed, any Block IO read/write will
219 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
220 // returned. After the Block IO protocol is reinstalled, subsequent
221 // Block IO read/write will success.
223 Status
= gBS
->HandleProtocol (
225 &gEfiBlockIoProtocolGuid
,
228 if (!EFI_ERROR (Status
)) {
229 Buffer
= AllocatePool (BlkIo
->Media
->BlockSize
);
230 if (Buffer
!= NULL
) {
233 BlkIo
->Media
->MediaId
,
235 BlkIo
->Media
->BlockSize
,
238 gBS
->FreePool (Buffer
);
242 Status
= gBS
->LoadImage (
250 if (EFI_ERROR (Status
)) {
252 // The DevicePath failed, and it's not a valid
253 // removable media device.
259 Status
= EFI_NOT_FOUND
;
263 if (EFI_ERROR (Status
)) {
265 // It there is any error from the Boot attempt exit now.
270 // Provide the image with it's load options
272 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
,
273 (VOID
**) &ImageInfo
);
274 ASSERT_EFI_ERROR (Status
);
276 if (Option
->LoadOptionsSize
!= 0) {
277 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
278 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
281 // Before calling the image, enable the Watchdog Timer for
282 // the 5 Minute period
284 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
286 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
287 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
290 // Clear the Watchdog Timer after the image returns
292 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
296 // Clear Boot Current
300 &gEfiGlobalVariableGuid
,
301 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
310 BdsBootByDiskSignatureAndPartition (
311 IN BDS_COMMON_OPTION
* Option
,
312 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
313 IN UINT32 LoadOptionsSize
,
314 IN VOID
*LoadOptions
,
315 OUT UINTN
*ExitDataSize
,
316 OUT CHAR16
**ExitData OPTIONAL
322 Check to see if a hard ware device path was passed in. If it was then search
323 all the block IO devices for the passed in hard drive device path.
327 Option - The current processing boot option.
329 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
332 LoadOptionsSize - Passed into gBS->StartImage ()
333 via the loaded image protocol.
335 LoadOptions - Passed into gBS->StartImage ()
336 via the loaded image protocol.
338 ExitDataSize - returned directly from gBS->StartImage ()
340 ExitData - returned directly from gBS->StartImage ()
344 EFI_SUCCESS - Status from gBS->StartImage (),
345 or BootByDiskSignatureAndPartition ()
347 EFI_NOT_FOUND - If the Device Path is not found in the system
352 UINTN BlockIoHandleCount
;
353 EFI_HANDLE
*BlockIoBuffer
;
354 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
355 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
356 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
357 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
358 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
360 BOOLEAN DevicePathMatch
;
361 HARDDRIVE_DEVICE_PATH
*TempPath
;
366 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
367 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
370 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
373 return EFI_NOT_FOUND
;
376 // The boot device have already been connected
378 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
379 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
381 // If there was an error or there are no device handles that support
382 // the BLOCK_IO Protocol, then return.
384 return EFI_NOT_FOUND
;
387 // Loop through all the device handles that support the BLOCK_IO Protocol
389 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
391 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
392 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
396 // Make PreviousDevicePath == the device path node before the end node
398 DevicePath
= BlockIoDevicePath
;
399 BlockIoHdDevicePath
= NULL
;
402 // find HardDriver device path node
404 while (!IsDevicePathEnd (DevicePath
)) {
405 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
406 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
408 BlockIoHdDevicePath
= DevicePath
;
412 DevicePath
= NextDevicePathNode (DevicePath
);
415 if (BlockIoHdDevicePath
== NULL
) {
419 // See if the harddrive device path in blockio matches the orig Hard Drive Node
421 DevicePathMatch
= FALSE
;
423 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
424 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
427 // Only several fields will be checked. NOT whole NODE
429 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
430 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
431 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
432 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
434 // Get the matched device path
436 DevicePathMatch
= TRUE
;
439 // Only do the boot, when devicepath match
441 if (DevicePathMatch
) {
443 // Combine the Block IO and Hard Drive Device path together and try
446 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
447 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
450 // Recursive boot with new device path
452 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
453 if (!EFI_ERROR (Status
)) {
459 gBS
->FreePool (BlockIoBuffer
);
464 BdsLibDeleteOptionFromHandle (
471 Delete the boot option associated with the handle passed in
475 Handle - The handle which present the device path to create boot option
479 EFI_SUCCESS - Delete the boot option success
481 EFI_NOT_FOUND - If the Device Path is not found in the system
483 EFI_OUT_OF_RESOURCES - Lack of memory resource
485 Other - Error return value from SetVariable()
490 UINT8
*BootOptionVar
;
492 UINTN BootOptionSize
;
495 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
496 UINTN DevicePathSize
;
497 UINTN OptionDevicePathSize
;
498 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
499 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
503 Status
= EFI_SUCCESS
;
507 BootOrder
= BdsLibGetVariableAndSize (
509 &gEfiGlobalVariableGuid
,
512 if (NULL
== BootOrder
) {
513 return EFI_NOT_FOUND
;
516 DevicePath
= DevicePathFromHandle (Handle
);
517 if (DevicePath
== NULL
) {
518 return EFI_NOT_FOUND
;
520 DevicePathSize
= GetDevicePathSize (DevicePath
);
523 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
524 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
525 BootOptionVar
= BdsLibGetVariableAndSize (
527 &gEfiGlobalVariableGuid
,
530 if (NULL
== BootOptionVar
) {
531 gBS
->FreePool (BootOrder
);
532 return EFI_OUT_OF_RESOURCES
;
535 TempPtr
= BootOptionVar
;
536 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
537 Description
= (CHAR16
*) TempPtr
;
538 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
539 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
540 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
543 // Check whether the device path match
545 if ((OptionDevicePathSize
== DevicePathSize
) &&
546 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
547 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
548 gBS
->FreePool (BootOptionVar
);
552 gBS
->FreePool (BootOptionVar
);
556 Status
= gRT
->SetVariable (
558 &gEfiGlobalVariableGuid
,
559 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
564 gBS
->FreePool (BootOrder
);
570 BdsDeleteAllInvalidEfiBootOption (
577 Delete all invalid EFI boot options. The probable invalid boot option could
578 be Removable media or Network boot device.
586 EFI_SUCCESS - Delete all invalid boot option success
588 EFI_NOT_FOUND - Variable "BootOrder" is not found
590 EFI_OUT_OF_RESOURCES - Lack of memory resource
592 Other - Error return value from SetVariable()
597 UINT8
*BootOptionVar
;
599 UINTN BootOptionSize
;
603 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
604 UINTN OptionDevicePathSize
;
605 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
606 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
607 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
613 Status
= EFI_SUCCESS
;
617 BootOrder
= BdsLibGetVariableAndSize (
619 &gEfiGlobalVariableGuid
,
622 if (NULL
== BootOrder
) {
623 return EFI_NOT_FOUND
;
627 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
628 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
629 BootOptionVar
= BdsLibGetVariableAndSize (
631 &gEfiGlobalVariableGuid
,
634 if (NULL
== BootOptionVar
) {
635 gBS
->FreePool (BootOrder
);
636 return EFI_OUT_OF_RESOURCES
;
639 TempPtr
= BootOptionVar
;
640 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
641 Description
= (CHAR16
*) TempPtr
;
642 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
643 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
644 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
647 // Skip legacy boot option (BBS boot device)
649 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
650 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
651 gBS
->FreePool (BootOptionVar
);
656 TempDevicePath
= OptionDevicePath
;
657 LastDeviceNode
= OptionDevicePath
;
658 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
659 LastDeviceNode
= TempDevicePath
;
660 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
663 // Skip the boot option that point to a file, since the device path in
664 // removable media boot option doesn't contains a file name.
666 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
667 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
669 // Skip boot option for internal Shell, it's always valid
671 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
672 gBS
->FreePool (BootOptionVar
);
679 // Check if it's a valid boot option for removable media
681 TempDevicePath
= OptionDevicePath
;
682 Status
= gBS
->LocateDevicePath (
683 &gEfiSimpleFileSystemProtocolGuid
,
687 if (!EFI_ERROR (Status
)) {
691 // Check if it's a valid boot option for network boot device
693 TempDevicePath
= OptionDevicePath
;
694 Status
= gBS
->LocateDevicePath (
695 &gEfiLoadFileProtocolGuid
,
699 if (!EFI_ERROR (Status
)) {
705 // Delete this invalid boot option "Boot####"
707 Status
= gRT
->SetVariable (
709 &gEfiGlobalVariableGuid
,
710 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
715 // Mark this boot option in boot order as deleted
717 BootOrder
[Index
] = 0xffff;
720 gBS
->FreePool (BootOptionVar
);
725 // Adjust boot order array
728 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
729 if (BootOrder
[Index
] != 0xffff) {
730 BootOrder
[Index2
] = BootOrder
[Index
];
734 Status
= gRT
->SetVariable (
736 &gEfiGlobalVariableGuid
,
737 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
738 Index2
* sizeof (UINT16
),
742 gBS
->FreePool (BootOrder
);
748 BdsLibEnumerateAllBootOption (
749 IN OUT LIST_ENTRY
*BdsBootOptionList
755 This function will enumerate all possible boot device in the system,
756 it will only excute once of every boot.
760 BdsBootOptionList - The header of the link list which indexed all
765 EFI_SUCCESS - Finished all the boot device enumerate and create
766 the boot option base on that boot device
771 UINT16 BootOptionNumber
;
772 UINTN NumberFileSystemHandles
;
773 EFI_HANDLE
*FileSystemHandles
;
774 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
776 UINTN NumberLoadFileHandles
;
777 EFI_HANDLE
*LoadFileHandles
;
778 VOID
*ProtocolInstance
;
779 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
781 EFI_HANDLE
*FvHandleBuffer
;
782 EFI_FV_FILETYPE Type
;
784 EFI_FV_FILE_ATTRIBUTES Attributes
;
785 UINT32 AuthenticationStatus
;
786 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
787 EFI_HANDLE ImageHandle
;
788 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
791 BootOptionNumber
= 0;
794 // If the boot device enumerate happened, just get the boot
795 // device from the boot order variable
797 if (mEnumBootDevice
) {
798 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
802 // Notes: this dirty code is to get the legacy boot option from the
803 // BBS table and create to variable as the EFI boot option, it should
804 // be removed after the CSM can provide legacy boot option directly
806 REFRESH_LEGACY_BOOT_OPTIONS
;
809 // Delete invalid boot option
811 BdsDeleteAllInvalidEfiBootOption ();
813 // Parse removable media
815 gBS
->LocateHandleBuffer (
817 &gEfiSimpleFileSystemProtocolGuid
,
819 &NumberFileSystemHandles
,
822 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
823 Status
= gBS
->HandleProtocol (
824 FileSystemHandles
[Index
],
825 &gEfiBlockIoProtocolGuid
,
828 if (!EFI_ERROR (Status
)) {
829 if (!BlkIo
->Media
->RemovableMedia
) {
831 // If the file system handle supports a BlkIo protocol,
832 // skip the removable media devices
839 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
840 // machinename is ia32, ia64, x64, ...
842 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
844 Status
= gBS
->LoadImage (
852 if (!EFI_ERROR(Status
)) {
854 // Verify the image is a EFI application (and not a driver)
856 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
857 ASSERT (!EFI_ERROR(Status
));
859 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
866 // No such file or the file is not a EFI application, delete this boot option
868 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
870 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
875 if (NumberFileSystemHandles
) {
876 gBS
->FreePool (FileSystemHandles
);
879 // Parse Network Boot Device
881 gBS
->LocateHandleBuffer (
883 &gEfiSimpleNetworkProtocolGuid
,
885 &NumberLoadFileHandles
,
888 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
889 Status
= gBS
->HandleProtocol (
890 LoadFileHandles
[Index
],
891 &gEfiLoadFileProtocolGuid
,
892 (VOID
**) &ProtocolInstance
894 if (EFI_ERROR (Status
)) {
898 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
902 if (NumberLoadFileHandles
) {
903 gBS
->FreePool (LoadFileHandles
);
906 // Check if we have on flash shell
908 gBS
->LocateHandleBuffer (
910 &gEfiFirmwareVolumeProtocolGuid
,
915 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
916 gBS
->HandleProtocol (
917 FvHandleBuffer
[Index
],
918 &gEfiFirmwareVolumeProtocolGuid
,
922 Status
= Fv
->ReadFile (
929 &AuthenticationStatus
931 if (EFI_ERROR (Status
)) {
933 // Skip if no shell file in the FV
938 // Build the shell boot option
940 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
945 gBS
->FreePool (FvHandleBuffer
);
948 // Make sure every boot only have one time
949 // boot device enumerate
951 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
952 mEnumBootDevice
= TRUE
;
958 BdsLibBuildOptionFromHandle (
959 IN EFI_HANDLE Handle
,
960 IN LIST_ENTRY
*BdsBootOptionList
966 Build the boot option with the handle parsed in
970 Handle - The handle which present the device path to create boot option
972 BdsBootOptionList - The header of the link list which indexed all current
981 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
984 DevicePath
= DevicePathFromHandle (Handle
);
985 TempString
= DevicePathToStr (DevicePath
);
988 // Create and register new boot option
990 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
994 BdsLibBuildOptionFromShell (
995 IN EFI_HANDLE Handle
,
996 IN OUT LIST_ENTRY
*BdsBootOptionList
1000 Routine Description:
1002 Build the on flash shell boot option with the handle parsed in
1006 Handle - The handle which present the device path to create on flash shell
1009 BdsBootOptionList - The header of the link list which indexed all current
1018 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1019 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1021 DevicePath
= DevicePathFromHandle (Handle
);
1024 // Build the shell device path
1026 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1027 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1030 // Create and register the shell boot option
1032 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1042 Routine Description:
1044 Boot from the EFI1.1 spec defined "BootNext" variable
1059 BDS_COMMON_OPTION
*BootOption
;
1060 LIST_ENTRY TempList
;
1065 // Init the boot option name buffer and temp link list
1067 InitializeListHead (&TempList
);
1068 ZeroMem (Buffer
, sizeof (Buffer
));
1070 BootNext
= BdsLibGetVariableAndSize (
1072 &gEfiGlobalVariableGuid
,
1077 // Clear the boot next variable first
1079 if (BootNext
!= NULL
) {
1082 &gEfiGlobalVariableGuid
,
1083 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1089 // Start to build the boot option and try to boot
1091 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1092 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1093 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1094 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);