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 <EdkGenericBdsLibInternal.h>
25 BOOLEAN mEnumBootDevice
= FALSE
;
29 IN BDS_COMMON_OPTION
*Option
35 Boot the legacy system with the boot option
39 Option - The legacy boot option which have BBS device path
43 EFI_UNSUPPORTED - There is no legacybios protocol, do not support
46 EFI_STATUS - Return the status of LegacyBios->LegacyBoot ().
51 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
53 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, &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_BLOCK_IO_PROTOCOL
*BlkIo
;
127 // Record the performance data for End of BDS
129 PERF_END (0, BDS_TOK
, NULL
, 0);
135 // Notes: put EFI64 ROM Shadow Solution
137 EFI64_SHADOW_ALL_LEGACY_ROM ();
140 // If it's Device Path that starts with a hard drive path,
141 // this routine will do the booting.
143 Status
= BdsBootByDiskSignatureAndPartition (
145 (HARDDRIVE_DEVICE_PATH
*) DevicePath
,
146 Option
->LoadOptionsSize
,
151 if (!EFI_ERROR (Status
)) {
153 // If we found a disk signature and partition device path return success
158 // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event
160 EfiSignalEventReadyToBoot ();
167 &gEfiGlobalVariableGuid
,
168 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
173 if ((DevicePathType (Option
->DevicePath
) == BBS_DEVICE_PATH
) &&
174 (DevicePathSubType (Option
->DevicePath
) == BBS_BBS_DP
)
177 // Check to see if we should legacy BOOT. If yes then do the legacy boot
179 return BdsLibDoLegacyBoot (Option
);
182 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Booting EFI 1.1 way %S\n", Option
->Description
));
184 Status
= gBS
->LoadImage (
194 // If we didn't find an image, we may need to load the default
195 // boot behavior for the device.
197 if (EFI_ERROR (Status
)) {
199 // Find a Simple File System protocol on the device path. If the remaining
200 // device path is set to end then no Files are being specified, so try
201 // the removable media file name.
203 TempDevicePath
= DevicePath
;
204 Status
= gBS
->LocateDevicePath (
205 &gEfiSimpleFileSystemProtocolGuid
,
209 if (!EFI_ERROR (Status
) && IsDevicePathEnd (TempDevicePath
)) {
210 FilePath
= FileDevicePath (Handle
, EFI_REMOVABLE_MEDIA_FILE_NAME
);
213 // Issue a dummy read to the device to check for media change.
214 // When the removable media is changed, any Block IO read/write will
215 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
216 // returned. After the Block IO protocol is reinstalled, subsequent
217 // Block IO read/write will success.
219 Status
= gBS
->HandleProtocol (
221 &gEfiBlockIoProtocolGuid
,
224 if (!EFI_ERROR (Status
)) {
225 Buffer
= AllocatePool (BlkIo
->Media
->BlockSize
);
226 if (Buffer
!= NULL
) {
229 BlkIo
->Media
->MediaId
,
231 BlkIo
->Media
->BlockSize
,
238 Status
= gBS
->LoadImage (
246 if (EFI_ERROR (Status
)) {
248 // The DevicePath failed, and it's not a valid
249 // removable media device.
255 Status
= EFI_NOT_FOUND
;
259 if (EFI_ERROR (Status
)) {
261 // It there is any error from the Boot attempt exit now.
266 // Provide the image with it's load options
268 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
269 ASSERT_EFI_ERROR (Status
);
271 if (Option
->LoadOptionsSize
!= 0) {
272 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
273 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
276 // Before calling the image, enable the Watchdog Timer for
277 // the 5 Minute period
279 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
281 Status
= gBS
->StartImage (ImageHandle
, ExitDataSize
, ExitData
);
282 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Image Return Status = %r\n", Status
));
285 // Clear the Watchdog Timer after the image returns
287 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
291 // Clear Boot Current
295 &gEfiGlobalVariableGuid
,
296 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
305 BdsBootByDiskSignatureAndPartition (
306 IN BDS_COMMON_OPTION
* Option
,
307 IN HARDDRIVE_DEVICE_PATH
* HardDriveDevicePath
,
308 IN UINT32 LoadOptionsSize
,
309 IN VOID
*LoadOptions
,
310 OUT UINTN
*ExitDataSize
,
311 OUT CHAR16
**ExitData OPTIONAL
317 Check to see if a hard ware device path was passed in. If it was then search
318 all the block IO devices for the passed in hard drive device path.
322 Option - The current processing boot option.
324 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
327 LoadOptionsSize - Passed into gBS->StartImage ()
328 via the loaded image protocol.
330 LoadOptions - Passed into gBS->StartImage ()
331 via the loaded image protocol.
333 ExitDataSize - returned directly from gBS->StartImage ()
335 ExitData - returned directly from gBS->StartImage ()
339 EFI_SUCCESS - Status from gBS->StartImage (),
340 or BootByDiskSignatureAndPartition ()
342 EFI_NOT_FOUND - If the Device Path is not found in the system
347 UINTN BlockIoHandleCount
;
348 EFI_HANDLE
*BlockIoBuffer
;
349 EFI_DEVICE_PATH_PROTOCOL
*BlockIoDevicePath
;
350 EFI_DEVICE_PATH_PROTOCOL
*BlockIoHdDevicePath
;
351 HARDDRIVE_DEVICE_PATH
*TmpHdPath
;
352 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
353 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
355 BOOLEAN DevicePathMatch
;
356 HARDDRIVE_DEVICE_PATH
*TempPath
;
361 if ( !((DevicePathType (&HardDriveDevicePath
->Header
) == MEDIA_DEVICE_PATH
) &&
362 (DevicePathSubType (&HardDriveDevicePath
->Header
) == MEDIA_HARDDRIVE_DP
))
365 // If the HardDriveDevicePath does not start with a Hard Drive Device Path
368 return EFI_NOT_FOUND
;
371 // The boot device have already been connected
373 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &BlockIoHandleCount
, &BlockIoBuffer
);
374 if (EFI_ERROR (Status
) || BlockIoHandleCount
== 0) {
376 // If there was an error or there are no device handles that support
377 // the BLOCK_IO Protocol, then return.
379 return EFI_NOT_FOUND
;
382 // Loop through all the device handles that support the BLOCK_IO Protocol
384 for (Index
= 0; Index
< BlockIoHandleCount
; Index
++) {
386 Status
= gBS
->HandleProtocol (BlockIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &BlockIoDevicePath
);
387 if (EFI_ERROR (Status
) || BlockIoDevicePath
== NULL
) {
391 // Make PreviousDevicePath == the device path node before the end node
393 DevicePath
= BlockIoDevicePath
;
394 BlockIoHdDevicePath
= NULL
;
397 // find HardDriver device path node
399 while (!IsDevicePathEnd (DevicePath
)) {
400 if ((DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) &&
401 (DevicePathSubType (DevicePath
) == MEDIA_HARDDRIVE_DP
)
403 BlockIoHdDevicePath
= DevicePath
;
407 DevicePath
= NextDevicePathNode (DevicePath
);
410 if (BlockIoHdDevicePath
== NULL
) {
414 // See if the harddrive device path in blockio matches the orig Hard Drive Node
416 DevicePathMatch
= FALSE
;
418 TmpHdPath
= (HARDDRIVE_DEVICE_PATH
*) BlockIoHdDevicePath
;
419 TempPath
= (HARDDRIVE_DEVICE_PATH
*) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
422 // Only several fields will be checked. NOT whole NODE
424 if ( TmpHdPath
->PartitionNumber
== TempPath
->PartitionNumber
&&
425 TmpHdPath
->MBRType
== TempPath
->MBRType
&&
426 TmpHdPath
->SignatureType
== TempPath
->SignatureType
&&
427 CompareGuid ((EFI_GUID
*) TmpHdPath
->Signature
, (EFI_GUID
*) TempPath
->Signature
)) {
429 // Get the matched device path
431 DevicePathMatch
= TRUE
;
434 // Only do the boot, when devicepath match
436 if (DevicePathMatch
) {
438 // Combine the Block IO and Hard Drive Device path together and try
441 DevicePath
= NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*) HardDriveDevicePath
);
442 NewDevicePath
= AppendDevicePath (BlockIoDevicePath
, DevicePath
);
445 // Recursive boot with new device path
447 Status
= BdsLibBootViaBootOption (Option
, NewDevicePath
, ExitDataSize
, ExitData
);
448 if (!EFI_ERROR (Status
)) {
454 FreePool (BlockIoBuffer
);
459 BdsLibDeleteOptionFromHandle (
466 Delete the boot option associated with the handle passed in
470 Handle - The handle which present the device path to create boot option
474 EFI_SUCCESS - Delete the boot option success
476 EFI_NOT_FOUND - If the Device Path is not found in the system
478 EFI_OUT_OF_RESOURCES - Lack of memory resource
480 Other - Error return value from SetVariable()
485 UINT8
*BootOptionVar
;
487 UINTN BootOptionSize
;
490 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
491 UINTN DevicePathSize
;
492 UINTN OptionDevicePathSize
;
493 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
494 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
498 Status
= EFI_SUCCESS
;
502 BootOrder
= BdsLibGetVariableAndSize (
504 &gEfiGlobalVariableGuid
,
507 if (NULL
== BootOrder
) {
508 return EFI_NOT_FOUND
;
511 DevicePath
= DevicePathFromHandle (Handle
);
512 if (DevicePath
== NULL
) {
513 return EFI_NOT_FOUND
;
515 DevicePathSize
= GetDevicePathSize (DevicePath
);
518 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
519 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
520 BootOptionVar
= BdsLibGetVariableAndSize (
522 &gEfiGlobalVariableGuid
,
525 if (NULL
== BootOptionVar
) {
526 FreePool (BootOrder
);
527 return EFI_OUT_OF_RESOURCES
;
530 TempPtr
= BootOptionVar
;
531 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
532 Description
= (CHAR16
*) TempPtr
;
533 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
534 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
535 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
538 // Check whether the device path match
540 if ((OptionDevicePathSize
== DevicePathSize
) &&
541 (CompareMem (DevicePath
, OptionDevicePath
, DevicePathSize
) == 0)) {
542 BdsDeleteBootOption (BootOrder
[Index
], BootOrder
, &BootOrderSize
);
543 FreePool (BootOptionVar
);
547 FreePool (BootOptionVar
);
551 Status
= gRT
->SetVariable (
553 &gEfiGlobalVariableGuid
,
554 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
559 FreePool (BootOrder
);
565 BdsDeleteAllInvalidEfiBootOption (
572 Delete all invalid EFI boot options. The probable invalid boot option could
573 be Removable media or Network boot device.
581 EFI_SUCCESS - Delete all invalid boot option success
583 EFI_NOT_FOUND - Variable "BootOrder" is not found
585 EFI_OUT_OF_RESOURCES - Lack of memory resource
587 Other - Error return value from SetVariable()
592 UINT8
*BootOptionVar
;
594 UINTN BootOptionSize
;
598 UINT16 BootOption
[BOOT_OPTION_MAX_CHAR
];
599 UINTN OptionDevicePathSize
;
600 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
601 EFI_DEVICE_PATH_PROTOCOL
*LastDeviceNode
;
602 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
608 Status
= EFI_SUCCESS
;
612 BootOrder
= BdsLibGetVariableAndSize (
614 &gEfiGlobalVariableGuid
,
617 if (NULL
== BootOrder
) {
618 return EFI_NOT_FOUND
;
622 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
623 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
624 BootOptionVar
= BdsLibGetVariableAndSize (
626 &gEfiGlobalVariableGuid
,
629 if (NULL
== BootOptionVar
) {
630 FreePool (BootOrder
);
631 return EFI_OUT_OF_RESOURCES
;
634 TempPtr
= BootOptionVar
;
635 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
636 Description
= (CHAR16
*) TempPtr
;
637 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
638 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
639 OptionDevicePathSize
= GetDevicePathSize (OptionDevicePath
);
642 // Skip legacy boot option (BBS boot device)
644 if ((DevicePathType (OptionDevicePath
) == BBS_DEVICE_PATH
) &&
645 (DevicePathSubType (OptionDevicePath
) == BBS_BBS_DP
)) {
646 FreePool (BootOptionVar
);
651 TempDevicePath
= OptionDevicePath
;
652 LastDeviceNode
= OptionDevicePath
;
653 while (!EfiIsDevicePathEnd (TempDevicePath
)) {
654 LastDeviceNode
= TempDevicePath
;
655 TempDevicePath
= EfiNextDevicePathNode (TempDevicePath
);
658 // Skip the boot option that point to a file, since the device path in
659 // removable media boot option doesn't contains a file name.
661 if (((DevicePathType (LastDeviceNode
) == MEDIA_DEVICE_PATH
) &&
662 (DevicePathSubType (LastDeviceNode
) == MEDIA_FILEPATH_DP
)) ||
664 // Skip boot option for internal Shell, it's always valid
666 (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LastDeviceNode
) != NULL
)) {
667 FreePool (BootOptionVar
);
674 // Check if it's a valid boot option for removable media
676 TempDevicePath
= OptionDevicePath
;
677 Status
= gBS
->LocateDevicePath (
678 &gEfiSimpleFileSystemProtocolGuid
,
682 if (!EFI_ERROR (Status
)) {
686 // Check if it's a valid boot option for network boot device
688 TempDevicePath
= OptionDevicePath
;
689 Status
= gBS
->LocateDevicePath (
690 &gEfiLoadFileProtocolGuid
,
694 if (!EFI_ERROR (Status
)) {
700 // Delete this invalid boot option "Boot####"
702 Status
= gRT
->SetVariable (
704 &gEfiGlobalVariableGuid
,
705 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
710 // Mark this boot option in boot order as deleted
712 BootOrder
[Index
] = 0xffff;
715 FreePool (BootOptionVar
);
720 // Adjust boot order array
723 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
724 if (BootOrder
[Index
] != 0xffff) {
725 BootOrder
[Index2
] = BootOrder
[Index
];
729 Status
= gRT
->SetVariable (
731 &gEfiGlobalVariableGuid
,
732 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
733 Index2
* sizeof (UINT16
),
737 FreePool (BootOrder
);
743 BdsLibEnumerateAllBootOption (
744 IN OUT LIST_ENTRY
*BdsBootOptionList
750 This function will enumerate all possible boot device in the system,
751 it will only excute once of every boot.
755 BdsBootOptionList - The header of the link list which indexed all
760 EFI_SUCCESS - Finished all the boot device enumerate and create
761 the boot option base on that boot device
766 UINT16 BootOptionNumber
;
767 UINTN NumberFileSystemHandles
;
768 EFI_HANDLE
*FileSystemHandles
;
769 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
771 UINTN NumberLoadFileHandles
;
772 EFI_HANDLE
*LoadFileHandles
;
773 VOID
*ProtocolInstance
;
774 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
776 EFI_HANDLE
*FvHandleBuffer
;
777 EFI_FV_FILETYPE Type
;
779 EFI_FV_FILE_ATTRIBUTES Attributes
;
780 UINT32 AuthenticationStatus
;
781 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
782 EFI_HANDLE ImageHandle
;
783 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
786 BootOptionNumber
= 0;
789 // If the boot device enumerate happened, just get the boot
790 // device from the boot order variable
792 if (mEnumBootDevice
) {
793 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
797 // Notes: this dirty code is to get the legacy boot option from the
798 // BBS table and create to variable as the EFI boot option, it should
799 // be removed after the CSM can provide legacy boot option directly
801 REFRESH_LEGACY_BOOT_OPTIONS
;
804 // Delete invalid boot option
806 BdsDeleteAllInvalidEfiBootOption ();
808 // Parse removable media
810 gBS
->LocateHandleBuffer (
812 &gEfiSimpleFileSystemProtocolGuid
,
814 &NumberFileSystemHandles
,
817 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
818 Status
= gBS
->HandleProtocol (
819 FileSystemHandles
[Index
],
820 &gEfiBlockIoProtocolGuid
,
823 if (!EFI_ERROR (Status
)) {
824 if (!BlkIo
->Media
->RemovableMedia
) {
826 // If the file system handle supports a BlkIo protocol,
827 // skip the removable media devices
834 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
835 // machinename is ia32, ia64, x64, ...
837 FilePath
= FileDevicePath (FileSystemHandles
[Index
], EFI_REMOVABLE_MEDIA_FILE_NAME
);
839 Status
= gBS
->LoadImage (
847 if (!EFI_ERROR(Status
)) {
849 // Verify the image is a EFI application (and not a driver)
851 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**) &ImageInfo
);
852 ASSERT (!EFI_ERROR(Status
));
854 if (ImageInfo
->ImageCodeType
== EfiLoaderCode
) {
861 // No such file or the file is not a EFI application, delete this boot option
863 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
865 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
);
870 if (NumberFileSystemHandles
) {
871 FreePool (FileSystemHandles
);
874 // Parse Network Boot Device
876 gBS
->LocateHandleBuffer (
878 &gEfiSimpleNetworkProtocolGuid
,
880 &NumberLoadFileHandles
,
883 for (Index
= 0; Index
< NumberLoadFileHandles
; Index
++) {
884 Status
= gBS
->HandleProtocol (
885 LoadFileHandles
[Index
],
886 &gEfiLoadFileProtocolGuid
,
887 (VOID
**) &ProtocolInstance
889 if (EFI_ERROR (Status
)) {
893 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
);
897 if (NumberLoadFileHandles
) {
898 FreePool (LoadFileHandles
);
901 // Check if we have on flash shell
903 gBS
->LocateHandleBuffer (
905 &gEfiFirmwareVolumeProtocolGuid
,
910 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
911 gBS
->HandleProtocol (
912 FvHandleBuffer
[Index
],
913 &gEfiFirmwareVolumeProtocolGuid
,
917 Status
= Fv
->ReadFile (
924 &AuthenticationStatus
926 if (EFI_ERROR (Status
)) {
928 // Skip if no shell file in the FV
933 // Build the shell boot option
935 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
940 FreePool (FvHandleBuffer
);
943 // Make sure every boot only have one time
944 // boot device enumerate
946 BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
947 mEnumBootDevice
= TRUE
;
953 BdsLibBuildOptionFromHandle (
954 IN EFI_HANDLE Handle
,
955 IN LIST_ENTRY
*BdsBootOptionList
961 Build the boot option with the handle parsed in
965 Handle - The handle which present the device path to create boot option
967 BdsBootOptionList - The header of the link list which indexed all current
976 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
979 DevicePath
= DevicePathFromHandle (Handle
);
980 TempString
= DevicePathToStr (DevicePath
);
983 // Create and register new boot option
985 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, TempString
, L
"BootOrder");
989 BdsLibBuildOptionFromShell (
990 IN EFI_HANDLE Handle
,
991 IN OUT LIST_ENTRY
*BdsBootOptionList
997 Build the on flash shell boot option with the handle parsed in
1001 Handle - The handle which present the device path to create on flash shell
1004 BdsBootOptionList - The header of the link list which indexed all current
1013 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1014 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode
;
1016 DevicePath
= DevicePathFromHandle (Handle
);
1019 // Build the shell device path
1021 EfiInitializeFwVolDevicepathNode (&ShellNode
, &gEfiShellFileGuid
);
1022 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) &ShellNode
);
1025 // Create and register the shell boot option
1027 BdsLibRegisterNewOption (BdsBootOptionList
, DevicePath
, L
"Internal EFI Shell", L
"BootOrder");
1037 Routine Description:
1039 Boot from the EFI1.1 spec defined "BootNext" variable
1054 BDS_COMMON_OPTION
*BootOption
;
1055 LIST_ENTRY TempList
;
1060 // Init the boot option name buffer and temp link list
1062 InitializeListHead (&TempList
);
1063 ZeroMem (Buffer
, sizeof (Buffer
));
1065 BootNext
= BdsLibGetVariableAndSize (
1067 &gEfiGlobalVariableGuid
,
1072 // Clear the boot next variable first
1074 if (BootNext
!= NULL
) {
1077 &gEfiGlobalVariableGuid
,
1078 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1084 // Start to build the boot option and try to boot
1086 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *BootNext
);
1087 BootOption
= BdsLibVariableToOption (&TempList
, Buffer
);
1088 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1089 BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);