UEFI-based PCs. Version 0.8.0 release.
#include "BdsHelper.h"
+#include "legacy.h"
+#include "../refind/screen.h"
EFI_GUID gEfiLegacyBootProtocolGuid = { 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d }};
@param DeviceType The device type that we wish to enable
**/
-VOID
-UpdateBbsTable (
- IN UINT16 DeviceType
- )
-{
- UINT16 Idx;
- EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
- EFI_STATUS Status;
- UINT16 HddCount = 0;
- HDD_INFO *HddInfo = NULL;
- UINT16 BbsCount = 0;
- BBS_TABLE *LocalBbsTable = NULL;
-
- Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
- if (EFI_ERROR (Status)) {
+VOID UpdateBbsTable (BDS_COMMON_OPTION *Option) {
+ UINT16 Idx;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_STATUS Status;
+ UINT16 HddCount = 0;
+ HDD_INFO *HddInfo = NULL;
+ UINT16 BbsCount = 0;
+ BBS_TABLE *LocalBbsTable = NULL;
+ BBS_BBS_DEVICE_PATH *OptionBBS;
+ CHAR16 Desc[100];
+
+ Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status) || (Option == NULL)) {
return;
- }
-
- Status = LegacyBios->GetBbsInfo (LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable);
-
- //Print (L"\n");
- //Print (L" NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n");
- //Print (L"=============================================\n");
-
- for (Idx = 0; Idx < BbsCount; Idx++)
- {
- if(LocalBbsTable[Idx].DeviceType == 0){
- continue;
- }
-
- // Set devices of a particular type to BootPriority of 0. I believe 0 is the highest priority
- if(LocalBbsTable[Idx].DeviceType == DeviceType){
- LocalBbsTable[Idx].BootPriority = 0;
- }
-
-/*
- Print (
- L" %02x: %04x %02x/%02x/%02x %02x/%02x %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)
- );
-*/
- }
-
- //Print(L"\n");
+ }
+
+ OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath;
+ Status = LegacyBios->GetBbsInfo (LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable);
+
+// Print (L"\n");
+// Print (L" NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n");
+// Print (L"=============================================\n");
+
+ for (Idx = 0; Idx < BbsCount; Idx++) {
+ if(LocalBbsTable[Idx].DeviceType == 0) {
+ continue;
+ }
+
+ BdsBuildLegacyDevNameString (&LocalBbsTable[Idx], Idx, sizeof (Desc), Desc);
+
+ // Set devices of a particular type to BootPriority of 0 or 1. 0 is the highest priority.
+ if (LocalBbsTable[Idx].DeviceType == OptionBBS->DeviceType) {
+ if (StriCmp(Desc, Option->Description) == 0) {
+ // This entry exactly matches what we're looking for; make it highest priority
+ LocalBbsTable[Idx].BootPriority = 0;
+ } else {
+ // This entry doesn't exactly match, but is the right disk type; make it a bit lower
+ // in priority. Done mainly as a fallback in case of string-matching weirdness.
+ LocalBbsTable[Idx].BootPriority = 1;
+ } // if/else
+ } // if
+
+// Print (
+// L" %02x: %04x %02x/%02x/%02x %02x/%02x %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)
+// );
+// Print(L"%s\n", Desc);
+
+ } // for
}
-// Internal helper function
-// BOOLEAN ArrayContains(UINT16* Arr, UINT8 ArrLen, UINT8 Target)
-// {
-// UINT8 i;
-// for(i = 0; i < ArrLen; i++)
-// {
-// if(Arr[i] == Target)
-// return TRUE;
-// }
-//
-// return FALSE;
-// }
-
/**
Boot the legacy system with the boot option
{
EFI_STATUS Status;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
- BBS_BBS_DEVICE_PATH *OptionBBS;
Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
- 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]='%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
+
+ UpdateBbsTable(Option);
+
+ return LegacyBios->LegacyBoot(LegacyBios, (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
+ Option->LoadOptionsSize, Option->LoadOptions);
+}
UINT16 OptionNumber;
BOOLEAN Exist;
- Print(L"Entering BdsAddNonExistingLegacyBootOptions()\n");
HddCount = 0;
BbsCount = 0;
LocalHddInfo = NULL;
&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
FreePool (BootOrder);
}
- Print(L"Exiting BdsAddNonExistingLegacyBootOptions()\n");
-
return Status;
}
//
// Update BootOrder
//
- Print(L"About to call BdsDeleteBootOption() on Index == %d\n", Index);
BdsDeleteBootOption (
BootOrder[Index],
BootOrder,
//
// should delete
//
- Print(L"Second About to call BdsDeleteBootOption(), Index = %d\n", Index);
BdsDeleteBootOption (
BootOrder[Index],
BootOrder,
return Status;
}
-
-/**
- Add the legacy boot devices from BBS table into
- the legacy device boot order.
-
- @retval EFI_SUCCESS The boot devices are added successfully.
- @retval EFI_NOT_FOUND The legacy boot devices are not found.
- @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
- @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;
- 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;
-}
-
#ifndef __LEGACY_H_
#define __LEGACY_H_
+#define BBS_MEDIA_PRESENT 0x0800
+#define BBS_MEDIA_MAYBE_PRESENT 0x0400
+
typedef UINT8 BBS_TYPE;
#define VAR_FLAG EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE
VOID
);
-/**
- Add the legacy boot devices from BBS table into
- the legacy device boot order.
+BOOLEAN
+BdsIsLegacyBootOption (
+ IN UINT8 *BootOptionVar,
+ OUT BBS_TABLE **BbsEntry,
+ OUT UINT16 *BbsIndex
+);
- @retval EFI_SUCCESS The boot devices are added successfully.
- @retval EFI_NOT_FOUND The legacy boot devices are not found.
- @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
- @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
- because of hardware error.
-**/
-EFI_STATUS
-EFIAPI
-BdsUpdateLegacyDevOrder (
- VOID
- );
+VOID
+BdsBuildLegacyDevNameString (
+ IN BBS_TABLE *CurBBSEntry,
+ IN UINTN Index,
+ IN UINTN BufSize,
+ OUT CHAR16 *BootString
+);
#endif
\ No newline at end of file
-0.7.10 (?/??/2014):
--------------------
+0.8.0 (5/4/2014):
+-----------------
+
+- The "dont_scan_volumes" parameter now also works with legacy-boot
+ volumes. Unlike with EFI volumes, where the option you pass must exactly
+ match an entire volume name, when applied to legacy-boot volumes, it
+ matches any part of the description that appears beneath the item when
+ you select it in the rEFInd main menu.
+
+- Can now boot in legacy mode from second (and probably later) hard disks!
- rEFInd now limits the length of the firmware name string shown in the
system information screen to 65 characters. This is done because at least
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>\r
\r
<p>Originally written: 3/14/2012; last Web page update:\r
-4/20/2014, referencing rEFInd 0.7.9</p>\r
+5/4/2014, referencing rEFInd 0.8.0</p>\r
\r
\r
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>\r
<h2>Identifying Your Hardware's Capabilities</h2>\r
</a>\r
\r
-<p>Let's get the easy case out of the way: If you have a Macintosh with an Intel CPU, it's got EFI capabilities, and you'll be able to use rEFInd. Earlier Macs with PowerPC CPUs use OpenFirmware, and rEFInd can't be used with them.</p>\r
+<p>Let's get the easy case out of the way: If you have a Macintosh with an Intel CPU, it's got EFI capabilities, and you'll be able to use rEFInd. Earlier Macs with PowerPC CPUs use OpenFirmware, and rEFInd can't be used with them. If your computer shipped new with Windows 8 or later, it almost certainly supports EFI; Microsoft requires that computers that bear a Windows 8 logo support EFI, and boot in EFI mode.</p>\r
\r
<p>For everything else, it can be harder to tell. Your best bet is to locate a PDF version of your computer's or motherboard's manual and search it for the string <i>EFI</i>. Checking your firmware's options via the firmware setup utility (typically access by pressing Del, F2, F10, or F12 at boot time) is also worth doing, but you'll need to check every option yourself. Most EFI-enabled PCs include at least one reference to an option you can set; however, manuals and firmware setup tools often don't make a big deal of this feature, particularly on boards with relatively primitive EFI support. For instance, the manual for a Gigabyte GA-78LMT-S2P motherboard includes the following paragraph, on p. 28:</p>\r
\r
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p>Another way to hide a boot loader is to move it into rEFInd's own directory. In order to keep rEFInd from showing up in its own menu, it ignores boot loaders in its own directory. This obviously includes the rEFInd binary file itself, but also anything else you might store there.</p>
+<p>You can also use the <tt>dont_scan_volumes</tt>, <tt>dont_scan_dirs</tt>, and <tt>dont_scan_files</tt> tokens in <tt>refind.conf</tt> to hide entire volumes, directories, and individual files, respectively. Note that <tt>dont_scan_volumes</tt> works with both EFI and legacy scans, whereas the other two options make sense for hiding only EFI-mode boot loaders.</p>
+
<a name="icons">
<h2>Setting OS Icons</h2>
</a>
-<p>In addition to hiding boot loaders, you can adjust their icons. You can do this in any of six ways for auto-detected boot loaders:</p>
+<p>In addition to hiding boot loaders, you can adjust their icons. You can do this in any of seven ways for auto-detected boot loaders:</p>
<ul>
<li>You can give the filesystem from which the boot loader is loaded a name that matches the OS name component of the icon filename. For instance, if you call your boot filesystem <tt>CentOS</tt>, it matches the <tt>os_centos.icns</tt> icon. This match is performed on a word-by-word basis within the name, with "words" being delimited by spaces, dashes (<tt>-</tt>), and underscores (<tt>_</tt>). Thus, a volume called <tt>Debian-boot</tt> will match <tt>os_debian.icns</tt> or <tt>os_boot.icns</tt>.</li>
+<li>You can give the GPT partition from which the boot loader is loaded a name that matches the OS name component of the icon filename. This works much like the previous method, except that you'd use a tool like <tt>gdisk</tt> or <tt>parted</tt> to set the partition's name, rather than <tt>tune2fs</tt> or GParted to set the filesystem's name.</li>
+
<li>rEFInd attempts to guess the Linux distribution based on data in the <tt>/etc/os-release</tt> file. This file will only be accessible if a separate <tt>/boot</tt> partition is <i>not</i> used, though. Manually adjusting the <tt>os-release</tt> file to change an OS icon in rEFInd is <i>not</i> recommended.</li>
<li>Certain boot loaders have hard-coded icons associated with them. For instance, filenames beginning with <tt>vmlinuz</tt> or <tt>bzImage</tt> acquire Linux "Tux" icon and the <tt>bootmgfw.efi</tt> loader acquires a Windows icon. Fedora and Red Hat kernels can be identified by the presence of <tt>.fc</tt> or <tt>.el</tt> strings in their filenames, and so acquire suitable icons automatically. For the most part, these are the associations you want to overcome with the preceding rules, but sometimes renaming a boot loader to a more conventional name is the better approach. Renaming a locally-compiled kernel so that it acquires a Fedora or Red Hat icon is reasonable, but I don't recommend renaming precompiled kernels unless you also manually copy them to the ESP.</li>
<tr>
<td><tt>dont_scan_volumes</tt> or <tt>don't_scan_volumes</tt></td>
<td>filesystem or partition label(s)</td>
- <td>Adds the specified volume or volumes to a volume "blacklist"—these filesystems are <i>not</i> scanned for EFI boot loaders. This may be useful to keep unwanted EFI boot entries, such as for a Macintosh recovery partition, from appearing on the main list of boot loaders. The default value is <tt>"Recovery HD", LRS_ESP</tt>, to keep the Mac OS X and Lenovo Windows recovery volumes from appearing. (These should get their own tools icon instead—see the <tt>showtools</tt> token.) Note that on a Macintosh with whole-disk encryption, you may need to uncomment this token and leave <tt>"Recovery HD"</tt> <i>off</i> the list to boot the system.</td>
+ <td>Adds the specified volume or volumes to a volume "blacklist"—these filesystems are <i>not</i> scanned for EFI boot loaders. This may be useful to keep unwanted EFI boot entries, such as for a Macintosh recovery partition, from appearing on the main list of boot loaders. The default value is <tt>"Recovery HD", LRS_ESP</tt>, to keep the Mac OS X and Lenovo Windows recovery volumes from appearing. (These should get their own tools icon instead—see the <tt>showtools</tt> token.) Note that on a Macintosh with whole-disk encryption, you may need to uncomment this token and leave <tt>"Recovery HD"</tt> <i>off</i> the list to boot the system. You can use <tt>dont_scan_volumes</tt> to hide disks or partitions from legacy-mode scans, too. In this case, you can enter any part of the description that appears beneath the icons to hide entries that include the string you specify.</td>
</tr>
<tr>
<td><tt>dont_scan_dirs</tt> or <tt>don't_scan_dirs</tt></td>
<h2>Creating OS Stanzas</h2>
</a>
-<p>OS stanzas in rEFInd are similar to those in GRUB Legacy, GRUB 2, or ELILO. You can use them to add configuration options to those that are auto-detected. You cannot modify the auto-detected options, though; if you just want to tweak one OS's configuration, you have several options, none of which is ideal:</p>
+<p>OS stanzas in rEFInd are similar to those in GRUB Legacy, GRUB 2, or ELILO. You can use them to add EFI boot loaders to those that are auto-detected. rEFInd does not yet support manual boot stanzas for BIOS-mode boot loaders. You also cannot modify the auto-detected options; if you just want to tweak one OS's configuration, you have several options, none of which is ideal:</p>
<ul>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 4/19/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.10</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
You can select which of these methods to use to construct the rEFInd main boot menu. Although rEFIt supports auto-detection, it does not support manual configuration; and rEFIt's options to enable, disable, and prioritize individual boot loader detection methods are primitive compared to those in rEFInd.</li>
<li>Support for launching legacy BIOS boot loaders on UEFI PCs with
-suitable CSM support (as of version 0.4.6). This feature requires building
-rEFInd with the TianoCore EDK2 toolkit, which I do for my main binary
-build. Note that some UEFI PCs, such as those with Gigabyte's Hybrid EFI,
-lack a usable CSM.</li>
+suitable CSM support (as of version 0.4.6, with significant improvements in
+version 0.8.0). This feature requires building rEFInd with the TianoCore
+EDK2 toolkit, which I do for my main binary build. Note that some UEFI PCs,
+such as those with Gigabyte's Hybrid EFI, lack a usable CSM.</li>
<li>Improved flexibility in setting the default OS to boot. rEFInd enables specifying the default by any substring in the description. You can also specify multiple defaults, so that if the first isn't available, another will take its place (which is useful when using removable disks). You can also add time specifications to set a default to be used only during certain hours of the day.</li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-bin-0.7.9.zip/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-bin-0.8.0.zip/download">A
binary zip file</a></b>—Download this if you want to install
rEFInd and/or its filesystem drivers on an <i>x</i>86 or <i>x</i>86-64
computer and have no need to test rEFInd first by booting it on an
href="installing.html">Installing rEFInd</a> page. Some users of Arch
Linux have reported problems booting some specific Arch Linux kernels
with rEFInd and some other tools. For them, a <a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-bin-gnuefi-0.7.9.zip/download">variant
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-bin-gnuefi-0.8.0.zip/download">variant
package</a> exists in which the <i>x</i>86-64 binary was compiled with
GNU-EFI rather than the usual TianoCore EDK2. This change helps some
users with this problem; but using GNU-EFI also means that this version
can't launch BIOS-mode OSes.</li>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-0.7.9-1.x86_64.rpm/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-0.8.0-1.x86_64.rpm/download">A
binary RPM file</a></b>—If you use an RPM-based <i>x</i>86-64
Linux system such as Fedora or openSUSE, you can install the binary RPM
package rather than use the binary zip file. (I don't provide an
rEFInd</a> page) as part of the installation process. Distribution
maintainers can examine the <tt>refind.spec</tt> file in the source
package and tweak it to their needs. The <a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-0.7.9-1.src.rpm/download">source
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-0.8.0-1.src.rpm/download">source
RPM file</a> might or might not build on your system as-is; it relies
on assumptions about the locations of the GNU-EFI development
files.</li>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind_0.7.9-1_amd64.deb/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind_0.8.0-1_amd64.deb/download">A
binary Debian package</a></b>—If you use an <i>x</i>86-64 version
of Debian, Ubuntu, Mint, or another Debian-based distribution, you can
install from this package, which was converted from the binary RPM
<p class="sidebar"><b>Note:</b> At the moment, neither the bootable CD-R image file nor the bootable USB flash drive image file supports booting with Secure Boot active. The x86-64 version of the <a href="http://en.altlinux.org/Rescue">ALT Linux Rescue disc</a> uses a Secure Boot-enabled rEFInd, though, so you may find that useful in some situations.</p>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-cd-0.7.9.zip/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-cd-0.8.0.zip/download">A
CD-R image file</a></b>—This download contains the same files as
the binary zip file, but you can burn it to a CD-R to test rEFInd
(and its filesystem drivers) without installing it first. (It boots on
computer.</p>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-flashdrive-0.7.9.zip/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-flashdrive-0.8.0.zip/download">A
USB flash drive image file</a></b>—Although you can create
your own rEFInd USB flash drive, you may find it easier to download
this version and copy it to your USB drive with <tt>dd</tt> or some
other low-level disk copying utility.</li>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.7.9/refind-src-0.7.9.zip/download">A
+ href="http://sourceforge.net/projects/refind/files/0.8.0/refind-src-0.8.0.zip/download">A
source code zip file</a></b>—This is useful if you want to compile
the software locally. Note that I use Linux with the <a
href="https://sourceforge.net/projects/tianocore/">TianoCore EFI
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/19/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
-<p>Last Web page update: 4/20/2014</p>
+<p>Last Web page update: 5/4/2014</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
+<li><b>0.8.0 (5/4/2014)</b>—The biggest changes with this version relate to BIOS/CSM/legacy support, particularly on UEFI-based PCs. This version can now boot from the second (or later) hard disk on such computers, and is more likely to be able to cope with removable disks. On both Macs and PCs, you can also now use <tt>dont_scan_volumes</tt> to remove a legacy-boot option from the boot list, so long as it has a unique name (as shown in rEFInd's main menu when you highlight the option). This version also introduces the ability to use partition names and partition GUIDs to refer to devices (in <tt>dont_scan_volumes</tt>, displayed in the rEFInd menu, and so on). Note that partition names are stored in GPT data structures. These are different from filesystem names, which are stored in filesystem data structures. rEFInd now limits the length of the firmware identity string shown in the "About" screen, to prevent problems with the string overrunning the space available on an 800x600 display. Finally, I've fixed a memory-allocation bug that caused error message displays on some systems when re-scanning boot loaders. This bug might conceivably have caused some systems to hang when re-scanning, too.</li>
+
<li><b>0.7.9 (4/20/2014)</b>—This version includes a number of bug fixes: <tt>install.sh</tt> no longer displays error messages if the <tt>dmraid</tt> utility isn't available; the HFS+ driver now reports a correct volume name; filesystem driver bugs that could cause lockups have been fixed; a redundant "utility" in the MOK utility's description has been removed; and an (as-yet untested) attempt to fix a continuous-rescanning problem after ejecting a disc on some computers has been implemented. In addition, rEFInd now removes redundant kernel entries on Ubuntu systems to keep the menu uncluttered and a new <tt>gdisk</tt> option has been added to the <tt>showtools</tt> item. (An EFI version of my <a href="http://www.rodsbooks.com/gdisk/"><tt>gdisk</tt></a> utility can be built with the help of the <a href="https://sourceforge.net/projects/uefigptfdisk/?source=directory">UEFI GPT fdisk</a> library.)</li>
<li><b>0.7.8 (3/9/2014</b>—This version emphasizes changes to icon and banner graphics handling. Internally, rEFInd can now scale graphics, which previous versions could not do. To make use of this feature, three new <tt>refind.conf</tt> tokens now exist: <tt>big_icon_size</tt> and <tt>small_icon_size</tt> set the sizes of big (first-row OS) and small (second-row tool) icons; and <tt>banner_scale</tt> tells rEFInd to draw banners to a 1:1 scale (<tt>noscale</tt>, the default) or to scale the banner to fill the screen (<tt>fillscreen</tt>). See <a href="configfile.html#table1">Table 1 on the configuration page of this document</a> for more on these new options. I've also adjusted the post-installation script used by the RPM and Debian packages to search for existing Shim programs called <tt>shimx64.efi</tt>, not just <tt>shim.efi</tt> (as had been done before). This should help when installing a package on distributions that use the <tt>shimx64.efi</tt> filename, such as Ubuntu. Finally, I'm providing a preliminary set of Debian packaging files, which may help distribution maintainers to adopt rEFInd.</li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 11/13/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 4/19/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
like to add detection for Itanium and ARM systems, but I have no
way to test such changes.</li>
+ <li>Further to the preceding, rEFInd's GPT-scanning code (used to
+ extract partition names) includes assumptions about byte order, and
+ so will work only on little-endian CPUs such as the x86 and
+ x86-64.</li>
+
<li>A way to set the color of the font would be useful for theming
purposes.</li>
characters, and by enabling use of variable-width as well as
monospace fonts.</li>
- <li>I would like to be able to specify the volume on which a boot
- loader resides using a partition GUID value, but extracting a GUID
- from the partition data is harder than extracting the volume's
- label or counting up the filesystem numbers.</li>
-
- <li>Currently, if a filesystem's label comes up empty, rEFInd
- substitutes the size, so you get displays like <tt>boot
- EFI\foo\bar.efi from 90 GiB volume</tt>. I'd like to add more
- checks to substitute the GPT <i>partition</i> label if the
- <i>filesystem</i> label comes up empty.</li>
-
- <li>Along the lines of the previous item, the
- <tt>default_selection</tt> might be expanded to support some form
- of specification of disk types, as in a special entry for any
+ <li>The <tt>default_selection</tt> might be expanded to support some
+ form of specification of disk types, as in a special entry for any
optical disk or any external disk, no matter what its name is.</li>
<li>It would be useful to be able to specify paths to boot loaders
<tt>pmset</tt> to disable the <tt>autopoweroff</tt> option</a> is
<a
href="http://apple.stackexchange.com/questions/91529/macbook-air-not-waking-up-from-suspend-sleep-with-refind-boot-manager-installed">claimed
- by some</a> to at least partially fix the problem, though.</li>
+ by some</a> to at least partially fix the problem, though. Using
+ the <tt>--ownhfs</tt> installation option may also help in some
+ cases.</li>
</ul></li> <!-- Known bugs -->
Linux's EFI stub loader). Also along these lines, adding drivers
for Linux LVM and RAID setups would be useful.</li>
- <li>The HFS+ driver returns a volume label of "HFS+ volume", no matter
- what the volume's real label is.</li>
-
<li>This may not be possible, or it may require a new driver, but a way
to have the drivers access files (like a Linux loopback mount) is
desirable.</li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-4/20/2014, referencing rEFInd 0.7.9</p>
+5/4/2014, referencing rEFInd 0.8.0</p>
<p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p>For all such cases, rEFInd supports booting legacy OSes; however, the details vary between Macs and UEFI PCs. Also, be aware that some UEFI PCs lack the Compatibility Support Module (CSM) that's required for this feature to work. This is true even of some computers that can boot BIOS-based OSes natively. This can happen because the firmware is basically a BIOS with a UEFI implementation tacked on top of it; such systems rely on the native BIOS to boot, and may not provide a way for EFI applications to access the BIOS features via CSM mechanisms. If you have such a computer and if you enable a legacy boot option in the configuration file, rEFInd notifies you of its inability to present legacy boot options when it starts up. rEFInd's legacy boot support also depends on features that are not available in the GNU-EFI development package, so you may see a similar notice if you run a version of rEFInd compiled with that package. (The primary build available on the <a href="getting.html">Getting rEFInd</a> page is compiled with the TianoCore EDK2 package, which does support the BIOS boot features.)</p>
-<p>The <tt>scanfor</tt> option, described on the <a href="configfile.html">Configuring the Boot Manager</a> page, controls rEFInd's detection of legacy OSes. On Macs, the default is to scan for such OSes, since a common boot scenario on Macs is dual-booting OS X and Windows, and of course BIOS support is required for this. (rEFInd 0.4.5 and earlier did <i>not</i> scan for legacy OSes by default, though, so you may need to change this option if you're upgrading and don't want to scan for legacy OSes.) On UEFI PCs, rEFInd defaults to <i>not</i> scanning for legacy OSes; thus, you must edit the <tt>scanfor</tt> item in the configuration file if you want to boot a legacy OS on a UEFI PC.</p>
+<p>The <tt>scanfor</tt> option, described on the <a href="configfile.html">Configuring the Boot Manager</a> page, controls rEFInd's detection of legacy OSes. On Macs, the default is to scan for such OSes, since a common boot scenario on Macs is dual-booting OS X and Windows, and of course BIOS support is required for this. On UEFI PCs, rEFInd defaults to <i>not</i> scanning for legacy OSes; thus, you must edit the <tt>scanfor</tt> item in the configuration file if you want to boot a legacy OS on a UEFI PC.</p>
<img src="os_legacy.png" align="right" width="128" height="128"
alt="The legacy OS icon is identical for all OSes on UEFI-based PCs."
border=2 background="gray"/>
-<p>On Macs, rEFInd uses a flexible scanning algorithm inherited from rEFIt. This procedure detects most legacy OSes on most disks, although it can sometimes miss an OS. This scanning algorithm can often identify the legacy OS you've installed and present a suitable icon. On UEFI PCs, rEFInd relies on the computer's NVRAM settings to determine which legacy boot loaders to scan; if an OS isn't listed in the NVRAM settings, rEFInd won't present it as an option. On most UEFI PCs, at least one hard disk and your optical drive appear as options. The two computers I've tested have failed to present USB flash drives as boot options when inserted, though. You may be able to get additional options to appear by editing your boot list in your firmware's setup utility, but I can make no promises about this. The UEFI scanning procedure is also incapable of detecting the OS type, so you'll see a generic legacy OS icon, as shown at the right.</p>
+<p>On Macs, rEFInd uses a flexible scanning algorithm inherited from rEFIt. This procedure detects most legacy OSes on most disks, although it can sometimes miss an OS. This scanning algorithm can often identify the legacy OS you've installed and present a suitable icon. On UEFI PCs, rEFInd relies on the computer's NVRAM settings to determine which legacy boot loaders to scan, but rEFInd does tell the firmware to find every BIOS-mode boot option and add it to its NVRAM list. On most UEFI PCs, at least one hard disk and your optical drive appear as options. On one computer I tested (a Lenovo laptop), the internal hard disk appears in the rEFInd menu as a removable disk, and selecting any BIOS-mode option causes the computer to attempt a network boot. Three other computers I've tested behave more sensibly. If you opt to scan for BIOS-mode optical disks (<tt>scanfor cd</tt>) on UEFI-based PCs, an icon will appear whether or not your drive holds a CD. The UEFI scanning procedure is also incapable of detecting the OS type, so you'll see a generic legacy OS icon, as shown at the right.</p>
+
+<p>On both PCs and Macs, if you see non-functional legacy boot options, you can remove them by using the <tt>dont_scan_volumes</tt> token in <tt>refind.conf</tt>: Add any substring from the description that appears when you highlight the non-functional option to the set of options to have rEFInd ignore that entry. (Note that you must provide a complete volume name when excluding EFI volumes from scanning. The legacy-mode exclusion operation is more flexible in this regard.)</p>
<hr />
/** Helper macro for stringification. */
#define FSW_EFI_STRINGIFY(x) #x
/** Expands to the EFI driver name given the file system type name. */
-#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.7.9 " FSW_EFI_STRINGIFY(t) L" File System Driver"
+#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.8.0 " FSW_EFI_STRINGIFY(t) L" File System Driver"
// function prototypes
*/
/* Changes copyright (c) 2013 Roderick W. Smith */
-#define VERSION L"0.7.9"
+#define VERSION L"0.8.0"
//
// config
#
#also_scan_dirs boot,ESP2:EFI/linux/kernels
-# Partitions to omit from scans. You must specify a volume by its
-# label, which you can obtain in an EFI shell by typing "vol", from
-# Linux by typing "blkid /dev/{devicename}", or by examining the
-# disk's label in various OSes' file browsers.
+# Partitions (or whole disks, for legacy-mode boots) to omit from scans.
+# For EFI-mode scans, you must specify a volume by its label, which you
+# can obtain in an EFI shell by typing "vol", from Linux by typing
+# "blkid /dev/{devicename}", or by examining the disk's label in various
+# OSes' file browsers.
+# For legacy-mode scans, you can specify any subset of the boot loader
+# description shown when you highlight the option in rEFInd.
# The default is "Recovery HD,LRS_ESP".
#
#dont_scan_volumes "Recovery HD"
Summary: EFI boot manager software
Name: refind
-Version: 0.7.9
+Version: 0.8.0
Release: 1%{?dist}
Summary: EFI boot manager software
License: GPLv3
# wiping out the just-updated files.
%changelog
+* Sun May 4 2014 R Smith <rodsmith@rodsbooks.com> - 0.8.0
+- Updated spec file for 0.8.0
* Sun Apr 20 2014 R Smith <rodsmith@rodsbooks.com> - 0.7.9
- Updated spec file for 0.7.9
* Sun Mar 9 2014 R Smith <rodsmith@rodsbooks.com> - 0.7.8
Volume->BlockIO != Volume->WholeDiskBlockIO) {
for (VolumeIndex2 = 0; VolumeIndex2 < VolumesCount; VolumeIndex2++) {
if (Volumes[VolumeIndex2]->BlockIO == Volume->WholeDiskBlockIO &&
- Volumes[VolumeIndex2]->BlockIOOffset == 0)
+ Volumes[VolumeIndex2]->BlockIOOffset == 0) {
WholeDiskVolume = Volumes[VolumeIndex2];
+ }
}
}
Found = TRUE;
} // while
} // if
- return Found;
+ return Found;
} // BOOLEAN IsIn()
+// Returns TRUE if any element of List can be found as a substring of
+// BigString, FALSE otherwise. Performs comparisons case-insensitively.
+BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List) {
+ UINTN i = 0, ElementLength;
+ BOOLEAN Found = FALSE;
+ CHAR16 *OneElement;
+
+ if (BigString && List) {
+ while (!Found && (OneElement = FindCommaDelimited(List, i++))) {
+ ElementLength = StrLen(OneElement);
+ if ((ElementLength <= StrLen(BigString)) && (StriSubCmp(OneElement, BigString)))
+ Found = TRUE;
+ } // while
+ } // if
+ return Found;
+} // BOOLEAN IsSubstringIn()
+
// Returns TRUE if specified Volume, Directory, and Filename correspond to an
// element in the comma-delimited List, FALSE otherwise. Note that Directory and
// Filename must *NOT* include a volume or path specification (that's part of
INTN FindSubString(IN CHAR16 *SmallString, IN CHAR16 *BigString);
VOID SplitPathName(CHAR16 *InPath, CHAR16 **VolName, CHAR16 **Path, CHAR16 **Filename);
BOOLEAN IsIn(IN CHAR16 *Filename, IN CHAR16 *List);
+BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List);
BOOLEAN FilenameIn(IN REFIT_VOLUME *Volume, IN CHAR16 *Directory, IN CHAR16 *Filename, IN CHAR16 *List);
BOOLEAN VolumeNumberToName(REFIT_VOLUME *Volume, CHAR16 **VolName);
VOID MyFreePool(IN OUT VOID *Pointer);
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.9.5");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.0");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith");
#ifdef __MAKEWITH_TIANO
static VOID StartLegacyUEFI(LEGACY_ENTRY *Entry)
{
-// UINTN ExitDataSize = 0;
-// CHAR16 *ExitData = NULL;
-// EFI_STATUS Status;
-
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);
{
LEGACY_ENTRY *Entry, *SubEntry;
REFIT_MENU_SCREEN *SubScreen;
- CHAR16 *VolDesc;
+ CHAR16 *VolDesc, *LegacyTitle;
CHAR16 ShortcutLetter = 0;
if (LoaderTitle == NULL) {
else
VolDesc = (Volume->DiskKind == DISK_KIND_OPTICAL) ? L"CD" : L"HD";
+ LegacyTitle = AllocateZeroPool(256 * sizeof(CHAR16));
+ if (LegacyTitle != NULL)
+ SPrint(LegacyTitle, 255, L"Boot %s from %s", LoaderTitle, VolDesc);
+ if (IsInSubstring(LegacyTitle, GlobalConfig.DontScanVolumes)) {
+ MyFreePool(LegacyTitle);
+ return NULL;
+ } // if
+
// prepare the menu entry
Entry = AllocateZeroPool(sizeof(LEGACY_ENTRY));
- Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
- SPrint(Entry->me.Title, 255, L"Boot %s from %s", LoaderTitle, VolDesc);
+ Entry->me.Title = LegacyTitle;
Entry->me.Tag = TAG_LEGACY;
Entry->me.Row = 0;
Entry->me.ShortcutLetter = ShortcutLetter;
CHAR16 ShortcutLetter = 0;
CHAR16 *LegacyDescription = BdsOption->Description;
+ if (IsInSubstring(LegacyDescription, GlobalConfig.DontScanVolumes))
+ return NULL;
+
// prepare the menu entry
Entry = AllocateZeroPool(sizeof(LEGACY_ENTRY));
Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
UINTN Index = 0;
CHAR16 BootOption[10];
UINTN BootOrderSize = 0;
- CHAR16 Buffer[20];
- BDS_COMMON_OPTION *BdsOption;
- LIST_ENTRY TempList;
- BBS_BBS_DEVICE_PATH * BbsDevicePath = NULL;
+ CHAR16 Buffer[20];
+ BDS_COMMON_OPTION *BdsOption;
+ LIST_ENTRY TempList;
+ BBS_BBS_DEVICE_PATH *BbsDevicePath = NULL;
+ BOOLEAN SearchingForUsb = FALSE;
InitializeListHead (&TempList);
ZeroMem (Buffer, sizeof (Buffer));
if (EFI_ERROR (Status))
return;
+ // EFI calls USB drives BBS_HARDDRIVE, but we want to distinguish them,
+ // so we set DiskType inappropriately elsewhere in the program and
+ // "translate" it here.
+ if (DiskType == BBS_USB) {
+ DiskType = BBS_HARDDISK;
+ SearchingForUsb = TRUE;
+ } // if
+
// Grab the boot order
BootOrder = BdsLibGetVariableAndSize(L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderSize);
if (BootOrder == NULL) {
if (BdsOption != NULL) {
BbsDevicePath = (BBS_BBS_DEVICE_PATH *)BdsOption->DevicePath;
-
// Only add the entry if it is of a requested type (e.g. USB, HD)
-
// Two checks necessary because some systems return EFI boot loaders
// with a DeviceType value that would inappropriately include them
// as legacy loaders....
if ((BbsDevicePath->DeviceType == DiskType) && (BdsOption->DevicePath->Type == DEVICE_TYPE_BIOS)) {
- AddLegacyEntryUEFI(BdsOption, BbsDevicePath->DeviceType);
- }
- }
+ // USB flash drives appear as hard disks with certain media flags set.
+ // Look for this, and if present, pass it on with the (technically
+ // incorrect, but internally useful) BBS_TYPE_USB flag set.
+ if (DiskType == BBS_HARDDISK) {
+ if (SearchingForUsb && (BbsDevicePath->StatusFlag & (BBS_MEDIA_PRESENT | BBS_MEDIA_MAYBE_PRESENT))) {
+ AddLegacyEntryUEFI(BdsOption, BBS_USB);
+ } else if (!SearchingForUsb && !(BbsDevicePath->StatusFlag & (BBS_MEDIA_PRESENT | BBS_MEDIA_MAYBE_PRESENT))) {
+ AddLegacyEntryUEFI(BdsOption, DiskType);
+ }
+ } else {
+ AddLegacyEntryUEFI(BdsOption, DiskType);
+ } // if/else
+ } // if
+ } // if (BdsOption != NULL)
Index++;
- }
+ } // while
} /* static VOID ScanLegacyUEFI() */
#endif // __MAKEWITH_GNUEFI
ScanLegacyVolume(Volume, VolumeIndex);
} // for
} else if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) {
+ // TODO: This actually picks up USB flash drives, too; try to find
+ // a way to differentiate the two....
ScanLegacyUEFI(BBS_HARDDISK);
}
} /* static VOID ScanLegacyInternal() */
ScanLegacyVolume(Volume, VolumeIndex);
} // for
} else if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) {
+ // TODO: This actually doesn't do anything useful; leaving in hopes of
+ // fixing it later....
ScanLegacyUEFI(BBS_USB);
}
} /* static VOID ScanLegacyExternal() */
// Locates boot loaders. NOTE: This assumes that GlobalConfig.LegacyType is set correctly.
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();
+ UINTN i;
+#ifdef __MAKEWITH_TIANO
+ CHAR8 s;
+ BOOLEAN ScanForLegacy = FALSE;
+
+ // Determine up-front if we'll be scanning for legacy loaders....
+ for (i = 0; i < NUM_SCAN_OPTIONS; i++) {
+ s = GlobalConfig.ScanFor[i];
+ if ((s == 'c') || (s == 'C') || (s == 'h') || (s == 'H') || (s == 'b') || (s == 'B'))
+ ScanForLegacy = TRUE;
+ } // for
+
+ // If UEFI & scanning for legacy loaders, update NVRAM boot manager list
+ if ((GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) && ScanForLegacy) {
+ BdsDeleteAllInvalidLegacyBootOptions();
+ BdsAddNonExistingLegacyBootOptions();
+ } // if
+#endif
// scan for loaders and tools, add them to the menu
for (i = 0; i < NUM_SCAN_OPTIONS; i++) {