From d6882a1cf9f487600ccb2b57ba880b5f91ff0c10 Mon Sep 17 00:00:00 2001 From: srs5694 Date: Wed, 2 Oct 2013 21:23:58 -0400 Subject: [PATCH] Graphics-mode launches now clear to rEFInd's menu background color rather than to gray. --- EfiLib/BdsHelper.c | 34 +- EfiLib/legacy.c | 815 +++++++++++++++++++++++++---------------- EfiLib/legacy.h | 23 +- NEWS.txt | 10 + docs/refind/linux.html | 4 +- refind/main.c | 28 +- refind/screen.c | 4 +- 7 files changed, 575 insertions(+), 343 deletions(-) diff --git a/EfiLib/BdsHelper.c b/EfiLib/BdsHelper.c index af17d4f..12a54a4 100644 --- a/EfiLib/BdsHelper.c +++ b/EfiLib/BdsHelper.c @@ -121,23 +121,23 @@ BdsLibDoLegacyBoot ( } OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath; -// Print(L"\n\n"); -// Print(L"Option->Name='%s'\n", Option->OptionName); -// Print(L"Option->Number='%d'\n", Option->OptionNumber); -// Print(L"Option->Description='%s'\n", Option->Description); -// Print(L"Option->LoadOptionsSize='%d'\n",Option->LoadOptionsSize); -// Print(L"Option->BootCurrent='%d'\n",Option->BootCurrent); -// Print(L"Option->DevicePath->Type= '%d'\n", Option->DevicePath->Type); -// Print(L"Option->DevicePath->SubType= '%d'\n", Option->DevicePath->SubType); -// Print(L"Option->DevicePath->Length[0]= '%d'\n", Option->DevicePath->Length[0]); -// Print(L"Option->DevicePath->Length[1]= '%d'\n", Option->DevicePath->Length[1]); -// Print(L"OptionBBS->DeviceType='%d'\n",OptionBBS->DeviceType); -// Print(L"OptionBBS->StatusFlag='%d'\n",OptionBBS->StatusFlag); -// Print(L"OptionBBS->String[0]='%c'\n",OptionBBS->String[0]); -// Print(L"About to legacy boot!\n"); -// PauseForKey(); - - UpdateBbsTable(OptionBBS->DeviceType); + Print(L"\n\n"); + Print(L"Option->Name='%s'\n", Option->OptionName); + Print(L"Option->Number='%d'\n", Option->OptionNumber); + Print(L"Option->Description='%s'\n", Option->Description); + Print(L"Option->LoadOptionsSize='%d'\n",Option->LoadOptionsSize); + Print(L"Option->BootCurrent='%d'\n",Option->BootCurrent); + Print(L"Option->DevicePath->Type= '%d'\n", Option->DevicePath->Type); + Print(L"Option->DevicePath->SubType= '%d'\n", Option->DevicePath->SubType); + Print(L"Option->DevicePath->Length[0]= '%d'\n", Option->DevicePath->Length[0]); + Print(L"Option->DevicePath->Length[1]= '%d'\n", Option->DevicePath->Length[1]); + Print(L"OptionBBS->DeviceType='%d'\n",OptionBBS->DeviceType); + Print(L"OptionBBS->StatusFlag='%d'\n",OptionBBS->StatusFlag); + Print(L"OptionBBS->String[0]='%s'\n",OptionBBS->String); + Print(L"About to legacy boot!\n"); + PauseForKey(); + + UpdateBbsTable(OptionBBS->DeviceType); return LegacyBios->LegacyBoot (LegacyBios, (BBS_BBS_DEVICE_PATH *) Option->DevicePath, Option->LoadOptionsSize, Option->LoadOptions); } \ No newline at end of file diff --git a/EfiLib/legacy.c b/EfiLib/legacy.c index 3aae71d..7728f97 100644 --- a/EfiLib/legacy.c +++ b/EfiLib/legacy.c @@ -22,6 +22,8 @@ BOOT_OPTION_BBS_MAPPING *mBootOptionBbsMapping = NULL; UINTN mBootOptionBbsMappingCount = 0; extern EFI_DEVICE_PATH EndDevicePath[]; +extern EFI_GUID gEfiLegacyBiosProtocolGuid; +EFI_GUID gEfiLegacyDevOrderVariableGuid = { 0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 }}; /** @@ -707,6 +709,7 @@ BdsAddNonExistingLegacyBootOptions ( UINT16 OptionNumber; BOOLEAN Exist; + Print(L"Entering BdsAddNonExistingLegacyBootOptions()\n"); HddCount = 0; BbsCount = 0; LocalHddInfo = NULL; @@ -759,6 +762,7 @@ BdsAddNonExistingLegacyBootOptions ( &BbsIndex, &OptionNumber ); + Print(L"Boot entry #%d %s exist.\n", Index, Exist ? L"does" : L"does not"); if (!Exist) { // // Not found such type of legacy device in boot options or we found but it's disabled @@ -817,6 +821,8 @@ BdsAddNonExistingLegacyBootOptions ( FreePool (BootOrder); } + Print(L"Exiting BdsAddNonExistingLegacyBootOptions()\n"); + return Status; } @@ -957,6 +963,7 @@ BdsDeleteAllInvalidLegacyBootOptions ( // // Update BootOrder // + Print(L"About to call BdsDeleteBootOption() on Index == %d\n", Index); BdsDeleteBootOption ( BootOrder[Index], BootOrder, @@ -968,7 +975,7 @@ BdsDeleteAllInvalidLegacyBootOptions ( return EFI_OUT_OF_RESOURCES; } } - + // // Skip Non-Legacy boot option // @@ -1011,6 +1018,7 @@ BdsDeleteAllInvalidLegacyBootOptions ( // // should delete // + Print(L"Second About to call BdsDeleteBootOption(), Index = %d\n", Index); BdsDeleteBootOption ( BootOrder[Index], BootOrder, @@ -1040,6 +1048,170 @@ BdsDeleteAllInvalidLegacyBootOptions ( return Status; } +/** + Fill the device order buffer. + + @param BbsTable The BBS table. + @param BbsType The BBS Type. + @param BbsCount The BBS Count. + @param Buf device order buffer. + + @return The device order buffer. + +**/ +UINT16 * +BdsFillDevOrderBuf ( + IN BBS_TABLE *BbsTable, + IN BBS_TYPE BbsType, + IN UINTN BbsCount, + OUT UINT16 *Buf + ) +{ + UINTN Index; + + for (Index = 0; Index < BbsCount; Index++) { + if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { + continue; + } + + if (BbsTable[Index].DeviceType != BbsType) { + continue; + } + + *Buf = (UINT16) (Index & 0xFF); + Buf++; + } + + return Buf; +} + +/** + Create the device order buffer. + + @param BbsTable The BBS table. + @param BbsCount The BBS Count. + + @retval EFI_SUCCES The buffer is created and the EFI variable named + VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is + set correctly. + @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough. + @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail + because of hardware error. +**/ +EFI_STATUS +BdsCreateDevOrder ( + IN BBS_TABLE *BbsTable, + IN UINT16 BbsCount + ) +{ + UINTN Index; + UINTN FDCount; + UINTN HDCount; + UINTN CDCount; + UINTN NETCount; + UINTN BEVCount; + UINTN TotalSize; + UINTN HeaderSize; + LEGACY_DEV_ORDER_ENTRY *DevOrder; + LEGACY_DEV_ORDER_ENTRY *DevOrderPtr; + EFI_STATUS Status; + + FDCount = 0; + HDCount = 0; + CDCount = 0; + NETCount = 0; + BEVCount = 0; + TotalSize = 0; + HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); + DevOrder = NULL; + Status = EFI_SUCCESS; + + // + // Count all boot devices + // + for (Index = 0; Index < BbsCount; Index++) { + if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { + continue; + } + + switch (BbsTable[Index].DeviceType) { + case BBS_FLOPPY: + FDCount++; + break; + + case BBS_HARDDISK: + HDCount++; + break; + + case BBS_CDROM: + CDCount++; + break; + + case BBS_EMBED_NETWORK: + NETCount++; + break; + + case BBS_BEV_DEVICE: + BEVCount++; + break; + + default: + break; + } + } + + TotalSize += (HeaderSize + sizeof (UINT16) * FDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * HDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * CDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * NETCount); + TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount); + + // + // Create buffer to hold all boot device order + // + DevOrder = AllocateZeroPool (TotalSize); + if (NULL == DevOrder) { + return EFI_OUT_OF_RESOURCES; + } + DevOrderPtr = DevOrder; + + DevOrderPtr->BbsType = BBS_FLOPPY; + DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_HARDDISK; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_CDROM; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_EMBED_NETWORK; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_BEV_DEVICE; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data); + + ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder)); + + // + // Save device order for legacy boot device to variable. + // + Status = gRT->SetVariable ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + VAR_FLAG, + TotalSize, + DevOrder + ); + FreePool (DevOrder); + + return Status; +} + /** Add the legacy boot devices from BBS table into the legacy device boot order. @@ -1050,314 +1222,335 @@ BdsDeleteAllInvalidLegacyBootOptions ( @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable because of hardware error. **/ -// EFI_STATUS -// EFIAPI -// BdsUpdateLegacyDevOrder ( -// VOID -// ) -// { -// LEGACY_DEV_ORDER_ENTRY *DevOrder; -// LEGACY_DEV_ORDER_ENTRY *NewDevOrder; -// LEGACY_DEV_ORDER_ENTRY *Ptr; -// LEGACY_DEV_ORDER_ENTRY *NewPtr; -// UINTN DevOrderSize; -// EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; -// EFI_STATUS Status; -// UINT16 HddCount; -// UINT16 BbsCount; -// HDD_INFO *LocalHddInfo; -// BBS_TABLE *LocalBbsTable; -// UINTN Index; -// UINTN Index2; -// UINTN *Idx; -// UINTN FDCount; -// UINTN HDCount; -// UINTN CDCount; -// UINTN NETCount; -// UINTN BEVCount; -// UINTN TotalSize; -// UINTN HeaderSize; -// UINT16 *NewFDPtr; -// UINT16 *NewHDPtr; -// UINT16 *NewCDPtr; -// UINT16 *NewNETPtr; -// UINT16 *NewBEVPtr; -// UINT16 *NewDevPtr; -// UINTN FDIndex; -// UINTN HDIndex; -// UINTN CDIndex; -// UINTN NETIndex; -// UINTN BEVIndex; -// -// Idx = NULL; -// FDCount = 0; -// HDCount = 0; -// CDCount = 0; -// NETCount = 0; -// BEVCount = 0; -// TotalSize = 0; -// HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); -// FDIndex = 0; -// HDIndex = 0; -// CDIndex = 0; -// NETIndex = 0; -// BEVIndex = 0; -// NewDevPtr = NULL; -// -// Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios); -// if (EFI_ERROR (Status)) { -// return Status; -// } -// -// Status = LegacyBios->GetBbsInfo ( -// LegacyBios, -// &HddCount, -// &LocalHddInfo, -// &BbsCount, -// &LocalBbsTable -// ); -// if (EFI_ERROR (Status)) { -// return Status; -// } -// -// DevOrder = BdsLibGetVariableAndSize ( -// VAR_LEGACY_DEV_ORDER, -// &gEfiLegacyDevOrderVariableGuid, -// &DevOrderSize -// ); -// if (NULL == DevOrder) { -// return BdsCreateDevOrder (LocalBbsTable, BbsCount); -// } -// // -// // First we figure out how many boot devices with same device type respectively -// // -// for (Index = 0; Index < BbsCount; Index++) { -// if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || -// (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) -// ) { -// continue; -// } -// -// switch (LocalBbsTable[Index].DeviceType) { -// case BBS_FLOPPY: -// FDCount++; -// break; -// -// case BBS_HARDDISK: -// HDCount++; -// break; -// -// case BBS_CDROM: -// CDCount++; -// break; -// -// case BBS_EMBED_NETWORK: -// NETCount++; -// break; -// -// case BBS_BEV_DEVICE: -// BEVCount++; -// break; -// -// default: -// break; -// } -// } -// -// TotalSize += (HeaderSize + FDCount * sizeof (UINT16)); -// TotalSize += (HeaderSize + HDCount * sizeof (UINT16)); -// TotalSize += (HeaderSize + CDCount * sizeof (UINT16)); -// TotalSize += (HeaderSize + NETCount * sizeof (UINT16)); -// TotalSize += (HeaderSize + BEVCount * sizeof (UINT16)); -// -// NewDevOrder = AllocateZeroPool (TotalSize); -// if (NULL == NewDevOrder) { -// return EFI_OUT_OF_RESOURCES; -// } -// -// -// -// // -// // copy FD -// // -// Ptr = DevOrder; -// NewPtr = NewDevOrder; -// NewPtr->BbsType = Ptr->BbsType; -// NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16)); -// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { -// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY -// ) { -// continue; -// } -// -// NewPtr->Data[FDIndex] = Ptr->Data[Index]; -// FDIndex++; -// } -// NewFDPtr = NewPtr->Data; -// -// // -// // copy HD -// // -// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); -// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); -// NewPtr->BbsType = Ptr->BbsType; -// NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); -// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { -// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK -// ) { -// continue; -// } -// -// NewPtr->Data[HDIndex] = Ptr->Data[Index]; -// HDIndex++; -// } -// NewHDPtr = NewPtr->Data; -// -// // -// // copy CD -// // -// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); -// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); -// NewPtr->BbsType = Ptr->BbsType; -// NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); -// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { -// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM -// ) { -// continue; -// } -// -// NewPtr->Data[CDIndex] = Ptr->Data[Index]; -// CDIndex++; -// } -// NewCDPtr = NewPtr->Data; -// -// // -// // copy NET -// // -// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); -// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); -// NewPtr->BbsType = Ptr->BbsType; -// NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); -// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { -// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK -// ) { -// continue; -// } -// -// NewPtr->Data[NETIndex] = Ptr->Data[Index]; -// NETIndex++; -// } -// NewNETPtr = NewPtr->Data; -// -// // -// // copy BEV -// // -// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); -// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); -// NewPtr->BbsType = Ptr->BbsType; -// NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); -// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { -// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || -// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE -// ) { -// continue; -// } -// -// NewPtr->Data[BEVIndex] = Ptr->Data[Index]; -// BEVIndex++; -// } -// NewBEVPtr = NewPtr->Data; -// -// for (Index = 0; Index < BbsCount; Index++) { -// if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || -// (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) -// ) { -// 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 != NULL) { -// 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 -// // insert it before disabled indexes. -// // -// for (Index2 = 0; Index2 < *Idx; Index2++) { -// if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) { -// break; -// } -// } -// CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16)); -// NewDevPtr[Index2] = (UINT16) (Index & 0xFF); -// (*Idx)++; -// } -// } -// } -// -// FreePool (DevOrder); -// -// Status = gRT->SetVariable ( -// VAR_LEGACY_DEV_ORDER, -// &gEfiLegacyDevOrderVariableGuid, -// VAR_FLAG, -// TotalSize, -// NewDevOrder -// ); -// FreePool (NewDevOrder); -// -// return Status; -// } +EFI_STATUS +EFIAPI +BdsUpdateLegacyDevOrder ( + VOID + ) +{ + LEGACY_DEV_ORDER_ENTRY *DevOrder; + LEGACY_DEV_ORDER_ENTRY *NewDevOrder; + LEGACY_DEV_ORDER_ENTRY *Ptr; + LEGACY_DEV_ORDER_ENTRY *NewPtr; + UINTN DevOrderSize; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + EFI_STATUS Status; + UINT16 HddCount; + UINT16 BbsCount; + HDD_INFO *LocalHddInfo; + BBS_TABLE *LocalBbsTable; + INTN Index; + INTN Index2; + UINTN *Idx; + UINTN FDCount; + UINTN HDCount; + UINTN CDCount; + UINTN NETCount; + UINTN BEVCount; + UINTN TotalSize; + UINTN HeaderSize; + UINT16 *NewFDPtr; + UINT16 *NewHDPtr; + UINT16 *NewCDPtr; + UINT16 *NewNETPtr; + UINT16 *NewBEVPtr; + UINT16 *NewDevPtr; + UINTN FDIndex; + UINTN HDIndex; + UINTN CDIndex; + UINTN NETIndex; + UINTN BEVIndex; + + Print(L"Entering BdsUpdateLegacyDevOrder()\n"); + + Idx = NULL; + FDCount = 0; + HDCount = 0; + CDCount = 0; + NETCount = 0; + BEVCount = 0; + TotalSize = 0; + HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); + FDIndex = 0; + HDIndex = 0; + CDIndex = 0; + NETIndex = 0; + BEVIndex = 0; + NewDevPtr = NULL; + + Print(L"About to call EfiLibLocateProtocol()\n"); + Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + + Print(L"About to call GetBbsInfo()\n"); + Status = LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &LocalBbsTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Print(L"About to call BdsLibGetVariableAndSize()\n"); + DevOrder = BdsLibGetVariableAndSize ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + &DevOrderSize + ); + if (NULL == DevOrder) { + Print(L"DevOrder was NULL\n"); + return BdsCreateDevOrder (LocalBbsTable, BbsCount); + } + // + // First we figure out how many boot devices with same device type respectively + // + Print(L"About to enter for() loop, BbsCount = %d\n", BbsCount); + for (Index = 0; Index < BbsCount; Index++) { +// Print(L" Loop: %d\n", Index); + if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) + ) { + continue; + } + + switch (LocalBbsTable[Index].DeviceType) { + case BBS_FLOPPY: + FDCount++; + break; + + case BBS_HARDDISK: + HDCount++; + break; + + case BBS_CDROM: + CDCount++; + break; + + case BBS_EMBED_NETWORK: + NETCount++; + break; + + case BBS_BEV_DEVICE: + BEVCount++; + break; + + default: + break; + } + } + + Print(L"Done with for() loop; counted:\n Floppies: %d\n Hard disks: %d\n CD-ROMs: %d\n", FDCount, HDCount, CDCount); + TotalSize += (HeaderSize + FDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + HDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + CDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + NETCount * sizeof (UINT16)); + TotalSize += (HeaderSize + BEVCount * sizeof (UINT16)); + + Print(L"About to allocate memory for NewDevOrder\n"); + NewDevOrder = AllocateZeroPool (TotalSize); + if (NULL == NewDevOrder) { + return EFI_OUT_OF_RESOURCES; + } + + + Print(L"About to copy FD entries\n"); + // + // copy FD + // + Ptr = DevOrder; + NewPtr = NewDevOrder; + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16)); + Print(L" Copying FD entries; about to loop from 0 to %d\n", Ptr->Length / sizeof (UINT16) - 1); + for (Index = 0; Index < (INTN) (Ptr->Length / sizeof (UINT16) - 1); Index++) { +// Print(L" Looping: Index = %d\n", Index); + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY + ) { + continue; + } + +// Print(L" About to set data\n"); + NewPtr->Data[FDIndex] = Ptr->Data[Index]; + FDIndex++; + } + Print(L" Done with for() loop\n"); + NewFDPtr = NewPtr->Data; + + Print(L"About to copy HD entries\n"); + // + // copy HD + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (sizeof (UINT16) + HDCount * sizeof (UINT16)); + for (Index = 0; Index < (INTN) (Ptr->Length / sizeof (UINT16) - 1); Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK + ) { + continue; + } + + NewPtr->Data[HDIndex] = Ptr->Data[Index]; + HDIndex++; + } + NewHDPtr = NewPtr->Data; + + Print(L"About to copy CD entries\n"); + // + // copy CD + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); + for (Index = 0; Index < (INTN) (Ptr->Length / sizeof (UINT16) - 1); Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM + ) { + continue; + } + + NewPtr->Data[CDIndex] = Ptr->Data[Index]; + CDIndex++; + } + NewCDPtr = NewPtr->Data; + + // + // copy NET + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); + for (Index = 0; Index < (INTN) (Ptr->Length / sizeof (UINT16) - 1); Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK + ) { + continue; + } + + NewPtr->Data[NETIndex] = Ptr->Data[Index]; + NETIndex++; + } + NewNETPtr = NewPtr->Data; + + // + // copy BEV + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); + for (Index = 0; Index < (INTN) (Ptr->Length / sizeof (UINT16) - 1); Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE + ) { + continue; + } + + NewPtr->Data[BEVIndex] = Ptr->Data[Index]; + BEVIndex++; + } + NewBEVPtr = NewPtr->Data; + + Print(L"About to enter another loop; BbsCount = %d\n", BbsCount); + for (Index = 0; Index < BbsCount; Index++) { +// Print(L" Looping: Index = %d\n", Index); + if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) + ) { + 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 + // + Print(L" Checking for new devices\n"); + if (Idx != NULL) { + 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 + // insert it before disabled indexes. + // + for (Index2 = 0; Index2 < *Idx; Index2++) { + if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) { + break; + } + } + CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16)); + NewDevPtr[Index2] = (UINT16) (Index & 0xFF); + (*Idx)++; + } + } + } + + FreePool (DevOrder); + + Print(L"About to call SetVariable()\n"); + Status = gRT->SetVariable ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + VAR_FLAG, + TotalSize, + NewDevOrder + ); + FreePool (NewDevOrder); + + Print(L"Returning from BdsUpdateLegacyDevOrder()\n"); + return Status; +} diff --git a/EfiLib/legacy.h b/EfiLib/legacy.h index 61dba38..618c755 100644 --- a/EfiLib/legacy.h +++ b/EfiLib/legacy.h @@ -18,6 +18,8 @@ #ifndef __LEGACY_H_ #define __LEGACY_H_ +typedef UINT8 BBS_TYPE; + #define VAR_FLAG EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE #pragma pack(1) @@ -32,6 +34,17 @@ typedef struct { } BOOT_OPTION_BBS_MAPPING; #pragma pack() +#pragma pack(1) +typedef struct { + BBS_TYPE BbsType; + /// + /// Length = sizeof (UINT16) + sizeof (Data) + /// + UINT16 Length; + UINT16 Data[1]; +} LEGACY_DEV_ORDER_ENTRY; +#pragma pack() + EFI_STATUS EFIAPI BdsAddNonExistingLegacyBootOptions ( @@ -61,10 +74,10 @@ BdsDeleteAllInvalidLegacyBootOptions ( @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable because of hardware error. **/ -// EFI_STATUS -// EFIAPI -// BdsUpdateLegacyDevOrder ( -// VOID -// ); +EFI_STATUS +EFIAPI +BdsUpdateLegacyDevOrder ( + VOID + ); #endif \ No newline at end of file diff --git a/NEWS.txt b/NEWS.txt index 3463d57..cc6651d 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,13 @@ +0.7.5 (10/??/2013): +------------------- + +- Fixed bug that caused clear to default gray screen when launching OSes + with 'use_graphics_for' enabled, even when the rEFInd background is not + gray. Now rEFInd clears to the same background color used in its menu. + When launching OS X, though, the OS X boot loader will itself clear to + gray a second or so later; and when launching Linux, it will clear to + black a second or so later. + 0.7.4.1 (8/25/2013): -------------------- diff --git a/docs/refind/linux.html b/docs/refind/linux.html index 3a1736d..a28b7ed 100644 --- a/docs/refind/linux.html +++ b/docs/refind/linux.html @@ -176,7 +176,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

Using the EFI Stub Loader: Three Configuration Options

-

The EFI stub loader is basic and reliable, but it requires some setup to use it on some computers. It also requires that you run a kernel with the same bit width as your EFI. In most cases, this means running a 64-bit kernel, since 32-bit EFI-based computers are so rare. I describe three methods of using the EFI stub loader: an easiest method for those with compatible partition and filesystem layouts, a quick test configuration for those without such a layout, and a long-term setup for those without the ideal setup.

+

The EFI stub loader is basic and reliable, but it requires some setup to use it on some computers. It also requires that you run a kernel with the same bit width as your EFI. In most cases, this means running a 64-bit kernel, since 32-bit EFI-based computers are so rare. I describe three methods of using the EFI stub loader: an easiest method for those with compatible partition and filesystem layouts, a quick test configuration for those without such a layout, and a long-term setup for those without the ideal setup.

For Those With Foresight or Luck: The Easiest Method

@@ -205,7 +205,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

-

When you reboot, you should see rEFInd options for your Linux kernels. If they work, your job is done, although you might want to apply some of the tweaks described in the maintenance-free setup section. If you have problems, you may need to adjust the refind_linux.conf file, as described in the detailed configuration section.

+

When you reboot, you should see rEFInd options for your Linux kernels. If they work, your job is done, although you might want to apply some of the tweaks described in the maintenance-free setup section. If you have problems, you may need to adjust the refind_linux.conf file, as described in the detailed configuration section.

Preparing a Test Configuration

diff --git a/refind/main.c b/refind/main.c index 699cb68..7bb69ff 100644 --- a/refind/main.c +++ b/refind/main.c @@ -153,7 +153,7 @@ static VOID AboutrEFInd(VOID) { if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.4.2"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.4.3"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -1625,14 +1625,18 @@ static VOID StartLegacy(IN LEGACY_ENTRY *Entry) // Start a device on a non-Mac using the EFI_LEGACY_BIOS_PROTOCOL #ifdef __MAKEWITH_TIANO -static VOID StartLegacyUEFI(IN LEGACY_ENTRY *Entry) +static VOID StartLegacyUEFI(LEGACY_ENTRY *Entry) { - BeginExternalScreen(TRUE, L"Booting Legacy OS (UEFI mode)"); + UINTN ExitDataSize = 0; + CHAR16 *ExitData = NULL; + EFI_STATUS Status; - BdsDeleteAllInvalidLegacyBootOptions(); - BdsAddNonExistingLegacyBootOptions(); -// BdsUpdateLegacyDevOrder(); + BeginExternalScreen(TRUE, L"Booting Legacy OS (UEFI mode)"); + Print(L"Launching from '%s'\n", DevicePathToStr(Entry->BdsOption->DevicePath)); + PauseForKey(); +// Status = BdsLibBootViaBootOption(Entry->BdsOption, Entry->BdsOption->DevicePath, &ExitDataSize, &ExitData); +// Print(L"BdsLibBootViaBootOption() returned %d\n", Status); BdsLibConnectDevicePath (Entry->BdsOption->DevicePath); BdsLibDoLegacyBoot(Entry->BdsOption); @@ -2154,6 +2158,17 @@ static VOID WarnIfLegacyProblems() { static VOID ScanForBootloaders(VOID) { UINTN i; + if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) { + Print(L"About to call BdsDeleteAllInvalidLegacyBootOptions()\n"); + BdsDeleteAllInvalidLegacyBootOptions(); + Print(L"About to call BdsAddNonExistingLegacyBootOptions()\n"); + BdsAddNonExistingLegacyBootOptions(); + Print(L"About to call BdsUpdateLegacyDevOrder()\n"); +// BdsUpdateLegacyDevOrder(); // EXTREME CAUTION: HOSED ONE FIRMWARE! + Print(L"Done with legacy boot updates!\n"); + PauseForKey(); + } + ScanVolumes(); // scan for loaders and tools, add them to the menu @@ -2415,6 +2430,7 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) ReadConfig(CONFIG_FILE_NAME); ScanVolumes(); + PauseForKey(); InitScreen(); WarnIfLegacyProblems(); MainMenu.TimeoutSeconds = GlobalConfig.Timeout; diff --git a/refind/screen.c b/refind/screen.c index 335dc93..7907d36 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -467,8 +467,8 @@ VOID BltClearScreen(IN BOOLEAN ShowBanner) } } else { - // clear to standard background color - egClearScreen(&StdBackgroundPixel); + // clear to menu background color + egClearScreen(&MenuBackgroundPixel); } GraphicsScreenDirty = FALSE; -- 2.39.2