X-Git-Url: https://code.delx.au/refind/blobdiff_plain/9ddca21dde439f353f85362e7a084fa999764497..40f640cba5b0b4136e6af59625242b623c28dca4:/refind/main.c diff --git a/refind/main.c b/refind/main.c index 6e79bc1..de40bd9 100644 --- a/refind/main.c +++ b/refind/main.c @@ -53,6 +53,10 @@ #include "driver_support.h" #include "../include/syslinux_mbr.h" +#ifdef __MAKEWITH_TIANO +#include "../EfiLib/BdsHelper.h" +#endif // __MAKEWITH_TIANO + // // variables @@ -89,7 +93,8 @@ static REFIT_MENU_ENTRY MenuEntryExit = { L"Exit rEFInd", TAG_EXIT, 1, 0, 0, static REFIT_MENU_SCREEN MainMenu = { L"Main Menu", NULL, 0, NULL, 0, NULL, 0, L"Automatic boot" }; static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL }; -REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, {TAG_SHELL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }}; // Structure used to hold boot loader filenames and time stamps in @@ -110,7 +115,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.3.2"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.5.4"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith"); @@ -198,7 +203,9 @@ static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths, MergeStrings(&FullLoadOptions, L" ", 0); // NOTE: That last space is also added by the EFI shell and seems to be significant // when passing options to Apple's boot.efi... - } + } else { + MergeStrings(&FullLoadOptions, LoadOptions, 0); + } // if/else // NOTE: We also include the terminating null in the length for safety. ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions; ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16); @@ -1137,8 +1144,9 @@ static VOID StartLegacy(IN LEGACY_ENTRY *Entry) (UGAHeight - BootLogoImage->Height) >> 1, &StdBackgroundPixel); - if (Entry->Volume->IsMbrPartition) + if (Entry->Volume->IsMbrPartition) { ActivateMbrPartition(Entry->Volume->WholeDiskBlockIO, Entry->Volume->MbrPartitionIndex); + } ExtractLegacyLoaderPaths(DiscoveredPathList, MAX_DISCOVERED_PATHS, LegacyLoaderList); @@ -1154,6 +1162,15 @@ static VOID StartLegacy(IN LEGACY_ENTRY *Entry) FinishExternalScreen(); } /* static VOID StartLegacy() */ +// Start a device on a non-Mac using the EFI_LEGACY_BIOS_PROTOCOL +#ifdef __MAKEWITH_TIANO +static VOID StartLegacyNonMac(IN LEGACY_ENTRY *Entry) +{ + BdsLibConnectDevicePath (Entry->BdsOption->DevicePath); + BdsLibDoLegacyBoot(Entry->BdsOption); +} +#endif // __MAKEWITH_TIANO + static LEGACY_ENTRY * AddLegacyEntry(IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Volume) { LEGACY_ENTRY *Entry, *SubEntry; @@ -1209,6 +1226,111 @@ static LEGACY_ENTRY * AddLegacyEntry(IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Vo return Entry; } /* static LEGACY_ENTRY * AddLegacyEntry() */ + +#ifdef __MAKEWITH_TIANO +/** + Create a rEFInd boot option from a Legacy BIOS protocol option. +*/ +static LEGACY_ENTRY * AddLegacyEntryNonMac(BDS_COMMON_OPTION *BdsOption, IN UINT16 DiskType) +{ + LEGACY_ENTRY *Entry, *SubEntry; + REFIT_MENU_SCREEN *SubScreen; + CHAR16 ShortcutLetter = 0; + CHAR16 *LegacyDescription = BdsOption->Description; + + // prepare the menu entry + Entry = AllocateZeroPool(sizeof(LEGACY_ENTRY)); + Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(Entry->me.Title, 255, L"Boot legacy target %s", LegacyDescription); + Entry->me.Tag = TAG_LEGACY_NON_MAC; + Entry->me.Row = 0; + Entry->me.ShortcutLetter = ShortcutLetter; + Entry->me.Image = LoadOSIcon(L"legacy", L"legacy", TRUE); + Entry->LoadOptions = (DiskType == BBS_CDROM) ? L"CD" : + ((DiskType == BBS_USB) ? L"USB" : L"HD"); + Entry->me.BadgeImage = NULL; + Entry->BdsOption = BdsOption; + Entry->Enabled = TRUE; + + // create the submenu + SubScreen = AllocateZeroPool(sizeof(REFIT_MENU_SCREEN)); + SubScreen->Title = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(SubScreen->Title, 255, L"No boot options for legacy target"); + SubScreen->TitleImage = Entry->me.Image; + + // default entry + SubEntry = AllocateZeroPool(sizeof(LEGACY_ENTRY)); + SubEntry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(SubEntry->me.Title, 255, L"Boot %s", LegacyDescription); + SubEntry->me.Tag = TAG_LEGACY_NON_MAC; + Entry->BdsOption = BdsOption; + AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry); + + AddMenuEntry(SubScreen, &MenuEntryReturn); + Entry->me.SubScreen = SubScreen; + AddMenuEntry(&MainMenu, (REFIT_MENU_ENTRY *)Entry); + return Entry; +} /* static LEGACY_ENTRY * AddLegacyEntryNonMac() */ + +/** + Scan for legacy BIOS targets on machines that implement EFI_LEGACY_BIOS_PROTOCOL. + In testing, protocol has not been implemented on Macs but has been + implemented on several Dell PCs and an ASUS motherboard. +*/ +static VOID ScanLegacyNonMac(IN UINTN DiskType) +{ + EFI_STATUS Status; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + UINT16 *BootOrder = NULL; + UINTN Index = 0; + UINT16 BootOption[10]; + UINTN BootOrderSize = 0; + CHAR16 Buffer[20]; + BDS_COMMON_OPTION *BdsOption; + LIST_ENTRY TempList; + BBS_BBS_DEVICE_PATH * BbsDevicePath = NULL; + + InitializeListHead (&TempList); + ZeroMem (Buffer, sizeof (Buffer)); + + // If LegacyBios protocol is not implemented on this platform, then + //we do not support this type of legacy boot on this machine. + Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) + return; + + // Grab the boot order + BootOrder = BdsLibGetVariableAndSize (L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderSize); + if (BootOrder == NULL) { + BootOrderSize = 0; + } + + Index = 0; + while (Index < BootOrderSize / sizeof (UINT16)) + { + // Grab each boot option variable from the boot order, and convert + // the variable into a BDS boot option + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); + BdsOption = BdsLibVariableToOption (&TempList, BootOption); + + if(BdsOption != NULL) { + //Print(L"Option description = '%s'\n", BdsOption->Description); + BbsDevicePath = (BBS_BBS_DEVICE_PATH *)BdsOption->DevicePath; + + // Only add the entry if it is of a supported type (e.g. USB, HD) + // See BdsHelper.c for currently supported types + if (BbsDevicePath->DeviceType == DiskType) { +// if(IsBbsDeviceTypeSupported(BbsDevicePath->DeviceType)) { + AddLegacyEntryNonMac(BdsOption, BbsDevicePath->DeviceType); + } + } + Index++; + } +} /* static VOID ScanLegacyNonMac() */ +#else +static VOID ScanLegacyNonMac(IN UINTN DiskType){} +#endif // __MAKEWITH_TIANO + static VOID ScanLegacyVolume(REFIT_VOLUME *Volume, UINTN VolumeIndex) { UINTN VolumeIndex2; BOOLEAN ShowVolume, HideIfOthersFound; @@ -1246,11 +1368,15 @@ static VOID ScanLegacyDisc(VOID) UINTN VolumeIndex; REFIT_VOLUME *Volume; - for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { - Volume = Volumes[VolumeIndex]; - if (Volume->DiskKind == DISK_KIND_OPTICAL) - ScanLegacyVolume(Volume, VolumeIndex); - } // for + if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) { + for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { + Volume = Volumes[VolumeIndex]; + if (Volume->DiskKind == DISK_KIND_OPTICAL) + ScanLegacyVolume(Volume, VolumeIndex); + } // for + } else if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) { + ScanLegacyNonMac(BBS_CDROM); + } } /* static VOID ScanLegacyDisc() */ // Scan internal hard disks for legacy (BIOS) boot code @@ -1260,11 +1386,15 @@ static VOID ScanLegacyInternal(VOID) UINTN VolumeIndex; REFIT_VOLUME *Volume; - for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { - Volume = Volumes[VolumeIndex]; - if (Volume->DiskKind == DISK_KIND_INTERNAL) - ScanLegacyVolume(Volume, VolumeIndex); - } // for + if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) { + for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { + Volume = Volumes[VolumeIndex]; + if (Volume->DiskKind == DISK_KIND_INTERNAL) + ScanLegacyVolume(Volume, VolumeIndex); + } // for + } else if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) { + ScanLegacyNonMac(BBS_HARDDISK); + } } /* static VOID ScanLegacyInternal() */ // Scan external disks for legacy (BIOS) boot code @@ -1274,11 +1404,15 @@ static VOID ScanLegacyExternal(VOID) UINTN VolumeIndex; REFIT_VOLUME *Volume; - for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { - Volume = Volumes[VolumeIndex]; - if (Volume->DiskKind == DISK_KIND_EXTERNAL) - ScanLegacyVolume(Volume, VolumeIndex); - } // for + if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) { + for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { + Volume = Volumes[VolumeIndex]; + if (Volume->DiskKind == DISK_KIND_EXTERNAL) + ScanLegacyVolume(Volume, VolumeIndex); + } // for + } else if (GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) { + ScanLegacyNonMac(BBS_USB); + } } /* static VOID ScanLegacyExternal() */ // @@ -1457,11 +1591,24 @@ static VOID LoadDrivers(VOID) ConnectAllDriversToAllControllers(); } /* static VOID LoadDrivers() */ + static VOID ScanForBootloaders(VOID) { - UINTN i; + UINTN i; +#ifdef __MAKEWITH_TIANO + EFI_STATUS Status; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; +#endif ScanVolumes(); +#ifdef __MAKEWITH_TIANO + // Check for UEFI-style legacy BIOS support. If present, set the appropriate + // GlobalConfig flag for it. + Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios); + if (!EFI_ERROR (Status)) + GlobalConfig.LegacyType = LEGACY_TYPE_UEFI; +#endif + // scan for loaders and tools, add them to the menu for (i = 0; i < NUM_SCAN_OPTIONS; i++) { switch(GlobalConfig.ScanFor[i]) { @@ -1575,6 +1722,7 @@ static VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *System // gImageHandle = ImageHandle; gBS = SystemTable->BootServices; // gRS = SystemTable->RuntimeServices; + gRT = SystemTable->RuntimeServices; // Some BDS functions need gRT to be set EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS); InitializeConsoleSim(); @@ -1592,8 +1740,9 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) EFI_STATUS Status; BOOLEAN MainLoopRunning = TRUE; REFIT_MENU_ENTRY *ChosenEntry; - UINTN MenuExit; + UINTN MenuExit, i; CHAR16 *Selection; + EG_PIXEL BGColor; // bootstrap InitializeLib(ImageHandle, SystemTable); @@ -1603,7 +1752,7 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) return Status; // read configuration - CopyMem(GlobalConfig.ScanFor, "ieo ", NUM_SCAN_OPTIONS); + CopyMem(GlobalConfig.ScanFor, "ieom ", NUM_SCAN_OPTIONS); ReadConfig(); MainMenu.TimeoutSeconds = GlobalConfig.Timeout; @@ -1612,6 +1761,15 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) // further bootstrap (now with config available) SetupScreen(); + if (GlobalConfig.ScanDelay > 0) { + BGColor.b = 255; + BGColor.g = 175; + BGColor.r = 100; + BGColor.a = 0; + egDisplayMessage(L"Pausing before disk scan; please wait....", &BGColor); + for (i = 0; i < GlobalConfig.ScanDelay; i++) + refit_call1_wrapper(BS->Stall, 1000000); + } // if LoadDrivers(); ScanForBootloaders(); ScanForTools(); @@ -1652,6 +1810,12 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) StartLegacy((LEGACY_ENTRY *)ChosenEntry); break; +#ifdef __MAKEWITH_TIANO + case TAG_LEGACY_NON_MAC: // Boot a legacy OS on a non-Mac + StartLegacyNonMac((LEGACY_ENTRY *)ChosenEntry); + break; +#endif // __MAKEWITH_TIANO + case TAG_TOOL: // Start a EFI tool StartTool((LOADER_ENTRY *)ChosenEntry); break;