bdsboot.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,112 行 · 第 1/3 页
C
1,112 行
Index2 = 0;
for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
if (BootOrder[Index] != 0xffff) {
BootOrder[Index2] = BootOrder[Index];
Index2 ++;
}
}
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
Index2 * sizeof (UINT16),
BootOrder
);
gBS->FreePool (BootOrder);
return Status;
}
EFI_STATUS
BdsLibEnumerateAllBootOption (
IN OUT EFI_LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
This function will enumerate all possible boot device in the system,
it will only excute once of every boot.
Arguments:
BdsBootOptionList - The header of the link list which indexed all
current boot options
Returns:
EFI_SUCCESS - Finished all the boot device enumerate and create
the boot option base on that boot device
--*/
{
EFI_STATUS Status;
UINT16 BootOptionNumber;
UINTN NumberFileSystemHandles;
EFI_HANDLE *FileSystemHandles;
EFI_BLOCK_IO_PROTOCOL *BlkIo;
UINTN Index;
UINTN NumberLoadFileHandles;
EFI_HANDLE *LoadFileHandles;
VOID *ProtocolInstance;
EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
UINTN FvHandleCount;
EFI_HANDLE *FvHandleBuffer;
EFI_FV_FILETYPE Type;
UINTN Size;
EFI_FV_FILE_ATTRIBUTES Attributes;
UINT32 AuthenticationStatus;
BOOLEAN NeedDelete;
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_FILE_HEADER ImageHeader;
EFI_IMAGE_OPTIONAL_HEADER OptionalHeader;
BootOptionNumber = 0;
//
// If the boot device enumerate happened, just get the boot
// device from the boot order variable
//
if (mEnumBootDevice) {
BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
return EFI_SUCCESS;
}
//
// Notes: this dirty code is to get the legacy boot option from the
// BBS table and create to variable as the EFI boot option, it should
// be removed after the CSM can provide legacy boot option directly
//
REFRESH_LEGACY_BOOT_OPTIONS;
//
// Delete invalid boot option
//
BdsDeleteAllInvalidEfiBootOption ();
//
// Parse removable media
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberFileSystemHandles,
&FileSystemHandles
);
for (Index = 0; Index < NumberFileSystemHandles; Index++) {
Status = gBS->HandleProtocol (
FileSystemHandles[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
if (!EFI_ERROR (Status)) {
if (!BlkIo->Media->RemovableMedia) {
//
// If the file system handle supports a BlkIo protocol,
// skip the non-removable media devices
//
continue;
}
}
//
// Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
// machinename is ia32, ia64, x64, ...
//
NeedDelete = TRUE;
Status = BdsLibGetImageHeader (
FileSystemHandles[Index],
DEFAULT_REMOVABLE_FILE_NAME,
&DosHeader,
&ImageHeader,
&OptionalHeader
);
if (!EFI_ERROR (Status) &&
EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageHeader.Machine) &&
OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
NeedDelete = FALSE;
}
if (NeedDelete) {
//
// No such file or the file is not a EFI application, delete this boot option
//
BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
} else {
BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList);
BootOptionNumber++;
}
}
if (NumberFileSystemHandles) {
gBS->FreePool (FileSystemHandles);
}
//
// Parse Network Boot Device
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleNetworkProtocolGuid,
NULL,
&NumberLoadFileHandles,
&LoadFileHandles
);
for (Index = 0; Index < NumberLoadFileHandles; Index++) {
Status = gBS->HandleProtocol (
LoadFileHandles[Index],
&gEfiLoadFileProtocolGuid,
(VOID **) &ProtocolInstance
);
if (EFI_ERROR (Status)) {
continue;
}
BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList);
BootOptionNumber++;
}
if (NumberLoadFileHandles) {
gBS->FreePool (LoadFileHandles);
}
//
// Check if we have on flash shell
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolumeProtocolGuid,
NULL,
&FvHandleCount,
&FvHandleBuffer
);
for (Index = 0; Index < FvHandleCount; Index++) {
gBS->HandleProtocol (
FvHandleBuffer[Index],
&gEfiFirmwareVolumeProtocolGuid,
(VOID **) &Fv
);
Status = Fv->ReadFile (
Fv,
&gEfiShellFileGuid,
NULL,
&Size,
&Type,
&Attributes,
&AuthenticationStatus
);
if (EFI_ERROR (Status)) {
//
// Skip if no shell file in the FV
//
continue;
}
//
// Build the shell boot option
//
BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
BootOptionNumber++;
}
if (FvHandleCount) {
gBS->FreePool (FvHandleBuffer);
}
//
// Make sure every boot only have one time
// boot device enumerate
//
BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
mEnumBootDevice = TRUE;
return EFI_SUCCESS;
}
VOID
BdsLibBuildOptionFromHandle (
IN EFI_HANDLE Handle,
IN EFI_LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
Build the boot option with the handle parsed in
Arguments:
Handle - The handle which present the device path to create boot option
BdsBootOptionList - The header of the link list which indexed all current
boot options
Returns:
VOID
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
CHAR16 *TempString;
DevicePath = EfiDevicePathFromHandle (Handle);
TempString = DevicePathToStr (DevicePath);
//
// Create and register new boot option
//
BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, TempString, L"BootOrder");
}
VOID
BdsLibBuildOptionFromShell (
IN EFI_HANDLE Handle,
IN OUT EFI_LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
Build the on flash shell boot option with the handle parsed in
Arguments:
Handle - The handle which present the device path to create on flash shell
boot option
BdsBootOptionList - The header of the link list which indexed all current
boot options
Returns:
None
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;
DevicePath = EfiDevicePathFromHandle (Handle);
//
// Build the shell device path
//
EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);
//
//ShellNode.Header.Type = MEDIA_DEVICE_PATH;
//ShellNode.Header.SubType = MEDIA_FV_FILEPATH_DP;
//SetDevicePathNodeLength (&ShellNode.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
//EfiCopyMem (&ShellNode.NameGuid, &gEfiShellFileGuid, sizeof (EFI_GUID));
//
DevicePath = EfiAppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);
//
// Create and register the shell boot option
//
BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"Internal EFI Shell", L"BootOrder");
}
VOID
BdsLibBootNext (
VOID
)
/*++
Routine Description:
Boot from the EFI1.1 spec defined "BootNext" variable
Arguments:
None
Returns:
None
--*/
{
UINT16 *BootNext;
UINTN BootNextSize;
CHAR16 Buffer[20];
BDS_COMMON_OPTION *BootOption;
EFI_LIST_ENTRY TempList;
UINTN ExitDataSize;
CHAR16 *ExitData;
//
// Init the boot option name buffer and temp link list
//
InitializeListHead (&TempList);
EfiZeroMem (Buffer, sizeof (Buffer));
BootNext = BdsLibGetVariableAndSize (
L"BootNext",
&gEfiGlobalVariableGuid,
&BootNextSize
);
//
// Clear the boot next variable first
//
if (BootNext != NULL) {
gRT->SetVariable (
L"BootNext",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
BootNext
);
//
// Start to build the boot option and try to boot
//
SPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);
BootOption = BdsLibVariableToOption (&TempList, Buffer);
BdsLibConnectDevicePath (BootOption->DevicePath);
BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?