]> code.delx.au - refind/blobdiff - refind/main.c
Fixed bug that caused volume icons to be read only from default icons
[refind] / refind / main.c
index ebbb9e2303ef88146ed401de3587343e95234299..881ac38182b9a600e32b54df15efdd646395dbce 100644 (file)
@@ -64,6 +64,8 @@
 #include "menu.h"
 #include "mok.h"
 #include "gpt.h"
+#include "apple.h"
+#include "mystrings.h"
 #include "security_policy.h"
 #include "driver_support.h"
 #include "../include/Handle.h"
@@ -112,6 +114,17 @@ EFI_GUID gFreedesktopRootGuid = { 0x4f68bce3, 0xe8cd, 0x4db1, { 0x96, 0xe7, 0xfb
 #define FALLBACK_BASENAME       L"bootia32.efi"
 #define EFI_STUB_ARCH           0x014c
 EFI_GUID gFreedesktopRootGuid = { 0x44479540, 0xf297, 0x41b2, { 0x9a, 0xf7, 0xd1, 0x31, 0xd5, 0xf0, 0x45, 0x8a }};
+#elif defined (EFIAARCH64)
+#define SHELL_NAMES             L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellaa64.efi,\\shell.efi,\\shellaa64.efi"
+#define GPTSYNC_NAMES           L"\\EFI\\tools\\gptsync.efi,\\EFI\\tools\\gptsync_aa64.efi"
+#define GDISK_NAMES             L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_aa64.efi"
+#define NETBOOT_NAMES           L"\\EFI\\tools\\ipxe.efi"
+#define MEMTEST_NAMES           L"memtest86.efi,memtest86_aa64.efi,memtest86aa64.efi,bootaa64.efi"
+#define DRIVER_DIRS             L"drivers,drivers_aa64"
+#define FALLBACK_FULLNAME       L"EFI\\BOOT\\bootaa64.efi"
+#define FALLBACK_BASENAME       L"bootaa64.efi"
+#define EFI_STUB_ARCH           0xaa64
+EFI_GUID gFreedesktopRootGuid = { 0xb921b045, 0x1df0, 0x41c3, { 0xaf, 0x44, 0x4c, 0x6f, 0x28, 0x0d, 0x3f, 0xae }};
 #else
 #define SHELL_NAMES             L"\\EFI\\tools\\shell.efi,\\shell.efi"
 #define GPTSYNC_NAMES           L"\\EFI\\tools\\gptsync.efi"
@@ -121,8 +134,8 @@ EFI_GUID gFreedesktopRootGuid = { 0x44479540, 0xf297, 0x41b2, { 0x9a, 0xf7, 0xd1
 #define DRIVER_DIRS             L"drivers"
 #define FALLBACK_FULLNAME       L"EFI\\BOOT\\boot.efi" /* Not really correct */
 #define FALLBACK_BASENAME       L"boot.efi"            /* Not really correct */
-// Below is GUID for ARM64
-EFI_GUID gFreedesktopRootGuid = { 0xb921b045, 0x1df0, 0x41c3, { 0xaf, 0x44, 0x4c, 0x6f, 0x28, 0x0d, 0x3f, 0xae }};
+// Below is GUID for ARM32
+EFI_GUID gFreedesktopRootGuid = { 0x69dad710, 0x2ce4, 0x4e3c, { 0xb1, 0x6c, 0x21, 0xa1, 0xd4, 0x9a, 0xbe, 0xd3 }};
 #endif
 #define FAT_ARCH                0x0ef1fab9 /* ID for Apple "fat" binary */
 
@@ -139,7 +152,7 @@ EFI_GUID gFreedesktopRootGuid = { 0xb921b045, 0x1df0, 0x41c3, { 0xaf, 0x44, 0x4c
 // Patterns that identify Linux kernels. Added to the loader match pattern when the
 // scan_all_linux_kernels option is set in the configuration file. Causes kernels WITHOUT
 // a ".efi" extension to be found when scanning for boot loaders.
-#define LINUX_MATCH_PATTERNS    L"vmlinuz*,bzImage*"
+#define LINUX_MATCH_PATTERNS    L"vmlinuz*,bzImage*,kernel*"
 
 // Maximum length of a text string in certain menus
 #define MAX_LINE_LENGTH 65
@@ -150,6 +163,7 @@ static REFIT_MENU_ENTRY MenuEntryShutdown = { L"Shut Down Computer", TAG_SHUTDOW
 REFIT_MENU_ENTRY MenuEntryReturn   = { L"Return to Main Menu", TAG_RETURN, 1, 0, 0, NULL, NULL, NULL };
 static REFIT_MENU_ENTRY MenuEntryExit     = { L"Exit rEFInd", TAG_EXIT, 1, 0, 0, NULL, NULL, NULL };
 static REFIT_MENU_ENTRY MenuEntryFirmware = { L"Reboot to Computer Setup Utility", TAG_FIRMWARE, 1, 0, 0, NULL, NULL, NULL };
+static REFIT_MENU_ENTRY MenuEntryRotateCsr = { L"Change SIP Policy", TAG_CSR_ROTATE, 1, 0, 0, NULL, NULL, NULL };
 
 REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL, 0, L"Automatic boot",
                                      L"Use arrow keys to move cursor; Enter to boot;",
@@ -160,7 +174,7 @@ REFIT_CONFIG GlobalConfig = { FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0, 0, DONT_CHA
                               20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC,
                               0, 0, { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE },
                               BANNER_NOSCALE, NULL, NULL, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL,
-                              NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               { TAG_SHELL, TAG_MEMTEST, TAG_GDISK, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY,
                                 TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE,
                                 0, 0, 0, 0, 0, 0, 0, 0 }
@@ -185,11 +199,12 @@ struct LOADER_LIST {
 
 static VOID AboutrEFInd(VOID)
 {
-    CHAR16 *FirmwareVendor;
+    CHAR16     *FirmwareVendor;
+    UINT32     CsrStatus;
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.2.3");
+        AddMenuInfoLine(&AboutMenu, PoolPrint(L"rEFInd Version %s", REFIND_VERSION));
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith");
@@ -204,9 +219,16 @@ static VOID AboutrEFInd(VOID)
 #elif defined(EFIX64)
         AddMenuInfoLine(&AboutMenu, PoolPrint(L" Platform: x86_64 (64 bit); Secure Boot %s",
                                               secure_mode() ? L"active" : L"inactive"));
+#elif defined(EFIAARCH64)
+        AddMenuInfoLine(&AboutMenu, PoolPrint(L" Platform: ARM (64 bit); Secure Boot %s",
+                                              secure_mode() ? L"active" : L"inactive"));
 #else
         AddMenuInfoLine(&AboutMenu, L" Platform: unknown");
 #endif
+        if (GetCsrStatus(&CsrStatus) == EFI_SUCCESS) {
+            RecordgCsrStatus(CsrStatus, FALSE);
+            AddMenuInfoLine(&AboutMenu, gCsrStatus);
+        }
         FirmwareVendor = StrDuplicate(ST->FirmwareVendor);
         LimitStringLength(FirmwareVendor, MAX_LINE_LENGTH); // More than ~65 causes empty info page on 800x600 display
         AddMenuInfoLine(&AboutMenu, PoolPrint(L" Firmware: %s %d.%02d", FirmwareVendor, ST->FirmwareRevision >> 16,
@@ -251,7 +273,7 @@ static VOID WarnSecureBootError(CHAR16 *Name, BOOLEAN Verbose) {
 // Returns TRUE if this file is a valid EFI loader file, and is proper ARCH
 static BOOLEAN IsValidLoader(EFI_FILE *RootDir, CHAR16 *FileName) {
     BOOLEAN         IsValid = TRUE;
-#if defined (EFIX64) | defined (EFI32)
+#if defined (EFIX64) | defined (EFI32) | defined (EFIAARCH64)
     EFI_STATUS      Status;
     EFI_FILE_HANDLE FileHandle;
     CHAR8           Header[512];
@@ -475,6 +497,7 @@ VOID StoreLoaderName(IN CHAR16 *Name) {
 // for information on Intel VMX features
 static VOID DoEnableAndLockVMX(VOID)
 {
+#if defined (EFIX64) | defined (EFI32)
     UINT32 msr = 0x3a;
     UINT32 low_bits = 0, high_bits = 0;
 
@@ -487,7 +510,8 @@ static VOID DoEnableAndLockVMX(VOID)
         low_bits = 0x05;
         msr = 0x3a;
         __asm__ volatile ("wrmsr" : : "c" (msr), "a" (low_bits), "d" (high_bits));
-    } 
+    }
+#endif
 } // VOID DoEnableAndLockVMX()
 
 static VOID StartLoader(LOADER_ENTRY *Entry, CHAR16 *SelectionName)
@@ -995,7 +1019,7 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo
     } // if/else network boot
 
     // detect specific loaders
-    if (StriSubCmp(L"bzImage", NameClues) || StriSubCmp(L"vmlinuz", NameClues)) {
+    if (StriSubCmp(L"bzImage", NameClues) || StriSubCmp(L"vmlinuz", NameClues) || StriSubCmp(L"kernel", NameClues)) {
         if (Volume->DiskKind != DISK_KIND_NET) {
             GuessLinuxDistribution(&OSIconName, Volume, LoaderPath);
             Entry->LoadOptions = GetMainLinuxOptions(LoaderPath, Volume);
@@ -1153,16 +1177,22 @@ INTN TimeComp(IN EFI_TIME *Time1, IN EFI_TIME *Time2) {
     return 0;
 } // INTN TimeComp()
 
-// Adds a loader list element, keeping it sorted by date. Returns the new
-// first element (the one with the most recent date).
+// Adds a loader list element, keeping it sorted by date. EXCEPTION: Fedora's rescue
+// kernel, which begins with "vmlinuz-0-rescue," should not be at the top of the list,
+// since that will make it the default if kernel folding is enabled, so float it to
+// the end.
+// Returns the new first element (the one with the most recent date).
 static struct LOADER_LIST * AddLoaderListEntry(struct LOADER_LIST *LoaderList, struct LOADER_LIST *NewEntry) {
     struct LOADER_LIST *LatestEntry, *CurrentEntry, *PrevEntry = NULL;
+    BOOLEAN LinuxRescue = FALSE;
 
     LatestEntry = CurrentEntry = LoaderList;
     if (LoaderList == NULL) {
         LatestEntry = NewEntry;
     } else {
-        while ((CurrentEntry != NULL) && (TimeComp(&(NewEntry->TimeStamp), &(CurrentEntry->TimeStamp)) < 0)) {
+        if (StriSubCmp(L"vmlinuz-0-rescue", NewEntry->FileName))
+            LinuxRescue = TRUE;
+        while ((CurrentEntry != NULL) && (LinuxRescue || (TimeComp(&(NewEntry->TimeStamp), &(CurrentEntry->TimeStamp)) < 0))) {
             PrevEntry = CurrentEntry;
             CurrentEntry = CurrentEntry->NextEntry;
         } // while
@@ -1409,7 +1439,9 @@ static BOOLEAN ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16
 
        NewLoader = LoaderList;
        while (NewLoader != NULL) {
-           IsLinux = (StriSubCmp(L"bzImage", NewLoader->FileName) || StriSubCmp(L"vmlinuz", NewLoader->FileName));
+           IsLinux = (StriSubCmp(L"bzImage", NewLoader->FileName) ||
+                      StriSubCmp(L"vmlinuz", NewLoader->FileName) ||
+                      StriSubCmp(L"kernel", NewLoader->FileName));
            if ((FirstKernel != NULL) && IsLinux && GlobalConfig.FoldLinuxKernels) {
                AddKernelToSubmenu(FirstKernel, NewLoader->FileName, Volume);
            } else {
@@ -1905,6 +1937,7 @@ static VOID ScanForTools(VOID) {
     UINTN i, j, VolumeIndex;
     UINT64 osind;
     CHAR8 *b = 0;
+    UINT32 CsrValue;
 
     MokLocations = StrDuplicate(MOK_LOCATIONS);
     if (MokLocations != NULL)
@@ -2035,6 +2068,14 @@ static VOID ScanForTools(VOID) {
                 FindTool(MokLocations, MOK_NAMES, L"MOK utility", BUILTIN_ICON_TOOL_MOK_TOOL);
                 break;
 
+            case TAG_CSR_ROTATE:
+                if ((GetCsrStatus(&CsrValue) == EFI_SUCCESS) && (GlobalConfig.CsrValues)) {
+                    TempMenuEntry = CopyMenuEntry(&MenuEntryRotateCsr);
+                    TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_CSR_ROTATE);
+                    AddMenuEntry(&MainMenu, TempMenuEntry);
+                } // if
+                break;
+
             case TAG_MEMTEST:
                 FindTool(MEMTEST_LOCATIONS, MEMTEST_NAMES, L"Memory test utility", BUILTIN_ICON_TOOL_MEMTEST);
                 break;
@@ -2056,9 +2097,9 @@ static VOID RescanAll(BOOLEAN DisplayMessage) {
     FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount);
     MainMenu.Entries = NULL;
     MainMenu.EntryCount = 0;
-    ReadConfig(GlobalConfig.ConfigFilename);
     ConnectAllDriversToAllControllers();
     ScanVolumes();
+    ReadConfig(GlobalConfig.ConfigFilename);
     ScanForBootloaders();
     ScanForTools();
     SetupScreen();
@@ -2144,60 +2185,6 @@ static VOID SetConfigFilename(EFI_HANDLE ImageHandle) {
     } // if
 } // VOID SetConfigFilename()
 
-
-#define EFI_APPLE_SET_OS_PROTOCOL_GUID  \
-  { 0xc5c5da95, 0x7d5c, 0x45e6, \
-    { 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77 } \
-  }
-
-typedef struct EfiAppleSetOsInterface {
-    UINT64 Version;
-    EFI_STATUS EFIAPI (*SetOsVersion) (IN CHAR8 *Version);
-    EFI_STATUS EFIAPI (*SetOsVendor) (IN CHAR8 *Vendor);
-} EfiAppleSetOsInterface;
-
-// Function to tell the firmware that OS X is being launched. This is
-// required to work around problems on some Macs that don't fully
-// initialize some hardware (especially video displays) when third-party
-// OSes are launched in EFI mode.
-static EFI_STATUS SetAppleOSInfo() {
-    CHAR16 *AppleOSVersion = NULL;
-    CHAR8 *AppleOSVersion8 = NULL;
-    EFI_STATUS Status;
-    EFI_GUID apple_set_os_guid = EFI_APPLE_SET_OS_PROTOCOL_GUID;
-    EfiAppleSetOsInterface *SetOs = NULL;
-
-    Status = refit_call3_wrapper(BS->LocateProtocol, &apple_set_os_guid, NULL, (VOID**) &SetOs);
-
-    // Not a Mac, so ignore the call....
-    if ((Status != EFI_SUCCESS) || (!SetOs))
-        return EFI_SUCCESS;
-
-    if ((SetOs->Version != 0) && GlobalConfig.SpoofOSXVersion) {
-        AppleOSVersion = StrDuplicate(L"Mac OS X");
-        MergeStrings(&AppleOSVersion, GlobalConfig.SpoofOSXVersion, ' ');
-        AppleOSVersion8 = AllocateZeroPool((StrLen(AppleOSVersion) + 1) * sizeof(CHAR8));
-        UnicodeStrToAsciiStr(AppleOSVersion, AppleOSVersion8);
-        if (AppleOSVersion8) {
-            Status = refit_call1_wrapper (SetOs->SetOsVersion, AppleOSVersion8);
-            if (!EFI_ERROR(Status))
-                Status = EFI_SUCCESS;
-        } else {
-            Status = EFI_OUT_OF_RESOURCES;
-            Print(L"Out of resources!\n");
-        }
-        if ((Status == EFI_SUCCESS) && (SetOs->Version == 2))
-            Status = refit_call1_wrapper (SetOs->SetOsVendor, "Apple Inc.");
-    } // if
-
-    if (Status != EFI_SUCCESS)
-        Print(L"Unable to set firmware boot type!\n");
-
-    MyFreePool(AppleOSVersion);
-    MyFreePool(AppleOSVersion8);
-    return (Status);
-} // EFI_STATUS SetAppleOSInfo()
-
 //
 // main entry point
 //
@@ -2225,7 +2212,11 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC)
        CopyMem(GlobalConfig.ScanFor, "ihebocm   ", NUM_SCAN_OPTIONS);
     SetConfigFilename(ImageHandle);
+    MokProtocol = SecureBootSetup();
+    LoadDrivers();
+    ScanVolumes(); // Do before ReadConfig() because it needs SelfVolume->VolName
     ReadConfig(GlobalConfig.ConfigFilename);
+    SetVolumeIcons();
 
     if (GlobalConfig.SpoofOSXVersion && GlobalConfig.SpoofOSXVersion[0] != L'\0')
         SetAppleOSInfo();
@@ -2238,9 +2229,6 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     refit_call4_wrapper(BS->SetWatchdogTimer, 0x0000, 0x0000, 0x0000, NULL);
 
     // further bootstrap (now with config available)
-    MokProtocol = SecureBootSetup();
-    LoadDrivers();
-    ScanVolumes();
     ScanForBootloaders();
     ScanForTools();
     SetupScreen();
@@ -2317,6 +2305,10 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                 RebootIntoFirmware();
                 break;
 
+            case TAG_CSR_ROTATE:
+                RotateCsrValue();
+                break;
+
         } // switch()
     } // while()