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
;
128 // Record the performance data for End of BDS
130 PERF_END (0, BDS_TOK
, NULL
, 0);
136 // Notes: put EFI64 ROM Shadow Solution
138 EFI64_SHADOW_ALL_LEGACY_ROM ();
141 // Notes: this code can be remove after the s3 script table
142 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
143 // EFI_EVENT_SIGNAL_LEGACY_BOOT
145 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
,
146 (VOID
**)&AcpiS3Save
);
147 if (!EFI_ERROR (Status
)) {
148 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
151 // If it's Device Path that starts with a hard drive path,
152 // this routine will do the booting.
154 Status
= BdsBootByDiskSignatureAndPartition (
156 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
157 Option
->LoadOptionsSize
,
162 if (!EFI_ERROR (Status
)) {
164 // If we found a disk signature and partition device path return success
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
,
278 (VOID
**) &ImageInfo
);
279 ASSERT_EFI_ERROR (Status
);
281 if (Option
->LoadOptionsSize
!= 0) {
282 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
283 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
286 // Before calling the image, enable the Watchdog Timer for
287 // the 5 Minute period
289 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
291 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
292 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
295 // Clear the Watchdog Timer after the image returns
297 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
301 // Clear Boot Current
305 &gEfiGlobalVariableGuid
,
306 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
315 BdsBootByDiskSignatureAndPartition (
316 IN BDS_COMMON_OPTION
* Option
,
317 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
318 IN UINT32 LoadOptionsSize
,
319 IN VOID
*LoadOptions
,
320 OUT UINTN
*ExitDataSize
,
321 OUT CHAR16
**ExitData OPTIONAL
327 Check to see if a hard ware device path was passed in. If it was then search
328 all the block IO devices for the passed in hard drive device path.
332 Option - The current processing boot option.
334 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
337 LoadOptionsSize - Passed into gBS->StartImage ()
338 via the loaded image protocol.
340 LoadOptions - Passed into gBS->StartImage ()
341 via the loaded image protocol.
343 ExitDataSize - returned directly from gBS->StartImage ()
345 ExitData - returned directly from gBS->StartImage ()
349 EFI_SUCCESS - Status from gBS->StartImage (),
350 or BootByDiskSignatureAndPartition ()
352 EFI_NOT_FOUND - If the Device Path is not found in the system
357 UINTN BlockIoHandleCount
;
358 EFI_HANDLE
*BlockIoBuffer
;
359 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
360 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
361 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
362 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
363 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
365 BOOLEAN DevicePathMatch
;
366 HARDDRIVE_DEVICE_PATH
*TempPath
;
371 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
372 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
375 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
378 return EFI_NOT_FOUND
;
381 // The boot device have already been connected
383 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
384 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
386 // If there was an error or there are no device handles that support
387 // the BLOCK_IO Protocol, then return.
389 return EFI_NOT_FOUND
;
392 // Loop through all the device handles that support the BLOCK_IO Protocol
394 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
396 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
397 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
401 // Make PreviousDevicePath == the device path node before the end node
403 DevicePath
= BlockIoDevicePath
;
404 BlockIoHdDevicePath
= NULL
;
407 // find HardDriver device path node
409 while (!IsDevicePathEnd (DevicePath
)) {
410 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
411 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
413 BlockIoHdDevicePath
= DevicePath
;
417 DevicePath
= NextDevicePathNode (DevicePath
);
420 if (BlockIoHdDevicePath
== NULL
) {
424 // See if the harddrive device path in blockio matches the orig Hard Drive Node
426 DevicePathMatch
= FALSE
;
428 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
429 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
432 // Only several fields will be checked. NOT whole NODE
434 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
435 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
436 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
437 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
439 // Get the matched device path
441 DevicePathMatch
= TRUE
;
444 // Only do the boot, when devicepath match
446 if (DevicePathMatch
) {
448 // Combine the Block IO and Hard Drive Device path together and try
451 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
452 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
455 // Recursive boot with new device path
457 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
458 if (!EFI_ERROR (Status
)) {
464 gBS
->FreePool (BlockIoBuffer
);
469 BdsLibDeleteOptionFromHandle (
476 Delete the boot option associated with the handle passed in
480 Handle - The handle which present the device path to create boot option
484 EFI_SUCCESS - Delete the boot option success
486 EFI_NOT_FOUND - If the Device Path is not found in the system
488 EFI_OUT_OF_RESOURCES - Lack of memory resource
490 Other - Error return value from SetVariable()
495 UINT8
*BootOptionVar
;
497 UINTN BootOptionSize
;
500 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
501 UINTN DevicePathSize
;
502 UINTN OptionDevicePathSize
;
503 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
504 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
508 Status
= EFI_SUCCESS
;
512 BootOrder
= BdsLibGetVariableAndSize (
514 &gEfiGlobalVariableGuid
,
517 if (NULL
== BootOrder
) {
518 return EFI_NOT_FOUND
;
521 DevicePath
= DevicePathFromHandle (Handle
);
522 if (DevicePath
== NULL
) {
523 return EFI_NOT_FOUND
;
525 DevicePathSize
= GetDevicePathSize (DevicePath
);
528 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
529 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
530 BootOptionVar
= BdsLibGetVariableAndSize (
532 &gEfiGlobalVariableGuid
,
535 if (NULL
== BootOptionVar
) {
536 gBS
->FreePool (BootOrder
);
537 return EFI_OUT_OF_RESOURCES
;
540 TempPtr
= BootOptionVar
;
541 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
542 Description
= (CHAR16
*) TempPtr
;
543 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
544 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
545 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
548 // Check whether the device path match
550 if ((OptionDevicePathSize
== DevicePathSize
) &&
551 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
552 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
553 gBS
->FreePool (BootOptionVar
);
557 gBS
->FreePool (BootOptionVar
);
561 Status
= gRT
->SetVariable (
563 &gEfiGlobalVariableGuid
,
564 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
569 gBS
->FreePool (BootOrder
);
575 BdsDeleteAllInvalidEfiBootOption (
582 Delete all invalid EFI boot options. The probable invalid boot option could
583 be Removable media or Network boot device.
591 EFI_SUCCESS - Delete all invalid boot option success
593 EFI_NOT_FOUND - Variable "BootOrder" is not found
595 EFI_OUT_OF_RESOURCES - Lack of memory resource
597 Other - Error return value from SetVariable()
602 UINT8
*BootOptionVar
;
604 UINTN BootOptionSize
;
608 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
609 UINTN OptionDevicePathSize
;
610 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
611 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
612 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
618 Status
= EFI_SUCCESS
;
622 BootOrder
= BdsLibGetVariableAndSize (
624 &gEfiGlobalVariableGuid
,
627 if (NULL
== BootOrder
) {
628 return EFI_NOT_FOUND
;
632 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
633 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
634 BootOptionVar
= BdsLibGetVariableAndSize (
636 &gEfiGlobalVariableGuid
,
639 if (NULL
== BootOptionVar
) {
640 gBS
->FreePool (BootOrder
);
641 return EFI_OUT_OF_RESOURCES
;
644 TempPtr
= BootOptionVar
;
645 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
646 Description
= (CHAR16
*) TempPtr
;
647 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
648 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
649 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
652 // Skip legacy boot option (BBS boot device)
654 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
655 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
656 gBS
->FreePool (BootOptionVar
);
661 TempDevicePath
= OptionDevicePath
;
662 LastDeviceNode
= OptionDevicePath
;
663 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
664 LastDeviceNode
= TempDevicePath
;
665 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
668 // Skip the boot option that point to a file, since the device path in
669 // removable media boot option doesn't contains a file name.
671 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
672 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
674 // Skip boot option for internal Shell, it's always valid
676 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
677 gBS
->FreePool (BootOptionVar
);
684 // Check if it's a valid boot option for removable media
686 TempDevicePath
= OptionDevicePath
;
687 Status
= gBS
->LocateDevicePath (
688 &gEfiSimpleFileSystemProtocolGuid
,
692 if (!EFI_ERROR (Status
)) {
696 // Check if it's a valid boot option for network boot device
698 TempDevicePath
= OptionDevicePath
;
699 Status
= gBS
->LocateDevicePath (
700 &gEfiLoadFileProtocolGuid
,
704 if (!EFI_ERROR (Status
)) {
710 // Delete this invalid boot option "Boot####"
712 Status
= gRT
->SetVariable (
714 &gEfiGlobalVariableGuid
,
715 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
720 // Mark this boot option in boot order as deleted
722 BootOrder
[Index
] = 0xffff;
725 gBS
->FreePool (BootOptionVar
);
730 // Adjust boot order array
733 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
734 if (BootOrder
[Index
] != 0xffff) {
735 BootOrder
[Index2
] = BootOrder
[Index
];
739 Status
= gRT
->SetVariable (
741 &gEfiGlobalVariableGuid
,
742 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
743 Index2
* sizeof (UINT16
),
747 gBS
->FreePool (BootOrder
);
753 BdsLibEnumerateAllBootOption (
754 IN OUT LIST_ENTRY
*BdsBootOptionList
760 This function will enumerate all possible boot device in the system,
761 it will only excute once of every boot.
765 BdsBootOptionList - The header of the link list which indexed all
770 EFI_SUCCESS - Finished all the boot device enumerate and create
771 the boot option base on that boot device
776 UINT16 BootOptionNumber
;
777 UINTN NumberFileSystemHandles
;
778 EFI_HANDLE
*FileSystemHandles
;
779 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
781 UINTN NumberLoadFileHandles
;
782 EFI_HANDLE
*LoadFileHandles
;
783 VOID
*ProtocolInstance
;
784 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
786 EFI_HANDLE
*FvHandleBuffer
;
787 EFI_FV_FILETYPE Type
;
789 EFI_FV_FILE_ATTRIBUTES Attributes
;
790 UINT32 AuthenticationStatus
;
791 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
792 EFI_HANDLE ImageHandle
;
793 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
796 BootOptionNumber
= 0;
799 // If the boot device enumerate happened, just get the boot
800 // device from the boot order variable
802 if (mEnumBootDevice
) {
803 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
807 // Notes: this dirty code is to get the legacy boot option from the
808 // BBS table and create to variable as the EFI boot option, it should
809 // be removed after the CSM can provide legacy boot option directly
811 REFRESH_LEGACY_BOOT_OPTIONS
;
814 // Delete invalid boot option
816 BdsDeleteAllInvalidEfiBootOption ();
818 // Parse removable media
820 gBS
->LocateHandleBuffer (
822 &gEfiSimpleFileSystemProtocolGuid
,
824 &NumberFileSystemHandles
,
827 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
828 Status
= gBS
->HandleProtocol (
829 FileSystemHandles
[Index
],
830 &gEfiBlockIoProtocolGuid
,
833 if (!EFI_ERROR (Status
)) {
834 if (!BlkIo
->Media
->RemovableMedia
) {
836 // If the file system handle supports a BlkIo protocol,
837 // skip the removable media devices
844 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
845 // machinename is ia32, ia64, x64, ...
847 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
849 Status
= gBS
->LoadImage (
857 if (!EFI_ERROR(Status
)) {
859 // Verify the image is a EFI application (and not a driver)
861 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
862 ASSERT (!EFI_ERROR(Status
));
864 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
871 // No such file or the file is not a EFI application, delete this boot option
873 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
875 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
880 if (NumberFileSystemHandles
) {
881 gBS
->FreePool (FileSystemHandles
);
884 // Parse Network Boot Device
886 gBS
->LocateHandleBuffer (
888 &gEfiSimpleNetworkProtocolGuid
,
890 &NumberLoadFileHandles
,
893 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
894 Status
= gBS
->HandleProtocol (
895 LoadFileHandles
[Index
],
896 &gEfiLoadFileProtocolGuid
,
897 (VOID
**) &ProtocolInstance
899 if (EFI_ERROR (Status
)) {
903 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
907 if (NumberLoadFileHandles
) {
908 gBS
->FreePool (LoadFileHandles
);
911 // Check if we have on flash shell
913 gBS
->LocateHandleBuffer (
915 &gEfiFirmwareVolumeProtocolGuid
,
920 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
921 gBS
->HandleProtocol (
922 FvHandleBuffer
[Index
],
923 &gEfiFirmwareVolumeProtocolGuid
,
927 Status
= Fv
->ReadFile (
934 &AuthenticationStatus
936 if (EFI_ERROR (Status
)) {
938 // Skip if no shell file in the FV
943 // Build the shell boot option
945 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
950 gBS
->FreePool (FvHandleBuffer
);
953 // Make sure every boot only have one time
954 // boot device enumerate
956 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
957 mEnumBootDevice
= TRUE
;
963 BdsLibBuildOptionFromHandle (
964 IN EFI_HANDLE Handle
,
965 IN LIST_ENTRY
*BdsBootOptionList
971 Build the boot option with the handle parsed in
975 Handle - The handle which present the device path to create boot option
977 BdsBootOptionList - The header of the link list which indexed all current
986 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
989 DevicePath
= DevicePathFromHandle (Handle
);
990 TempString
= DevicePathToStr (DevicePath
);
993 // Create and register new boot option
995 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
999 BdsLibBuildOptionFromShell (
1000 IN EFI_HANDLE Handle
,
1001 IN OUT LIST_ENTRY
*BdsBootOptionList
1005 Routine Description:
1007 Build the on flash shell boot option with the handle parsed in
1011 Handle - The handle which present the device path to create on flash shell
1014 BdsBootOptionList - The header of the link list which indexed all current
1023 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1024 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1026 DevicePath
= DevicePathFromHandle (Handle
);
1029 // Build the shell device path
1031 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1032 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1035 // Create and register the shell boot option
1037 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1047 Routine Description:
1049 Boot from the EFI1.1 spec defined "BootNext" variable
1064 BDS_COMMON_OPTION
*BootOption
;
1065 LIST_ENTRY TempList
;
1070 // Init the boot option name buffer and temp link list
1072 InitializeListHead (&TempList
);
1073 ZeroMem (Buffer
, sizeof (Buffer
));
1075 BootNext
= BdsLibGetVariableAndSize (
1077 &gEfiGlobalVariableGuid
,
1082 // Clear the boot next variable first
1084 if (BootNext
!= NULL
) {
1087 &gEfiGlobalVariableGuid
,
1088 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1094 // Start to build the boot option and try to boot
1096 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1097 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1098 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1099 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);