boot.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,972 行 · 第 1/5 页
C
1,972 行
*LoadOptionSize = 0;
Print (L"\n New BootOption Data. ASCII/Unicode strings only, with max of %d characters\n", MAX_CHAR);
Ascii = FALSE;
BmntClearLine();
ConOut->SetAttribute (ConOut, BootMenu.ReverseScreenAttribute);
Print (L" Enter BootOption Data Type [A-Ascii U-Unicode N-No BootOption] : ");
WaitForSingleEvent (ConIn->WaitForKey, 0);
ConIn->ReadKeyStroke (ConIn, &Key);
switch (Key.UnicodeChar) {
case 'N':
case 'n':
Print(L" None\n");
ConOut->SetAttribute (ConOut, BootMenu.ScreenAttribute);
return (EFI_SUCCESS);
case 'A':
case 'a':
Ascii = TRUE;
Print(L" Ascii");
Print (L"\n Enter BootOption Data [Data will be stored as Ascii string]:");
break;
case 'U':
case 'u':
default :
Print (L" Unicode");
Print (L"\n Enter BootOption Data [Data will be stored as Unicode string]: ");
break;
}
ConOut->SetAttribute (ConOut, BootMenu.ScreenAttribute);
Print (L"\n");
TempStr = (CHAR16 *) AllocateZeroPool(SizeLoadOptionStr);
ASSERT(TempStr);
Input (L" ", TempStr, SizeLoadOptionStr);
if (Ascii) {
AsciiChar = (CHAR8 *)LoadOptionStr;
TempStr1 = TempStr;
for(;*TempStr1 != CHAR_NULL;TempStr1++) {
// Convert to ASCII
*AsciiChar = (CHAR8)*TempStr1;
*LoadOptionSize += 1;
AsciiChar++;
}
// Check to see if any boot options were added
// LoadOptionSize would be non-zero if something was entered at input
// if something was added then increment LoadOptionSize by 1 so that
// we can capture the Null string terminator character as well
if (*LoadOptionSize) {
*LoadOptionSize += 1;
*AsciiChar = '\0';
}
} else {
StrCpy(LoadOptionStr,TempStr);
*LoadOptionSize = StrSize(LoadOptionStr);
}
FreePool(TempStr);
return EFI_SUCCESS;
}
EFI_STATUS
BootTheOption (
IN FILE_MENU_CONTEXT *Context,
IN BOOT_MENU_CONTEXT *BootOption
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH *DevicePath;
EFI_HANDLE ImageHandle;
LEGACY_BOOT_INTERFACE *BootLegacy;
DevicePath = Context->DevicePath;
if (DevicePath->Type == BBS_DEVICE_PATH &&
DevicePath->SubType == BBS_BBS_DP ) {
//
// If the device path starts with a BBS device path entry
// call into platform code to boot the legacy PC AT way
//
LibLocateProtocol (&LegacyBootProtocol, &BootLegacy);
if (BootLegacy) {
Status = BootLegacy->BootIt (DevicePath);
if (EFI_ERROR(Status)) {
Print (L"Start of %s failed: %r\n", BootOption->Description, Status);
BootPause ();
return Status;
}
} else {
//
// Booting from legacy devices not support on this platform
//
ASSERT(FALSE);
return EFI_UNSUPPORTED;
}
}
if (Context->IsRemovableMedia) {
Status = DefaultBootTheBootOption (Context, BootOption, &ImageHandle);
if (EFI_ERROR(Status)) {
return Status;
}
} else {
Status = BS->LoadImage(TRUE, GlobalImageHandle, DevicePath, NULL, 0, &ImageHandle);
if (EFI_ERROR(Status)) {
return Status;
}
}
//
// Before calling the image, enable the Watchdog Timer for the 5 Minute period
//
Status = BS->StartImage (ImageHandle, 0, NULL);
if (EFI_ERROR(Status)) {
}
return Status;
}
EFI_STATUS
DefaultBootTheBootOption (
IN FILE_MENU_CONTEXT *Context,
IN BOOT_MENU_CONTEXT *BootOption,
OUT EFI_HANDLE *ImageHandle
)
{
UINTN PathSize;
EFI_STATUS Status;
UINTN NoHandles, Index;
EFI_HANDLE *Handles;
EFI_HANDLE Handle;
EFI_FILE_HANDLE EfiBoot, Dir;
UINTN FileInfoSize, BufferSize;
EFI_FILE_INFO *FileInfo;
CHAR16 *FileName;
EFI_DEVICE_PATH *FilePath, *DevicePath;
EFI_LOADED_IMAGE *ImageInfo;
EFI_BLOCK_IO *BlkIo;
VOID *Buffer;
EfiBoot = NULL;
Dir = NULL;
ASSERT (Context->DevicePath);
PathSize = DevicePathSize(Context->DevicePath) - sizeof(EFI_DEVICE_PATH);
FileInfoSize = sizeof(EFI_FILE_HANDLE) + 1024;
FileInfo = AllocatePool (FileInfoSize);
ASSERT (FileInfo);
//
// Read a block just in case we booted without the media in place
// This will allow for the FileSystemProtocol to be found when attempting
// to boot from the device in that case.
//
LibLocateHandle (ByProtocol, &BlockIoProtocol, NULL, &NoHandles, &Handles);
for (Index=0; Index < NoHandles; Index++) {
Handle = Handles[Index];
DevicePath=DevicePathFromHandle (Handle);
if (CompareMem(DevicePath, Context->DevicePath, PathSize) != 0) {
continue;
}
Status = BS->HandleProtocol(Handle, &BlockIoProtocol, (VOID **)&BlkIo);
if (!EFI_ERROR(Status)) {
if (!BlkIo->Media->LogicalPartition) {
Buffer = AllocatePool (BlkIo->Media->BlockSize);
BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer);
FreePool (Buffer);
}
}
}
//
// Find all file system handles
//
LibLocateHandle (ByProtocol, &FileSystemProtocol, NULL, &NoHandles, &Handles);
for (Index=0; Index < NoHandles; Index++) {
Handle = Handles[Index];
//
// See if this is a file system on the same device
//
// BUGBUG: this doesn't handle instance paths
DevicePath = DevicePathFromHandle (Handle);
if (!DevicePath) {
continue;
}
if (CompareMem(DevicePath, Context->DevicePath, PathSize) != 0) {
//
// Match on the first part of the device path
//
continue;
}
//
// We found a file system on the device. Open it.
//
Dir = LibOpenRoot(Handle);
if (!Dir) {
continue;
}
Status = Dir->Open (Dir, &EfiBoot, L"EFI", EFI_FILE_MODE_READ, 0);
Dir->Close (Dir);
if (EFI_ERROR(Status)) {
continue;
}
Status = EfiBoot->Open (EfiBoot, &Dir, L"BOOT", EFI_FILE_MODE_READ, 0);
EfiBoot->Close (EfiBoot);
if (EFI_ERROR(Status)) {
continue;
}
//
// Check the Boot directory for a bootable image
//
Dir->SetPosition (Dir, 0);
for (; ;) {
BufferSize = FileInfoSize;
Status = Dir->Read (Dir, &BufferSize, FileInfo);
//
// If at the end of the search, we're done
//
if (EFI_ERROR(Status) || BufferSize == 0) {
break;
}
//
// If it not an image name, skip it
//
if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) /*||
!IsEfiImageName(FileInfo->FileName)*/) {
continue;
}
//
// Build a path to the image and see if we can load it
//
FileName = PoolPrint(L"\\EFI\\BOOT\\%s", FileInfo->FileName);
ASSERT (FileName);
FilePath = FileDevicePath (Handle, FileName);
Status = BS->LoadImage (
TRUE,
GlobalImageHandle,
FilePath,
NULL,
0,
ImageHandle
);
if (!EFI_ERROR(Status)) {
//
// Verify the image is an application (and not a driver)
//
Status = BS->HandleProtocol (*ImageHandle, &LoadedImageProtocol, &ImageInfo);
ASSERT (!EFI_ERROR(Status));
if (ImageInfo->ImageCodeType != EfiLoaderCode) {
DEBUG ((D_BM | D_INFO, "DefaultBootImage: Image %hs is not an application\n", FileName));
Status = BS->Exit(*ImageHandle, EFI_SUCCESS, 0, NULL);
ASSERT (!EFI_ERROR(Status));
Status = EFI_LOAD_ERROR;
} else {
DEBUG ((D_BM | D_INFO, "BmDefaultBootImage: Loaded %hs\n", FileName));
}
}
FreePool (FileName);
FreePool (FilePath);
if (!EFI_ERROR(Status)) {
Dir->Close (Dir);
FreePool (FileInfo);
return Status;
}
}
Dir->Close (EfiBoot);
}
*ImageHandle = NULL;
if (FileInfo) {
FreePool (FileInfo);
}
return EFI_NOT_FOUND;
}
BOOLEAN
IsEfiImageName (
CHAR16 *FileName
)
{
// Search for ".efi" extension
while (*FileName) {
if (FileName[0] == '.' && StriCmp(FileName, L".EFI") == 0) {
return TRUE;
}
FileName += 1;
}
return FALSE;
}
BOOLEAN
PrintBootHelp(
IN CHAR16 *Description
)
{
SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
EFI_STATUS Status;
UINTN MaxColumn, ScreenSize;
UINTN Row,Col;
UINTN Size,PrintSize;
BOOLEAN Done;
CHAR16 *TempStr;
ConOut = ST->ConOut;
InitializeListHead (&BootOrderHelpMenu.Head);
Status = ConOut->SetAttribute (ConOut, BootOrderHelpMenu.ScreenAttribute);
ASSERT (!EFI_ERROR (Status));
ConOut->EnableCursor(ConOut, FALSE);
if (BootOrderHelpMenu.ClearScreen) {
Status = ConOut->ClearScreen (ConOut);
ASSERT (!EFI_ERROR (Status));
}
ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &MaxColumn, &ScreenSize);
Print (BootOrderHelpMenu.Header);
Size = StrSize(Description)/sizeof(CHAR16);
TempStr = Description;
Col = MaxColumn - BootOrderHelpMenu.Col*2;
Done = FALSE;
for (Row = 2;!Done; ) {
if( Size > Col) {
PrintSize = Col;
} else {
PrintSize = Size;
Done = TRUE;
}
PrintAt(BootOrderHelpMenu.Col, Row, L"%-.*s", PrintSize, TempStr);
Size -= PrintSize;
TempStr = TempStr + PrintSize;
Row++;
}
return TRUE;
}
EFI_STATUS
Bmnt_DisplayDeleteBootMenu (
VOID
)
{
BOOT_MENU_CONTEXT *ResultContext;
BOOT_MENU_CONTEXT *PreviousResultContext;
BOOT_MENU_CONTEXT *SaveNvramContext;
BOOT_MENU_CONTEXT *DeleteAllContext;
BOOT_MENU_CONTEXT *DeleteHelpContext;
BOOT_MENU_CONTEXT *DeleteExitContext;
BOOLEAN NVRAMNeedsUpdating;
UINTN MenuOption;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
BOOLEAN Done;
UINTN EndRow;
UINTN MaxColumn, ScreenSize;
BOOLEAN Exit;
CHAR16 *Header = L"%EDelete Boot Option(s). Select an Option\n\n";
//
// initialize header text
//
FreeBootOrderMenuOfVariables();
InitializeBootOrderMenuFromVariable();
BootMenu.Header = Header;
DeleteAllContext =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?