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 EfiSignalEventReadyToBoot ();
169 &gEfiGlobalVariableGuid
,
170 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
175 if ((DevicePathType (Option
->DevicePath
) == BBS_DEVICE_PATH
) &&
176 (DevicePathSubType (Option
->DevicePath
) == BBS_BBS_DP
)
179 // Check to see if we should legacy BOOT. If yes then do the legacy boot
181 return BdsLibDoLegacyBoot (Option
);
184 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Booting EFI 1.1 way %S\n", Option
->Description
));
186 Status
= gBS
->LoadImage (
196 // If we didn't find an image, we may need to load the default
197 // boot behavior for the device.
199 if (EFI_ERROR (Status
)) {
201 // Find a Simple File System protocol on the device path. If the remaining
202 // device path is set to end then no Files are being specified, so try
203 // the removable media file name.
205 TempDevicePath
= DevicePath
;
206 Status
= gBS
->LocateDevicePath (
207 &gEfiSimpleFileSystemProtocolGuid
,
211 if (!EFI_ERROR (Status
) && IsDevicePathEnd (TempDevicePath
)) {
212 FilePath
= FileDevicePath (Handle
, EFI_REMOVABLE_MEDIA_FILE_NAME
);
215 // Issue a dummy read to the device to check for media change.
216 // When the removable media is changed, any Block IO read/write will
217 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
218 // returned. After the Block IO protocol is reinstalled, subsequent
219 // Block IO read/write will success.
221 Status
= gBS
->HandleProtocol (
223 &gEfiBlockIoProtocolGuid
,
226 if (!EFI_ERROR (Status
)) {
227 Buffer
= AllocatePool (BlkIo
->Media
->BlockSize
);
228 if (Buffer
!= NULL
) {
231 BlkIo
->Media
->MediaId
,
233 BlkIo
->Media
->BlockSize
,
236 gBS
->FreePool (Buffer
);
240 Status
= gBS
->LoadImage (
248 if (EFI_ERROR (Status
)) {
250 // The DevicePath failed, and it's not a valid
251 // removable media device.
257 Status
= EFI_NOT_FOUND
;
261 if (EFI_ERROR (Status
)) {
263 // It there is any error from the Boot attempt exit now.
268 // Provide the image with it's load options
270 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
271 ASSERT_EFI_ERROR (Status
);
273 if (Option
->LoadOptionsSize
!= 0) {
274 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
275 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
278 // Before calling the image, enable the Watchdog Timer for
279 // the 5 Minute period
281 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
283 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
284 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
287 // Clear the Watchdog Timer after the image returns
289 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
293 // Clear Boot Current
297 &gEfiGlobalVariableGuid
,
298 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
307 BdsBootByDiskSignatureAndPartition (
308 IN BDS_COMMON_OPTION
* Option
,
309 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
310 IN UINT32 LoadOptionsSize
,
311 IN VOID
*LoadOptions
,
312 OUT UINTN
*ExitDataSize
,
313 OUT CHAR16
**ExitData OPTIONAL
319 Check to see if a hard ware device path was passed in. If it was then search
320 all the block IO devices for the passed in hard drive device path.
324 Option - The current processing boot option.
326 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
329 LoadOptionsSize - Passed into gBS->StartImage ()
330 via the loaded image protocol.
332 LoadOptions - Passed into gBS->StartImage ()
333 via the loaded image protocol.
335 ExitDataSize - returned directly from gBS->StartImage ()
337 ExitData - returned directly from gBS->StartImage ()
341 EFI_SUCCESS - Status from gBS->StartImage (),
342 or BootByDiskSignatureAndPartition ()
344 EFI_NOT_FOUND - If the Device Path is not found in the system
349 UINTN BlockIoHandleCount
;
350 EFI_HANDLE
*BlockIoBuffer
;
351 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
352 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
353 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
354 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
355 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
357 BOOLEAN DevicePathMatch
;
358 HARDDRIVE_DEVICE_PATH
*TempPath
;
363 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
364 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
367 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
370 return EFI_NOT_FOUND
;
373 // The boot device have already been connected
375 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
376 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
378 // If there was an error or there are no device handles that support
379 // the BLOCK_IO Protocol, then return.
381 return EFI_NOT_FOUND
;
384 // Loop through all the device handles that support the BLOCK_IO Protocol
386 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
388 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
389 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
393 // Make PreviousDevicePath == the device path node before the end node
395 DevicePath
= BlockIoDevicePath
;
396 BlockIoHdDevicePath
= NULL
;
399 // find HardDriver device path node
401 while (!IsDevicePathEnd (DevicePath
)) {
402 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
403 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
405 BlockIoHdDevicePath
= DevicePath
;
409 DevicePath
= NextDevicePathNode (DevicePath
);
412 if (BlockIoHdDevicePath
== NULL
) {
416 // See if the harddrive device path in blockio matches the orig Hard Drive Node
418 DevicePathMatch
= FALSE
;
420 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
421 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
424 // Only several fields will be checked. NOT whole NODE
426 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
427 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
428 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
429 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
431 // Get the matched device path
433 DevicePathMatch
= TRUE
;
436 // Only do the boot, when devicepath match
438 if (DevicePathMatch
) {
440 // Combine the Block IO and Hard Drive Device path together and try
443 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
444 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
447 // Recursive boot with new device path
449 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
450 if (!EFI_ERROR (Status
)) {
456 gBS
->FreePool (BlockIoBuffer
);
461 BdsLibDeleteOptionFromHandle (
468 Delete the boot option associated with the handle passed in
472 Handle - The handle which present the device path to create boot option
476 EFI_SUCCESS - Delete the boot option success
478 EFI_NOT_FOUND - If the Device Path is not found in the system
480 EFI_OUT_OF_RESOURCES - Lack of memory resource
482 Other - Error return value from SetVariable()
487 UINT8
*BootOptionVar
;
489 UINTN BootOptionSize
;
492 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
493 UINTN DevicePathSize
;
494 UINTN OptionDevicePathSize
;
495 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
496 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
500 Status
= EFI_SUCCESS
;
504 BootOrder
= BdsLibGetVariableAndSize (
506 &gEfiGlobalVariableGuid
,
509 if (NULL
== BootOrder
) {
510 return EFI_NOT_FOUND
;
513 DevicePath
= DevicePathFromHandle (Handle
);
514 if (DevicePath
== NULL
) {
515 return EFI_NOT_FOUND
;
517 DevicePathSize
= GetDevicePathSize (DevicePath
);
520 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
521 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
522 BootOptionVar
= BdsLibGetVariableAndSize (
524 &gEfiGlobalVariableGuid
,
527 if (NULL
== BootOptionVar
) {
528 gBS
->FreePool (BootOrder
);
529 return EFI_OUT_OF_RESOURCES
;
532 TempPtr
= BootOptionVar
;
533 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
534 Description
= (CHAR16
*) TempPtr
;
535 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
536 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
537 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
540 // Check whether the device path match
542 if ((OptionDevicePathSize
== DevicePathSize
) &&
543 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
544 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
545 gBS
->FreePool (BootOptionVar
);
549 gBS
->FreePool (BootOptionVar
);
553 Status
= gRT
->SetVariable (
555 &gEfiGlobalVariableGuid
,
556 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
561 gBS
->FreePool (BootOrder
);
567 BdsDeleteAllInvalidEfiBootOption (
574 Delete all invalid EFI boot options. The probable invalid boot option could
575 be Removable media or Network boot device.
583 EFI_SUCCESS - Delete all invalid boot option success
585 EFI_NOT_FOUND - Variable "BootOrder" is not found
587 EFI_OUT_OF_RESOURCES - Lack of memory resource
589 Other - Error return value from SetVariable()
594 UINT8
*BootOptionVar
;
596 UINTN BootOptionSize
;
600 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
601 UINTN OptionDevicePathSize
;
602 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
603 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
604 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
610 Status
= EFI_SUCCESS
;
614 BootOrder
= BdsLibGetVariableAndSize (
616 &gEfiGlobalVariableGuid
,
619 if (NULL
== BootOrder
) {
620 return EFI_NOT_FOUND
;
624 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
625 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
626 BootOptionVar
= BdsLibGetVariableAndSize (
628 &gEfiGlobalVariableGuid
,
631 if (NULL
== BootOptionVar
) {
632 gBS
->FreePool (BootOrder
);
633 return EFI_OUT_OF_RESOURCES
;
636 TempPtr
= BootOptionVar
;
637 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
638 Description
= (CHAR16
*) TempPtr
;
639 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
640 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
641 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
644 // Skip legacy boot option (BBS boot device)
646 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
647 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
648 gBS
->FreePool (BootOptionVar
);
653 TempDevicePath
= OptionDevicePath
;
654 LastDeviceNode
= OptionDevicePath
;
655 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
656 LastDeviceNode
= TempDevicePath
;
657 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
660 // Skip the boot option that point to a file, since the device path in
661 // removable media boot option doesn't contains a file name.
663 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
664 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
666 // Skip boot option for internal Shell, it's always valid
668 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
669 gBS
->FreePool (BootOptionVar
);
676 // Check if it's a valid boot option for removable media
678 TempDevicePath
= OptionDevicePath
;
679 Status
= gBS
->LocateDevicePath (
680 &gEfiSimpleFileSystemProtocolGuid
,
684 if (!EFI_ERROR (Status
)) {
688 // Check if it's a valid boot option for network boot device
690 TempDevicePath
= OptionDevicePath
;
691 Status
= gBS
->LocateDevicePath (
692 &gEfiLoadFileProtocolGuid
,
696 if (!EFI_ERROR (Status
)) {
702 // Delete this invalid boot option "Boot####"
704 Status
= gRT
->SetVariable (
706 &gEfiGlobalVariableGuid
,
707 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
712 // Mark this boot option in boot order as deleted
714 BootOrder
[Index
] = 0xffff;
717 gBS
->FreePool (BootOptionVar
);
722 // Adjust boot order array
725 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
726 if (BootOrder
[Index
] != 0xffff) {
727 BootOrder
[Index2
] = BootOrder
[Index
];
731 Status
= gRT
->SetVariable (
733 &gEfiGlobalVariableGuid
,
734 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
735 Index2
* sizeof (UINT16
),
739 gBS
->FreePool (BootOrder
);
745 BdsLibEnumerateAllBootOption (
746 IN OUT LIST_ENTRY
*BdsBootOptionList
752 This function will enumerate all possible boot device in the system,
753 it will only excute once of every boot.
757 BdsBootOptionList - The header of the link list which indexed all
762 EFI_SUCCESS - Finished all the boot device enumerate and create
763 the boot option base on that boot device
768 UINT16 BootOptionNumber
;
769 UINTN NumberFileSystemHandles
;
770 EFI_HANDLE
*FileSystemHandles
;
771 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
773 UINTN NumberLoadFileHandles
;
774 EFI_HANDLE
*LoadFileHandles
;
775 VOID
*ProtocolInstance
;
776 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
778 EFI_HANDLE
*FvHandleBuffer
;
779 EFI_FV_FILETYPE Type
;
781 EFI_FV_FILE_ATTRIBUTES Attributes
;
782 UINT32 AuthenticationStatus
;
783 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
784 EFI_HANDLE ImageHandle
;
785 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
788 BootOptionNumber
= 0;
791 // If the boot device enumerate happened, just get the boot
792 // device from the boot order variable
794 if (mEnumBootDevice
) {
795 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
799 // Notes: this dirty code is to get the legacy boot option from the
800 // BBS table and create to variable as the EFI boot option, it should
801 // be removed after the CSM can provide legacy boot option directly
803 REFRESH_LEGACY_BOOT_OPTIONS
;
806 // Delete invalid boot option
808 BdsDeleteAllInvalidEfiBootOption ();
810 // Parse removable media
812 gBS
->LocateHandleBuffer (
814 &gEfiSimpleFileSystemProtocolGuid
,
816 &NumberFileSystemHandles
,
819 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
820 Status
= gBS
->HandleProtocol (
821 FileSystemHandles
[Index
],
822 &gEfiBlockIoProtocolGuid
,
825 if (!EFI_ERROR (Status
)) {
826 if (!BlkIo
->Media
->RemovableMedia
) {
828 // If the file system handle supports a BlkIo protocol,
829 // skip the removable media devices
836 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
837 // machinename is ia32, ia64, x64, ...
839 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
841 Status
= gBS
->LoadImage (
849 if (!EFI_ERROR(Status
)) {
851 // Verify the image is a EFI application (and not a driver)
853 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
854 ASSERT (!EFI_ERROR(Status
));
856 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
863 // No such file or the file is not a EFI application, delete this boot option
865 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
867 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
872 if (NumberFileSystemHandles
) {
873 gBS
->FreePool (FileSystemHandles
);
876 // Parse Network Boot Device
878 gBS
->LocateHandleBuffer (
880 &gEfiSimpleNetworkProtocolGuid
,
882 &NumberLoadFileHandles
,
885 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
886 Status
= gBS
->HandleProtocol (
887 LoadFileHandles
[Index
],
888 &gEfiLoadFileProtocolGuid
,
889 (VOID
**) &ProtocolInstance
891 if (EFI_ERROR (Status
)) {
895 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
899 if (NumberLoadFileHandles
) {
900 gBS
->FreePool (LoadFileHandles
);
903 // Check if we have on flash shell
905 gBS
->LocateHandleBuffer (
907 &gEfiFirmwareVolumeProtocolGuid
,
912 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
913 gBS
->HandleProtocol (
914 FvHandleBuffer
[Index
],
915 &gEfiFirmwareVolumeProtocolGuid
,
919 Status
= Fv
->ReadFile (
926 &AuthenticationStatus
928 if (EFI_ERROR (Status
)) {
930 // Skip if no shell file in the FV
935 // Build the shell boot option
937 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
942 gBS
->FreePool (FvHandleBuffer
);
945 // Make sure every boot only have one time
946 // boot device enumerate
948 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
949 mEnumBootDevice
= TRUE
;
955 BdsLibBuildOptionFromHandle (
956 IN EFI_HANDLE Handle
,
957 IN LIST_ENTRY
*BdsBootOptionList
963 Build the boot option with the handle parsed in
967 Handle - The handle which present the device path to create boot option
969 BdsBootOptionList - The header of the link list which indexed all current
978 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
981 DevicePath
= DevicePathFromHandle (Handle
);
982 TempString
= DevicePathToStr (DevicePath
);
985 // Create and register new boot option
987 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
991 BdsLibBuildOptionFromShell (
992 IN EFI_HANDLE Handle
,
993 IN OUT LIST_ENTRY
*BdsBootOptionList
999 Build the on flash shell boot option with the handle parsed in
1003 Handle - The handle which present the device path to create on flash shell
1006 BdsBootOptionList - The header of the link list which indexed all current
1015 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1016 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1018 DevicePath
= DevicePathFromHandle (Handle
);
1021 // Build the shell device path
1023 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1024 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1027 // Create and register the shell boot option
1029 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1039 Routine Description:
1041 Boot from the EFI1.1 spec defined "BootNext" variable
1056 BDS_COMMON_OPTION
*BootOption
;
1057 LIST_ENTRY TempList
;
1062 // Init the boot option name buffer and temp link list
1064 InitializeListHead (&TempList
);
1065 ZeroMem (Buffer
, sizeof (Buffer
));
1067 BootNext
= BdsLibGetVariableAndSize (
1069 &gEfiGlobalVariableGuid
,
1074 // Clear the boot next variable first
1076 if (BootNext
!= NULL
) {
1079 &gEfiGlobalVariableGuid
,
1080 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1086 // Start to build the boot option and try to boot
1088 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1089 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1090 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1091 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);