boot.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,972 行 · 第 1/5 页
C
1,972 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
boot.c
Abstract:
Boot Manger type menus
Revision History
--*/
#include "efi.h"
#include "efilib.h"
#include "menu.h"
#include "legacyboot.h"
#define DIRECTION_UP 1
#define DIRECTION_DOWN 2
UINT16
AllocateBootOrder (
IN UINT16 *BootOrderList,
IN UINTN BootOrderSize
);
BOOLEAN
IsInVarBootOrder (
IN UINT16 BootOption,
IN UINT16 *BootOrderList,
IN UINTN BootOrderSize
);
EFI_STATUS
SetNvramForBootMenu (
IN EFI_MENU *Menu
);
VOID
BootContextPrint (
IN struct _MENU_OPTION *MenuOption,
IN VOID *Context,
IN UINTN *Row,
IN UINTN Column
);
BOOT_MENU_CONTEXT *
AllocateSpecialBootOption (
IN EFI_MENU *Menu,
IN CHAR16 *String,
IN UINTN Attribute,
IN UINTN Option
);
VOID
FreeBootMenu (
IN EFI_MENU *Menu
);
VOID
FreeAllOfBootMenu (
IN EFI_MENU *Menu
);
VOID
FreeSpecificBootMenuOption (
IN EFI_MENU *Menu,
IN BOOT_MENU_CONTEXT *Context
);
BOOLEAN
PrintBootHelp(
IN CHAR16 *Description
);
EFI_STATUS
DeleteAllBootOptions (
OUT BOOLEAN *NVRAMNeedsUpdating
);
EFI_STATUS
ResetBootNextOption (
OUT BOOLEAN *NVRAMNeedsUpdating,
IN BOOLEAN Prompt
);
EFI_STATUS
OrderOption(
IN BOOT_MENU_CONTEXT *Context,
IN UINTN Direction,
OUT BOOLEAN *UpdateNvram
);
EFI_STATUS
UpdateLoadOption(
IN CHAR16 *LoadOptionStr,
IN UINTN SizeLoadOptionStr,
OUT UINTN *LoadOptionSize,
IN BOOLEAN EditMode);
EFI_MENU BootMenu = {
MENU_SIGNATURE, NULL,
4, CON_UNSELECTED, CON_ACTIVE_SELECTION,
TRUE, 10,
NULL,
NULL, 7,
NULL, NULL, NULL, NULL, NULL, FALSE, 0, MENU_ENTRY_FORMAT
};
EFI_MENU BootOrderHelpMenu = {
MENU_SIGNATURE, NULL,
4, CON_UNSELECTED, CON_ACTIVE_SELECTION,
TRUE, 10,
L"Boot Order Menu Help Screen\n\n",
NULL, 7,
NULL, NULL, NULL, NULL, NULL, FALSE, 0, MENU_ENTRY_FORMAT
};
EFI_MENU DeleteHelpMenu = {
MENU_SIGNATURE, NULL,
4, CON_UNSELECTED, CON_ACTIVE_SELECTION,
TRUE, 10,
L"Delete Menu Help Screen\n\n",
NULL, 7,
NULL, NULL, NULL, NULL, NULL, FALSE, 0, MENU_ENTRY_FORMAT
};
EFI_MENU BootNextHelpMenu = {
MENU_SIGNATURE, NULL,
4, CON_UNSELECTED, CON_ACTIVE_SELECTION,
TRUE, 10,
L"BootNext Menu Help Screen\n\n",
NULL, 7,
NULL, NULL, NULL, NULL, NULL, FALSE, 0, MENU_ENTRY_FORMAT
};
UINTN
InitializeBootOrderMenuFromVariable (
VOID
)
{
BOOT_MENU_CONTEXT *Context;
UINTN Index;
UINT16 BootString[10];
UINT8 *LoadOptionFromVar, *LoadOption;
UINTN BootOptionSize;
BOOLEAN BootNextFlag;
UINT16 *BootOrderList;
UINTN BootOrderListSize;
UINT16 *BootNext;
UINTN BootNextSize;
BootOrderList = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &BootOrderListSize);
BootNext = LibGetVariableAndSize (VarBootNext, &EfiGlobalVariable, &BootNextSize);
if (BootNext) {
if (BootNextSize != sizeof(UINT16)) {
FreePool (BootNext);
BootNext = NULL;
}
}
BootMenu.BottomOfPage = NULL;
InitializeListHead (&BootMenu.Head);
for (Index = 0; Index < BootOrderListSize/sizeof(UINT16); Index++) {
SPrint (BootString, sizeof(BootString), VarBootOption, BootOrderList[Index]);
LoadOptionFromVar = LibGetVariableAndSize (BootString, &EfiGlobalVariable, &BootOptionSize);
if (!LoadOptionFromVar) {
continue;
}
LoadOption = AllocateZeroPool(BootOptionSize);
if (!LoadOption) {
continue;
}
CopyMem(LoadOption,LoadOptionFromVar,BootOptionSize);
FreePool(LoadOptionFromVar);
if (BootNext) {
BootNextFlag = *BootNext == BootOrderList[Index];
} else {
BootNextFlag = FALSE;
}
Context = BuildBootMenuContext (
LoadOption,
BootOptionSize,
BootOrderList[Index],
BootString,
BootNextFlag,
FALSE
);
}
if(BootNext) {
FreePool (BootNext);
}
if(BootOrderList) {
FreePool (BootOrderList);
}
return Index;
}
VOID
FreeBootOrderMenuOfVariables (
VOID
)
{
FreeAllOfBootMenu(&BootMenu);
}
BOOT_MENU_CONTEXT *
BuildBootMenuContext (
IN CHAR8 *BootOption,
IN UINTN BootOptionSize,
IN UINT16 BootOptionNumber,
IN CHAR16 *BootString,
IN BOOLEAN BootNext,
IN BOOLEAN Modified
)
{
BOOT_MENU_CONTEXT *Context;
UINTN SizeDevicePath;
UINT8 *LoadOption;
UINT8 *End;
UINT32 FilePathListLength;
UINTN StringSize;
LoadOption = BootOption;
Context = AllocateZeroPool (sizeof(BOOT_MENU_CONTEXT));
if (!Context) {
return NULL;
}
Context->OptionNumber = BootOptionNumber;
Context->IsBootNext = BootNext;
Context->LoadOptionModified = Modified;
End = LoadOption + BootOptionSize;
Context->RawOption = BootOption;
Context->RawOptionSize = BootOptionSize;
Context->Attributes = *(UINT32 *) LoadOption;
Context->IsActive = (BOOLEAN)(Context->Attributes & LOAD_OPTION_ACTIVE);
LoadOption += sizeof(UINT32);
FilePathListLength = *(UINT16 *) LoadOption;
LoadOption += sizeof(UINT16);
StringSize = StrSize((CHAR16 *)LoadOption);
Context->Description = AllocateZeroPool (StringSize);
CopyMem (Context->Description, (CHAR16 *)LoadOption, StringSize);
LoadOption += StringSize;
SizeDevicePath = DevicePathSize ((EFI_DEVICE_PATH *)LoadOption);
if (SizeDevicePath > FilePathListLength) {
SizeDevicePath = FilePathListLength;
}
if ((LoadOption + SizeDevicePath) > End) {
Context->IsActive = FALSE;
SizeDevicePath = End - LoadOption;
}
//
// To avoid alignment problems copy to an aligned buffer
//
Context->FilePath = AllocatePool (SizeDevicePath);
CopyMem (Context->FilePath, (EFI_DEVICE_PATH *)LoadOption, SizeDevicePath);
Context->FilePathString = DevicePathToStr (Context->FilePath);
LoadOption += SizeDevicePath;
Context->LoadOptionsSize = BootOptionSize - sizeof(UINT32) - sizeof(UINT16) - StringSize - SizeDevicePath;
Context->LoadOptions = AllocatePool(Context->LoadOptionsSize);
CopyMem (Context->LoadOptions, LoadOption, Context->LoadOptionsSize);
StrCpy (Context->BootString, BootString);
Context->MenuOption = BOOT_MENU_SELECTION;
Context->Menu = AllocateMenuOption (&BootMenu, Context->Description, CON_UNSELECTED, Context);
Context->Menu->ContextPrint = BootContextPrint;
return Context;
}
EFI_STATUS
Bmnt_DisplayBootOrderMenu (
VOID
)
{
BOOT_MENU_CONTEXT *ResultContext;
BOOT_MENU_CONTEXT *PreviousResultContext;
BOOT_MENU_CONTEXT *SaveNvramContext;
BOOT_MENU_CONTEXT *BootHelpContext;
BOOT_MENU_CONTEXT *BootExitContext;
BOOLEAN NVRAMNeedsUpdating;
UINTN MenuOption;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
BOOLEAN Done;
UINTN Direction;
CHAR16 *Header = L"%EChange boot order. Select an Operation\n\n";
//
// initialize header text
//
FreeBootOrderMenuOfVariables();
InitializeBootOrderMenuFromVariable();
BootMenu.Header = Header;
SaveNvramContext =
AllocateSpecialBootOption (&BootMenu, L"Save Settings to NVRAM", CON_UNSELECTED, BOOT_MENU_SAVE_NVRAM);
BootHelpContext =
AllocateSpecialBootOption (&BootMenu, L"Help", CON_UNSELECTED, BOOT_MENU_HELP);
BootExitContext =
AllocateSpecialBootOption (&BootMenu, L"Exit", CON_UNSELECTED, BOOT_MENU_EXIT);
BootMenu.Selection = NULL;
NVRAMNeedsUpdating = FALSE;
for (Done = FALSE, ResultContext = NULL; !Done;) {
PreviousResultContext = ResultContext;
ResultContext = MenuDisplay (&BootMenu, &Key);
if (!ResultContext) {
Done = TRUE;
break;
}
//
// default move option down
//
Direction = DIRECTION_DOWN;
switch (Key.UnicodeChar){
case CHAR_CARRIAGE_RETURN:
if (ResultContext->MenuOption != BOOT_MENU_SELECTION) {
MenuOption = ResultContext->MenuOption;
} else {
MenuOption = -1;
}
break;
case 'U':
case 'u':
Direction = DIRECTION_UP;
case 'D':
case 'd':
if (ResultContext->MenuOption == BOOT_MENU_SELECTION) {
MenuOption = BOOT_MENU_SELECTION;
} else {
MenuOption = -1;
}
break;
default:
MenuOption = -1;
} // end switch
if (MenuOption == BOOT_MENU_EXIT) {
if (NVRAMNeedsUpdating) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 2, L"NVRAM Not updated. Save NVRAM? [Y to save, N to ignore]");
WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
MenuOption = BOOT_MENU_SAVE_NVRAM;
}
}
Done = TRUE;
}
switch (MenuOption) {
case BOOT_MENU_EXIT:
break;
case BOOT_MENU_HELP:
PrintMenuHelp(&BootOrderHelpMenu,BootOrderMenuHelpStr);
break;
case BOOT_MENU_SAVE_NVRAM:
Status = SetNvramForBootMenu (&BootMenu);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?