3 Copyright (c) 2006 - 2007, 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
23 // Include common header file for this module.
25 #include "CommonHeader.h"
27 #include "Performance.h"
29 BOOLEAN mEnumBootDevice
= FALSE
;
33 IN BDS_COMMON_OPTION
*Option
39 Boot the legacy system with the boot option
43 Option - The legacy boot option which have BBS device path
47 EFI_UNSUPPORTED - There is no legacybios protocol, do not support
50 EFI_STATUS - Return the status of LegacyBios->LegacyBoot ().
55 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
57 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, &LegacyBios
);
58 if (EFI_ERROR (Status
)) {
60 // If no LegacyBios protocol we do not support legacy boot
62 return EFI_UNSUPPORTED
;
65 // Notes: if we seperate the int 19, then we don't need to refresh BBS
67 BdsRefreshBbsTableForBoot (Option
);
70 // Write boot to OS performance data to a file
73 WriteBootToOsPerformanceData ();
77 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Legacy Boot: %S\n", Option
->Description
));
78 return LegacyBios
->LegacyBoot (
80 (BBS_BBS_DEVICE_PATH
*) Option
->DevicePath
,
81 Option
->LoadOptionsSize
,
87 BdsLibBootViaBootOption (
88 IN BDS_COMMON_OPTION
* Option
,
89 IN EFI_DEVICE_PATH_PROTOCOL
* DevicePath
,
90 OUT UINTN
*ExitDataSize
,
91 OUT CHAR16
**ExitData OPTIONAL
97 Process the boot option follow the EFI 1.1 specification and
98 special treat the legacy boot option with BBS_DEVICE_PATH.
102 Option - The boot option need to be processed
104 DevicePath - The device path which describe where to load
105 the boot image or the legcy BBS device path
106 to boot the legacy OS
108 ExitDataSize - Returned directly from gBS->StartImage ()
110 ExitData - Returned directly from gBS->StartImage ()
114 EFI_SUCCESS - Status from gBS->StartImage (),
115 or BdsBootByDiskSignatureAndPartition ()
117 EFI_NOT_FOUND - If the Device Path is not found in the system
123 EFI_HANDLE ImageHandle
;
124 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
125 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
126 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
127 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
128 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
132 // Record the performance data for End of BDS
134 PERF_END (0, BDS_TOK
, NULL
, 0);
140 // Notes: put EFI64 ROM Shadow Solution
142 EFI64_SHADOW_ALL_LEGACY_ROM ();
145 // Notes: this code can be remove after the s3 script table
146 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
147 // EFI_EVENT_SIGNAL_LEGACY_BOOT
149 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, &AcpiS3Save
);
150 if (!EFI_ERROR (Status
)) {
151 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
154 // If it's Device Path that starts with a hard drive path,
155 // this routine will do the booting.
157 Status
= BdsBootByDiskSignatureAndPartition (
159 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
160 Option
->LoadOptionsSize
,
165 if (!EFI_ERROR (Status
)) {
167 // If we found a disk signature and partition device path return success
172 // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event
174 EfiSignalEventReadyToBoot ();
181 &gEfiGlobalVariableGuid
,
182 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
187 if ((DevicePathType (Option
->DevicePath
) == BBS_DEVICE_PATH
) &&
188 (DevicePathSubType (Option
->DevicePath
) == BBS_BBS_DP
)
191 // Check to see if we should legacy BOOT. If yes then do the legacy boot
193 return BdsLibDoLegacyBoot (Option
);
196 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Booting EFI 1.1 way %S\n", Option
->Description
));
198 Status
= gBS
->LoadImage (
208 // If we didn't find an image, we may need to load the default
209 // boot behavior for the device.
211 if (EFI_ERROR (Status
)) {
213 // Find a Simple File System protocol on the device path. If the remaining
214 // device path is set to end then no Files are being specified, so try
215 // the removable media file name.
217 TempDevicePath
= DevicePath
;
218 Status
= gBS
->LocateDevicePath (
219 &gEfiSimpleFileSystemProtocolGuid
,
223 if (!EFI_ERROR (Status
) && IsDevicePathEnd (TempDevicePath
)) {
224 FilePath
= FileDevicePath (Handle
, EFI_REMOVABLE_MEDIA_FILE_NAME
);
227 // Issue a dummy read to the device to check for media change.
228 // When the removable media is changed, any Block IO read/write will
229 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
230 // returned. After the Block IO protocol is reinstalled, subsequent
231 // Block IO read/write will success.
233 Status
= gBS
->HandleProtocol (
235 &gEfiBlockIoProtocolGuid
,
238 if (!EFI_ERROR (Status
)) {
239 Buffer
= AllocatePool (BlkIo
->Media
->BlockSize
);
240 if (Buffer
!= NULL
) {
243 BlkIo
->Media
->MediaId
,
245 BlkIo
->Media
->BlockSize
,
252 Status
= gBS
->LoadImage (
260 if (EFI_ERROR (Status
)) {
262 // The DevicePath failed, and it's not a valid
263 // removable media device.
269 Status
= EFI_NOT_FOUND
;
273 if (EFI_ERROR (Status
)) {
275 // It there is any error from the Boot attempt exit now.
280 // Provide the image with it's load options
282 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
283 ASSERT_EFI_ERROR (Status
);
285 if (Option
->LoadOptionsSize
!= 0) {
286 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
287 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
290 // Before calling the image, enable the Watchdog Timer for
291 // the 5 Minute period
293 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
295 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
296 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
299 // Clear the Watchdog Timer after the image returns
301 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
305 // Clear Boot Current
309 &gEfiGlobalVariableGuid
,
310 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
319 BdsBootByDiskSignatureAndPartition (
320 IN BDS_COMMON_OPTION
* Option
,
321 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
322 IN UINT32 LoadOptionsSize
,
323 IN VOID
*LoadOptions
,
324 OUT UINTN
*ExitDataSize
,
325 OUT CHAR16
**ExitData OPTIONAL
331 Check to see if a hard ware device path was passed in. If it was then search
332 all the block IO devices for the passed in hard drive device path.
336 Option - The current processing boot option.
338 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
341 LoadOptionsSize - Passed into gBS->StartImage ()
342 via the loaded image protocol.
344 LoadOptions - Passed into gBS->StartImage ()
345 via the loaded image protocol.
347 ExitDataSize - returned directly from gBS->StartImage ()
349 ExitData - returned directly from gBS->StartImage ()
353 EFI_SUCCESS - Status from gBS->StartImage (),
354 or BootByDiskSignatureAndPartition ()
356 EFI_NOT_FOUND - If the Device Path is not found in the system
361 UINTN BlockIoHandleCount
;
362 EFI_HANDLE
*BlockIoBuffer
;
363 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
364 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
365 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
366 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
367 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
369 BOOLEAN DevicePathMatch
;
370 HARDDRIVE_DEVICE_PATH
*TempPath
;
375 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
376 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
379 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
382 return EFI_NOT_FOUND
;
385 // The boot device have already been connected
387 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
388 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
390 // If there was an error or there are no device handles that support
391 // the BLOCK_IO Protocol, then return.
393 return EFI_NOT_FOUND
;
396 // Loop through all the device handles that support the BLOCK_IO Protocol
398 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
400 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
401 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
405 // Make PreviousDevicePath == the device path node before the end node
407 DevicePath
= BlockIoDevicePath
;
408 BlockIoHdDevicePath
= NULL
;
411 // find HardDriver device path node
413 while (!IsDevicePathEnd (DevicePath
)) {
414 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
415 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
417 BlockIoHdDevicePath
= DevicePath
;
421 DevicePath
= NextDevicePathNode (DevicePath
);
424 if (BlockIoHdDevicePath
== NULL
) {
428 // See if the harddrive device path in blockio matches the orig Hard Drive Node
430 DevicePathMatch
= FALSE
;
432 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
433 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
436 // Only several fields will be checked. NOT whole NODE
438 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
439 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
440 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
441 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
443 // Get the matched device path
445 DevicePathMatch
= TRUE
;
448 // Only do the boot, when devicepath match
450 if (DevicePathMatch
) {
452 // Combine the Block IO and Hard Drive Device path together and try
455 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
456 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
459 // Recursive boot with new device path
461 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
462 if (!EFI_ERROR (Status
)) {
468 FreePool (BlockIoBuffer
);
473 BdsLibDeleteOptionFromHandle (
480 Delete the boot option associated with the handle passed in
484 Handle - The handle which present the device path to create boot option
488 EFI_SUCCESS - Delete the boot option success
490 EFI_NOT_FOUND - If the Device Path is not found in the system
492 EFI_OUT_OF_RESOURCES - Lack of memory resource
494 Other - Error return value from SetVariable()
499 UINT8
*BootOptionVar
;
501 UINTN BootOptionSize
;
504 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
505 UINTN DevicePathSize
;
506 UINTN OptionDevicePathSize
;
507 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
508 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
512 Status
= EFI_SUCCESS
;
516 BootOrder
= BdsLibGetVariableAndSize (
518 &gEfiGlobalVariableGuid
,
521 if (NULL
== BootOrder
) {
522 return EFI_NOT_FOUND
;
525 DevicePath
= DevicePathFromHandle (Handle
);
526 if (DevicePath
== NULL
) {
527 return EFI_NOT_FOUND
;
529 DevicePathSize
= GetDevicePathSize (DevicePath
);
532 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
533 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
534 BootOptionVar
= BdsLibGetVariableAndSize (
536 &gEfiGlobalVariableGuid
,
539 if (NULL
== BootOptionVar
) {
540 FreePool (BootOrder
);
541 return EFI_OUT_OF_RESOURCES
;
544 TempPtr
= BootOptionVar
;
545 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
546 Description
= (CHAR16
*) TempPtr
;
547 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
548 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
549 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
552 // Check whether the device path match
554 if ((OptionDevicePathSize
== DevicePathSize
) &&
555 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
556 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
557 FreePool (BootOptionVar
);
561 FreePool (BootOptionVar
);
565 Status
= gRT
->SetVariable (
567 &gEfiGlobalVariableGuid
,
568 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
573 FreePool (BootOrder
);
579 BdsDeleteAllInvalidEfiBootOption (
586 Delete all invalid EFI boot options. The probable invalid boot option could
587 be Removable media or Network boot device.
595 EFI_SUCCESS - Delete all invalid boot option success
597 EFI_NOT_FOUND - Variable "BootOrder" is not found
599 EFI_OUT_OF_RESOURCES - Lack of memory resource
601 Other - Error return value from SetVariable()
606 UINT8
*BootOptionVar
;
608 UINTN BootOptionSize
;
612 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
613 UINTN OptionDevicePathSize
;
614 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
615 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
616 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
622 Status
= EFI_SUCCESS
;
626 BootOrder
= BdsLibGetVariableAndSize (
628 &gEfiGlobalVariableGuid
,
631 if (NULL
== BootOrder
) {
632 return EFI_NOT_FOUND
;
636 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
637 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
638 BootOptionVar
= BdsLibGetVariableAndSize (
640 &gEfiGlobalVariableGuid
,
643 if (NULL
== BootOptionVar
) {
644 FreePool (BootOrder
);
645 return EFI_OUT_OF_RESOURCES
;
648 TempPtr
= BootOptionVar
;
649 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
650 Description
= (CHAR16
*) TempPtr
;
651 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
652 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
653 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
656 // Skip legacy boot option (BBS boot device)
658 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
659 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
660 FreePool (BootOptionVar
);
665 TempDevicePath
= OptionDevicePath
;
666 LastDeviceNode
= OptionDevicePath
;
667 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
668 LastDeviceNode
= TempDevicePath
;
669 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
672 // Skip the boot option that point to a file, since the device path in
673 // removable media boot option doesn't contains a file name.
675 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
676 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
678 // Skip boot option for internal Shell, it's always valid
680 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
681 FreePool (BootOptionVar
);
688 // Check if it's a valid boot option for removable media
690 TempDevicePath
= OptionDevicePath
;
691 Status
= gBS
->LocateDevicePath (
692 &gEfiSimpleFileSystemProtocolGuid
,
696 if (!EFI_ERROR (Status
)) {
700 // Check if it's a valid boot option for network boot device
702 TempDevicePath
= OptionDevicePath
;
703 Status
= gBS
->LocateDevicePath (
704 &gEfiLoadFileProtocolGuid
,
708 if (!EFI_ERROR (Status
)) {
714 // Delete this invalid boot option "Boot####"
716 Status
= gRT
->SetVariable (
718 &gEfiGlobalVariableGuid
,
719 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
724 // Mark this boot option in boot order as deleted
726 BootOrder
[Index
] = 0xffff;
729 FreePool (BootOptionVar
);
734 // Adjust boot order array
737 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
738 if (BootOrder
[Index
] != 0xffff) {
739 BootOrder
[Index2
] = BootOrder
[Index
];
743 Status
= gRT
->SetVariable (
745 &gEfiGlobalVariableGuid
,
746 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
747 Index2
* sizeof (UINT16
),
751 FreePool (BootOrder
);
757 BdsLibEnumerateAllBootOption (
758 IN OUT LIST_ENTRY
*BdsBootOptionList
764 This function will enumerate all possible boot device in the system,
765 it will only excute once of every boot.
769 BdsBootOptionList - The header of the link list which indexed all
774 EFI_SUCCESS - Finished all the boot device enumerate and create
775 the boot option base on that boot device
780 UINT16 BootOptionNumber
;
781 UINTN NumberFileSystemHandles
;
782 EFI_HANDLE
*FileSystemHandles
;
783 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
785 UINTN NumberLoadFileHandles
;
786 EFI_HANDLE
*LoadFileHandles
;
787 VOID
*ProtocolInstance
;
788 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
790 EFI_HANDLE
*FvHandleBuffer
;
791 EFI_FV_FILETYPE Type
;
793 EFI_FV_FILE_ATTRIBUTES Attributes
;
794 UINT32 AuthenticationStatus
;
795 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
796 EFI_HANDLE ImageHandle
;
797 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
800 BootOptionNumber
= 0;
803 // If the boot device enumerate happened, just get the boot
804 // device from the boot order variable
806 if (mEnumBootDevice
) {
807 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
811 // Notes: this dirty code is to get the legacy boot option from the
812 // BBS table and create to variable as the EFI boot option, it should
813 // be removed after the CSM can provide legacy boot option directly
815 REFRESH_LEGACY_BOOT_OPTIONS
;
818 // Delete invalid boot option
820 BdsDeleteAllInvalidEfiBootOption ();
822 // Parse removable media
824 gBS
->LocateHandleBuffer (
826 &gEfiSimpleFileSystemProtocolGuid
,
828 &NumberFileSystemHandles
,
831 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
832 Status
= gBS
->HandleProtocol (
833 FileSystemHandles
[Index
],
834 &gEfiBlockIoProtocolGuid
,
837 if (!EFI_ERROR (Status
)) {
838 if (!BlkIo
->Media
->RemovableMedia
) {
840 // If the file system handle supports a BlkIo protocol,
841 // skip the removable media devices
848 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
849 // machinename is ia32, ia64, x64, ...
851 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
853 Status
= gBS
->LoadImage (
861 if (!EFI_ERROR(Status
)) {
863 // Verify the image is a EFI application (and not a driver)
865 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
866 ASSERT (!EFI_ERROR(Status
));
868 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
875 // No such file or the file is not a EFI application, delete this boot option
877 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
879 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
884 if (NumberFileSystemHandles
) {
885 FreePool (FileSystemHandles
);
888 // Parse Network Boot Device
890 gBS
->LocateHandleBuffer (
892 &gEfiSimpleNetworkProtocolGuid
,
894 &NumberLoadFileHandles
,
897 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
898 Status
= gBS
->HandleProtocol (
899 LoadFileHandles
[Index
],
900 &gEfiLoadFileProtocolGuid
,
901 (VOID
**) &ProtocolInstance
903 if (EFI_ERROR (Status
)) {
907 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
911 if (NumberLoadFileHandles
) {
912 FreePool (LoadFileHandles
);
915 // Check if we have on flash shell
917 gBS
->LocateHandleBuffer (
919 &gEfiFirmwareVolumeProtocolGuid
,
924 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
925 gBS
->HandleProtocol (
926 FvHandleBuffer
[Index
],
927 &gEfiFirmwareVolumeProtocolGuid
,
931 Status
= Fv
->ReadFile (
938 &AuthenticationStatus
940 if (EFI_ERROR (Status
)) {
942 // Skip if no shell file in the FV
947 // Build the shell boot option
949 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
954 FreePool (FvHandleBuffer
);
957 // Make sure every boot only have one time
958 // boot device enumerate
960 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
961 mEnumBootDevice
= TRUE
;
967 BdsLibBuildOptionFromHandle (
968 IN EFI_HANDLE Handle
,
969 IN LIST_ENTRY
*BdsBootOptionList
975 Build the boot option with the handle parsed in
979 Handle - The handle which present the device path to create boot option
981 BdsBootOptionList - The header of the link list which indexed all current
990 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
993 DevicePath
= DevicePathFromHandle (Handle
);
994 TempString
= DevicePathToStr (DevicePath
);
997 // Create and register new boot option
999 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
1003 BdsLibBuildOptionFromShell (
1004 IN EFI_HANDLE Handle
,
1005 IN OUT LIST_ENTRY
*BdsBootOptionList
1009 Routine Description:
1011 Build the on flash shell boot option with the handle parsed in
1015 Handle - The handle which present the device path to create on flash shell
1018 BdsBootOptionList - The header of the link list which indexed all current
1027 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1028 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1030 DevicePath
= DevicePathFromHandle (Handle
);
1033 // Build the shell device path
1035 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1036 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1039 // Create and register the shell boot option
1041 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1051 Routine Description:
1053 Boot from the EFI1.1 spec defined "BootNext" variable
1068 BDS_COMMON_OPTION
*BootOption
;
1069 LIST_ENTRY TempList
;
1074 // Init the boot option name buffer and temp link list
1076 InitializeListHead (&TempList
);
1077 ZeroMem (Buffer
, sizeof (Buffer
));
1079 BootNext
= BdsLibGetVariableAndSize (
1081 &gEfiGlobalVariableGuid
,
1086 // Clear the boot next variable first
1088 if (BootNext
!= NULL
) {
1091 &gEfiGlobalVariableGuid
,
1092 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1098 // Start to build the boot option and try to boot
1100 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1101 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1102 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1103 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);