bbssupport.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,604 行 · 第 1/3 页
C
1,604 行
Ptr += sizeof (BBS_TYPE);
NewPtr += sizeof (BBS_TYPE);
Length = *((UINT16 *) Ptr);
*((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
Ptr += sizeof (UINT16);
for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY
) {
Ptr += sizeof (UINT16);
continue;
}
NewFDPtr[FDIndex] = *(UINT16 *) Ptr;
FDIndex++;
Ptr += sizeof (UINT16);
}
//
// copy HD
//
NewPtr = (UINT8 *) NewHDPtr - HeaderSize;
*((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
Ptr += sizeof (BBS_TYPE);
NewPtr += sizeof (BBS_TYPE);
Length = *((UINT16 *) Ptr);
*((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
Ptr += sizeof (UINT16);
for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK
) {
Ptr += sizeof (UINT16);
continue;
}
NewHDPtr[HDIndex] = *(UINT16 *) Ptr;
HDIndex++;
Ptr += sizeof (UINT16);
}
//
// copy CD
//
NewPtr = (UINT8 *) NewCDPtr - HeaderSize;
*((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
Ptr += sizeof (BBS_TYPE);
NewPtr += sizeof (BBS_TYPE);
Length = *((UINT16 *) Ptr);
*((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
Ptr += sizeof (UINT16);
for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
LocalBbsTable[*Ptr].DeviceType != BBS_CDROM
) {
Ptr += sizeof (UINT16);
continue;
}
NewCDPtr[CDIndex] = *(UINT16 *) Ptr;
CDIndex++;
Ptr += sizeof (UINT16);
}
//
// copy NET
//
NewPtr = (UINT8 *) NewNETPtr - HeaderSize;
*((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
Ptr += sizeof (BBS_TYPE);
NewPtr += sizeof (BBS_TYPE);
Length = *((UINT16 *) Ptr);
*((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
Ptr += sizeof (UINT16);
for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK
) {
Ptr += sizeof (UINT16);
continue;
}
NewNETPtr[NETIndex] = *(UINT16 *) Ptr;
NETIndex++;
Ptr += sizeof (UINT16);
}
//
// copy BEV
//
NewPtr = (UINT8 *) NewBEVPtr - HeaderSize;
*((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
Ptr += sizeof (BBS_TYPE);
NewPtr += sizeof (BBS_TYPE);
Length = *((UINT16 *) Ptr);
*((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
Ptr += sizeof (UINT16);
for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE
) {
Ptr += sizeof (UINT16);
continue;
}
NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;
BEVIndex++;
Ptr += sizeof (UINT16);
}
for (Index = 0; Index < BbsCount; Index++) {
if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
(LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
(LocalBbsTable[Index].BootPriority == BBS_LOWEST_PRIORITY)
) {
continue;
}
switch (LocalBbsTable[Index].DeviceType) {
case BBS_FLOPPY:
Idx = &FDIndex;
NewDevPtr = NewFDPtr;
break;
case BBS_HARDDISK:
Idx = &HDIndex;
NewDevPtr = NewHDPtr;
break;
case BBS_CDROM:
Idx = &CDIndex;
NewDevPtr = NewCDPtr;
break;
case BBS_EMBED_NETWORK:
Idx = &NETIndex;
NewDevPtr = NewNETPtr;
break;
case BBS_BEV_DEVICE:
Idx = &BEVIndex;
NewDevPtr = NewBEVPtr;
break;
default:
Idx = NULL;
break;
}
//
// at this point we have copied those valid indexes to new buffer
// and we should check if there is any new appeared boot device
//
if (Idx) {
for (Index2 = 0; Index2 < *Idx; Index2++) {
if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
break;
}
}
if (Index2 == *Idx) {
//
// Index2 == *Idx means we didn't find Index
// so Index is a new appeared device's index in BBS table
// save it.
//
NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);
(*Idx)++;
}
}
}
if (FDCount) {
//
// Just to make sure that disabled indexes are all at the end of the array
//
for (Index = 0; Index < FDIndex - 1; Index++) {
if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {
continue;
}
for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {
if (0 == (NewFDPtr[Index2] & 0xFF00)) {
tmp = NewFDPtr[Index];
NewFDPtr[Index] = NewFDPtr[Index2];
NewFDPtr[Index2] = tmp;
break;
}
}
}
}
if (HDCount) {
//
// Just to make sure that disabled indexes are all at the end of the array
//
for (Index = 0; Index < HDIndex - 1; Index++) {
if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {
continue;
}
for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {
if (0 == (NewHDPtr[Index2] & 0xFF00)) {
tmp = NewHDPtr[Index];
NewHDPtr[Index] = NewHDPtr[Index2];
NewHDPtr[Index2] = tmp;
break;
}
}
}
}
if (CDCount) {
//
// Just to make sure that disabled indexes are all at the end of the array
//
for (Index = 0; Index < CDIndex - 1; Index++) {
if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {
continue;
}
for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {
if (0 == (NewCDPtr[Index2] & 0xFF00)) {
tmp = NewCDPtr[Index];
NewCDPtr[Index] = NewCDPtr[Index2];
NewCDPtr[Index2] = tmp;
break;
}
}
}
}
if (NETCount) {
//
// Just to make sure that disabled indexes are all at the end of the array
//
for (Index = 0; Index < NETIndex - 1; Index++) {
if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {
continue;
}
for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {
if (0 == (NewNETPtr[Index2] & 0xFF00)) {
tmp = NewNETPtr[Index];
NewNETPtr[Index] = NewNETPtr[Index2];
NewNETPtr[Index2] = tmp;
break;
}
}
}
}
if (BEVCount) {
//
// Just to make sure that disabled indexes are all at the end of the array
//
for (Index = 0; Index < BEVIndex - 1; Index++) {
if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {
continue;
}
for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {
if (0 == (NewBEVPtr[Index2] & 0xFF00)) {
tmp = NewBEVPtr[Index];
NewBEVPtr[Index] = NewBEVPtr[Index2];
NewBEVPtr[Index2] = tmp;
break;
}
}
}
}
SafeFreePool (DevOrder);
Status = gRT->SetVariable (
VarLegacyDevOrder,
&EfiLegacyDevOrderGuid,
VAR_FLAG,
TotalSize,
NewDevOrder
);
SafeFreePool (NewDevOrder);
return Status;
}
EFI_STATUS
BdsSetBootPriority4SameTypeDev (
IN UINT16 DeviceType,
IN OUT BBS_TABLE *LocalBbsTable,
IN OUT UINT16 *Priority
)
/*++
DeviceType - BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM and so on
LocalBbsTable - BBS table instance
Priority - As input arg, it is the start point of boot priority, as output arg, it is the start point of boot
priority can be used next time.
--*/
{
UINT8 *DevOrder;
UINT8 *OrigBuffer;
UINT16 *DevIndex;
UINTN DevOrderSize;
UINTN DevCount;
UINTN Index;
DevOrder = BdsLibGetVariableAndSize (
VarLegacyDevOrder,
&EfiLegacyDevOrderGuid,
&DevOrderSize
);
if (NULL == DevOrder) {
return EFI_OUT_OF_RESOURCES;
}
OrigBuffer = DevOrder;
while (DevOrder < OrigBuffer + DevOrderSize) {
if (DeviceType == * (BBS_TYPE *) DevOrder) {
break;
}
DevOrder += sizeof (BBS_TYPE);
DevOrder += *(UINT16 *) DevOrder;
}
if (DevOrder >= OrigBuffer + DevOrderSize) {
SafeFreePool (OrigBuffer);
return EFI_NOT_FOUND;
}
DevOrder += sizeof (BBS_TYPE);
DevCount = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);
DevIndex = (UINT16 *) (DevOrder + sizeof (UINT16));
//
// If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
//
for (Index = 0; Index < DevCount; Index++) {
if ((DevIndex[Index] & 0xFF00) == 0xFF00) {
//
// LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
//
} else {
LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;
(*Priority)++;
}
}
SafeFreePool (OrigBuffer);
return EFI_SUCCESS;
}
VOID
PrintBbsTable (
IN BBS_TABLE *LocalBbsTable
)
{
UINT16 Idx;
DEBUG ((EFI_D_ERROR, "\n"));
DEBUG ((EFI_D_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
DEBUG ((EFI_D_ERROR, "=============================================\n"));
for (Idx = 0; Idx < MAX_BBS_ENTRIES; Idx++) {
if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
(LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
(LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
) {
continue;
}
DEBUG (
(EFI_D_ERROR,
" %02x: %04x %02x/%02x/%02x %02x/02%x %04x %04x %04x:%04x\n",
(UINTN) Idx,
(UINTN) LocalBbsTable[Idx].BootPriority,
(UINTN) LocalBbsTable[Idx].Bus,
(UINTN) LocalBbsTable[Idx].Device,
(UINTN) LocalBbsTable[Idx].Function,
(UINTN) LocalBbsTable[Idx].Class,
(UINTN) LocalBbsTable[Idx].SubClass,
(UINTN) LocalBbsTable[Idx].DeviceType,
(UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
(UINTN) LocalBbsTable[Idx].BootHandlerSegment,
(UINTN) LocalBbsTable[Idx].BootHandlerOffset,
(UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
(UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))
);
}
DEBUG ((EFI_D_ERROR, "\n"));
}
EFI_STATUS
BdsRefreshBbsTableForBoot (
IN BDS_COMMON_OPTION *Entry
)
{
EFI_STATUS Status;
UINT16 HddCount;
UINT16 BbsCount;
HDD_INFO *LocalHddInfo;
BBS_TABLE *LocalBbsTable;
UINT16 DevType;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
UINTN Index;
UINT16 Priority;
UINT16 *BootOrder;
UINTN BootOrderSize;
UINT8 *BootOptionVar;
UINTN BootOptionSize;
UINT16 BootOption[100];
UINT8 *Ptr;
UINT16 DevPathLen;
EFI_DEVICE_PATH_PROTOCOL *DevPath;
HddCount = 0;
BbsCount = 0;
LocalHddInfo = NULL;
LocalBbsTable = NULL;
DevType = BBS_UNKNOWN;
Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);
if (EFI_ERROR (Status)) {
return Status;
}
LegacyBios->GetBbsInfo (
LegacyBios,
&HddCount,
&LocalHddInfo,
&BbsCount,
&LocalBbsTable
);
//
// First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
// We will set them according to the settings setup by user
//
for (Index = 0; Index < BbsCount; Index++) {
if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
(BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
(BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
}
}
//
// boot priority always starts at 0
//
Priority = 0;
if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
//
// If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
//
DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
Status = BdsSetBootPriority4SameTypeDev (
DevType,
LocalBbsTable,
&Priority
);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// we have to set the boot priority for other BBS entries with different device types
//
BootOrder = (UINT16 *) BdsLibGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
for (Index = 0; BootOrder && Index < BootOrderSize / sizeof (UINT16); Index++) {
SPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
BootOptionVar = BdsLibGetVariableAndSize (
BootOption,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (NULL == BootOptionVar) {
continue;
}
Ptr = BootOptionVar;
Ptr += sizeof (UINT32);
DevPathLen = *(UINT16 *) Ptr;
Ptr += sizeof (UINT16);
Ptr += EfiStrSize ((UINT16 *) Ptr);
DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {
SafeFreePool (BootOptionVar);
continue;
}
Ptr += DevPathLen;
if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {
//
// We don't want to process twice for a device type
//
SafeFreePool (BootOptionVar);
continue;
}
Status = BdsSetBootPriority4SameTypeDev (
((BBS_TABLE *) Ptr)->DeviceType,
LocalBbsTable,
&Priority
);
SafeFreePool (BootOptionVar);
if (EFI_ERROR (Status)) {
break;
}
}
if (BootOrder) {
SafeFreePool (BootOrder);
}
//
// For debug
//
PrintBbsTable (LocalBbsTable);
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?