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
;
130 // Notes: put EFI64 ROM Shadow Solution
132 EFI64_SHADOW_ALL_LEGACY_ROM ();
135 // Notes: this code can be remove after the s3 script table
136 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
137 // EFI_EVENT_SIGNAL_LEGACY_BOOT
139 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, &AcpiS3Save
);
140 if (!EFI_ERROR (Status
)) {
141 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
144 // If it's Device Path that starts with a hard drive path,
145 // this routine will do the booting.
147 Status
= BdsBootByDiskSignatureAndPartition (
149 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
150 Option
->LoadOptionsSize
,
155 if (!EFI_ERROR (Status
)) {
157 // If we found a disk signature and partition device path return success
162 // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event
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
, &ImageInfo
);
273 ASSERT_EFI_ERROR (Status
);
275 if (Option
->LoadOptionsSize
!= 0) {
276 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
277 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
280 // Before calling the image, enable the Watchdog Timer for
281 // the 5 Minute period
283 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
285 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
286 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
289 // Clear the Watchdog Timer after the image returns
291 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
295 // Clear Boot Current
299 &gEfiGlobalVariableGuid
,
300 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
309 BdsBootByDiskSignatureAndPartition (
310 IN BDS_COMMON_OPTION
* Option
,
311 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
312 IN UINT32 LoadOptionsSize
,
313 IN VOID
*LoadOptions
,
314 OUT UINTN
*ExitDataSize
,
315 OUT CHAR16
**ExitData OPTIONAL
321 Check to see if a hard ware device path was passed in. If it was then search
322 all the block IO devices for the passed in hard drive device path.
326 Option - The current processing boot option.
328 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
331 LoadOptionsSize - Passed into gBS->StartImage ()
332 via the loaded image protocol.
334 LoadOptions - Passed into gBS->StartImage ()
335 via the loaded image protocol.
337 ExitDataSize - returned directly from gBS->StartImage ()
339 ExitData - returned directly from gBS->StartImage ()
343 EFI_SUCCESS - Status from gBS->StartImage (),
344 or BootByDiskSignatureAndPartition ()
346 EFI_NOT_FOUND - If the Device Path is not found in the system
351 UINTN BlockIoHandleCount
;
352 EFI_HANDLE
*BlockIoBuffer
;
353 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
354 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
355 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
356 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
357 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
359 BOOLEAN DevicePathMatch
;
360 HARDDRIVE_DEVICE_PATH
*TempPath
;
365 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
366 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
369 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
372 return EFI_NOT_FOUND
;
375 // The boot device have already been connected
377 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
378 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
380 // If there was an error or there are no device handles that support
381 // the BLOCK_IO Protocol, then return.
383 return EFI_NOT_FOUND
;
386 // Loop through all the device handles that support the BLOCK_IO Protocol
388 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
390 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
391 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
395 // Make PreviousDevicePath == the device path node before the end node
397 DevicePath
= BlockIoDevicePath
;
398 BlockIoHdDevicePath
= NULL
;
401 // find HardDriver device path node
403 while (!IsDevicePathEnd (DevicePath
)) {
404 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
405 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
407 BlockIoHdDevicePath
= DevicePath
;
411 DevicePath
= NextDevicePathNode (DevicePath
);
414 if (BlockIoHdDevicePath
== NULL
) {
418 // See if the harddrive device path in blockio matches the orig Hard Drive Node
420 DevicePathMatch
= FALSE
;
422 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
423 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
426 // Only several fields will be checked. NOT whole NODE
428 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
429 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
430 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
431 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
433 // Get the matched device path
435 DevicePathMatch
= TRUE
;
438 // Only do the boot, when devicepath match
440 if (DevicePathMatch
) {
442 // Combine the Block IO and Hard Drive Device path together and try
445 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
446 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
449 // Recursive boot with new device path
451 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
452 if (!EFI_ERROR (Status
)) {
458 gBS
->FreePool (BlockIoBuffer
);
463 BdsLibDeleteOptionFromHandle (
470 Delete the boot option associated with the handle passed in
474 Handle - The handle which present the device path to create boot option
478 EFI_SUCCESS - Delete the boot option success
480 EFI_NOT_FOUND - If the Device Path is not found in the system
482 EFI_OUT_OF_RESOURCES - Lack of memory resource
484 Other - Error return value from SetVariable()
489 UINT8
*BootOptionVar
;
491 UINTN BootOptionSize
;
494 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
495 UINTN DevicePathSize
;
496 UINTN OptionDevicePathSize
;
497 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
498 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
502 Status
= EFI_SUCCESS
;
506 BootOrder
= BdsLibGetVariableAndSize (
508 &gEfiGlobalVariableGuid
,
511 if (NULL
== BootOrder
) {
512 return EFI_NOT_FOUND
;
515 DevicePath
= DevicePathFromHandle (Handle
);
516 if (DevicePath
== NULL
) {
517 return EFI_NOT_FOUND
;
519 DevicePathSize
= GetDevicePathSize (DevicePath
);
522 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
523 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
524 BootOptionVar
= BdsLibGetVariableAndSize (
526 &gEfiGlobalVariableGuid
,
529 if (NULL
== BootOptionVar
) {
530 gBS
->FreePool (BootOrder
);
531 return EFI_OUT_OF_RESOURCES
;
534 TempPtr
= BootOptionVar
;
535 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
536 Description
= (CHAR16
*) TempPtr
;
537 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
538 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
539 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
542 // Check whether the device path match
544 if ((OptionDevicePathSize
== DevicePathSize
) &&
545 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
546 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
547 gBS
->FreePool (BootOptionVar
);
551 gBS
->FreePool (BootOptionVar
);
555 Status
= gRT
->SetVariable (
557 &gEfiGlobalVariableGuid
,
558 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
563 gBS
->FreePool (BootOrder
);
569 BdsDeleteAllInvalidEfiBootOption (
576 Delete all invalid EFI boot options. The probable invalid boot option could
577 be Removable media or Network boot device.
585 EFI_SUCCESS - Delete all invalid boot option success
587 EFI_NOT_FOUND - Variable "BootOrder" is not found
589 EFI_OUT_OF_RESOURCES - Lack of memory resource
591 Other - Error return value from SetVariable()
596 UINT8
*BootOptionVar
;
598 UINTN BootOptionSize
;
602 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
603 UINTN OptionDevicePathSize
;
604 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
605 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
606 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
612 Status
= EFI_SUCCESS
;
616 BootOrder
= BdsLibGetVariableAndSize (
618 &gEfiGlobalVariableGuid
,
621 if (NULL
== BootOrder
) {
622 return EFI_NOT_FOUND
;
626 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
627 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
628 BootOptionVar
= BdsLibGetVariableAndSize (
630 &gEfiGlobalVariableGuid
,
633 if (NULL
== BootOptionVar
) {
634 gBS
->FreePool (BootOrder
);
635 return EFI_OUT_OF_RESOURCES
;
638 TempPtr
= BootOptionVar
;
639 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
640 Description
= (CHAR16
*) TempPtr
;
641 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
642 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
643 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
646 // Skip legacy boot option (BBS boot device)
648 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
649 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
650 gBS
->FreePool (BootOptionVar
);
655 TempDevicePath
= OptionDevicePath
;
656 LastDeviceNode
= OptionDevicePath
;
657 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
658 LastDeviceNode
= TempDevicePath
;
659 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
662 // Skip the boot option that point to a file, since the device path in
663 // removable media boot option doesn't contains a file name.
665 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
666 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
668 // Skip boot option for internal Shell, it's always valid
670 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
671 gBS
->FreePool (BootOptionVar
);
678 // Check if it's a valid boot option for removable media
680 TempDevicePath
= OptionDevicePath
;
681 Status
= gBS
->LocateDevicePath (
682 &gEfiSimpleFileSystemProtocolGuid
,
686 if (!EFI_ERROR (Status
)) {
690 // Check if it's a valid boot option for network boot device
692 TempDevicePath
= OptionDevicePath
;
693 Status
= gBS
->LocateDevicePath (
694 &gEfiLoadFileProtocolGuid
,
698 if (!EFI_ERROR (Status
)) {
704 // Delete this invalid boot option "Boot####"
706 Status
= gRT
->SetVariable (
708 &gEfiGlobalVariableGuid
,
709 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
714 // Mark this boot option in boot order as deleted
716 BootOrder
[Index
] = 0xffff;
719 gBS
->FreePool (BootOptionVar
);
724 // Adjust boot order array
727 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
728 if (BootOrder
[Index
] != 0xffff) {
729 BootOrder
[Index2
] = BootOrder
[Index
];
733 Status
= gRT
->SetVariable (
735 &gEfiGlobalVariableGuid
,
736 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
737 Index2
* sizeof (UINT16
),
741 gBS
->FreePool (BootOrder
);
747 BdsLibEnumerateAllBootOption (
748 IN OUT LIST_ENTRY
*BdsBootOptionList
754 This function will enumerate all possible boot device in the system,
755 it will only excute once of every boot.
759 BdsBootOptionList - The header of the link list which indexed all
764 EFI_SUCCESS - Finished all the boot device enumerate and create
765 the boot option base on that boot device
770 UINT16 BootOptionNumber
;
771 UINTN NumberFileSystemHandles
;
772 EFI_HANDLE
*FileSystemHandles
;
773 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
775 UINTN NumberLoadFileHandles
;
776 EFI_HANDLE
*LoadFileHandles
;
777 VOID
*ProtocolInstance
;
778 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
780 EFI_HANDLE
*FvHandleBuffer
;
781 EFI_FV_FILETYPE Type
;
783 EFI_FV_FILE_ATTRIBUTES Attributes
;
784 UINT32 AuthenticationStatus
;
785 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
786 EFI_HANDLE ImageHandle
;
787 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
790 BootOptionNumber
= 0;
793 // If the boot device enumerate happened, just get the boot
794 // device from the boot order variable
796 if (mEnumBootDevice
) {
797 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
801 // Notes: this dirty code is to get the legacy boot option from the
802 // BBS table and create to variable as the EFI boot option, it should
803 // be removed after the CSM can provide legacy boot option directly
805 REFRESH_LEGACY_BOOT_OPTIONS
;
808 // Delete invalid boot option
810 BdsDeleteAllInvalidEfiBootOption ();
812 // Parse removable media
814 gBS
->LocateHandleBuffer (
816 &gEfiSimpleFileSystemProtocolGuid
,
818 &NumberFileSystemHandles
,
821 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
822 Status
= gBS
->HandleProtocol (
823 FileSystemHandles
[Index
],
824 &gEfiBlockIoProtocolGuid
,
827 if (!EFI_ERROR (Status
)) {
828 if (!BlkIo
->Media
->RemovableMedia
) {
830 // If the file system handle supports a BlkIo protocol,
831 // skip the removable media devices
838 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
839 // machinename is ia32, ia64, x64, ...
841 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
843 Status
= gBS
->LoadImage (
851 if (!EFI_ERROR(Status
)) {
853 // Verify the image is a EFI application (and not a driver)
855 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
856 ASSERT (!EFI_ERROR(Status
));
858 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
865 // No such file or the file is not a EFI application, delete this boot option
867 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
869 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
874 if (NumberFileSystemHandles
) {
875 gBS
->FreePool (FileSystemHandles
);
878 // Parse Network Boot Device
880 gBS
->LocateHandleBuffer (
882 &gEfiSimpleNetworkProtocolGuid
,
884 &NumberLoadFileHandles
,
887 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
888 Status
= gBS
->HandleProtocol (
889 LoadFileHandles
[Index
],
890 &gEfiLoadFileProtocolGuid
,
891 (VOID
**) &ProtocolInstance
893 if (EFI_ERROR (Status
)) {
897 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
901 if (NumberLoadFileHandles
) {
902 gBS
->FreePool (LoadFileHandles
);
905 // Check if we have on flash shell
907 gBS
->LocateHandleBuffer (
909 &gEfiFirmwareVolumeProtocolGuid
,
914 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
915 gBS
->HandleProtocol (
916 FvHandleBuffer
[Index
],
917 &gEfiFirmwareVolumeProtocolGuid
,
921 Status
= Fv
->ReadFile (
928 &AuthenticationStatus
930 if (EFI_ERROR (Status
)) {
932 // Skip if no shell file in the FV
937 // Build the shell boot option
939 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
944 gBS
->FreePool (FvHandleBuffer
);
947 // Make sure every boot only have one time
948 // boot device enumerate
950 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
951 mEnumBootDevice
= TRUE
;
957 BdsLibBuildOptionFromHandle (
958 IN EFI_HANDLE Handle
,
959 IN LIST_ENTRY
*BdsBootOptionList
965 Build the boot option with the handle parsed in
969 Handle - The handle which present the device path to create boot option
971 BdsBootOptionList - The header of the link list which indexed all current
980 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
983 DevicePath
= DevicePathFromHandle (Handle
);
984 TempString
= DevicePathToStr (DevicePath
);
987 // Create and register new boot option
989 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
993 BdsLibBuildOptionFromShell (
994 IN EFI_HANDLE Handle
,
995 IN OUT LIST_ENTRY
*BdsBootOptionList
1001 Build the on flash shell boot option with the handle parsed in
1005 Handle - The handle which present the device path to create on flash shell
1008 BdsBootOptionList - The header of the link list which indexed all current
1017 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1018 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1020 DevicePath
= DevicePathFromHandle (Handle
);
1023 // Build the shell device path
1025 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1026 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1029 // Create and register the shell boot option
1031 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1041 Routine Description:
1043 Boot from the EFI1.1 spec defined "BootNext" variable
1058 BDS_COMMON_OPTION
*BootOption
;
1059 LIST_ENTRY TempList
;
1064 // Init the boot option name buffer and temp link list
1066 InitializeListHead (&TempList
);
1067 ZeroMem (Buffer
, sizeof (Buffer
));
1069 BootNext
= BdsLibGetVariableAndSize (
1071 &gEfiGlobalVariableGuid
,
1076 // Clear the boot next variable first
1078 if (BootNext
!= NULL
) {
1081 &gEfiGlobalVariableGuid
,
1082 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1088 // Start to build the boot option and try to boot
1090 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1091 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1092 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1093 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);