From: srs5694 Date: Sun, 16 Jun 2013 23:31:13 +0000 (-0400) Subject: Scan /etc/fstab to extract a root= option if refind_linux.conf isn't X-Git-Url: https://code.delx.au/refind/commitdiff_plain/012b59e3b9537d04f9bd7f66a3d673fa999e80a4 Scan /etc/fstab to extract a root= option if refind_linux.conf isn't found. --- diff --git a/NEWS.txt b/NEWS.txt index d240d41..1302fe7 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,11 @@ +0.6.12 (?/??/2013): +------------------- + +- Added code to determine Linux root filesystem from /etc/fstab file, if + it's on the same partition as the kernel and if the refind_linux.conf + file is not available. This enables rEFInd to boot Linux without any + rEFInd-specific configuration files on some (but not all) systems. + 0.6.11 (5/13/2013): ------------------- diff --git a/docs/refind/themes.html b/docs/refind/themes.html index 771ab8d..3410cae 100644 --- a/docs/refind/themes.html +++ b/docs/refind/themes.html @@ -274,6 +274,8 @@ to be tedious.

  • The Gris Theme (also available as an Arch Linux package.)
  • +
  • The Mac theme was created by Wesley Turner-Harris. See Wesley's Web site if you want to contact the creator of this theme.
  • +

    If you've created or discovered another rEFInd theme, please tell me about it so that I can provide a link to it from this page.

    diff --git a/refind/config.c b/refind/config.c index 30b3c1f..97c62d6 100644 --- a/refind/config.c +++ b/refind/config.c @@ -781,6 +781,65 @@ VOID ScanUserConfigured(CHAR16 *FileName) } // if() } // VOID ScanUserConfigured() +// Create an options file based on /etc/fstab. The resulting file has two options +// lines, one of which boots the system with "ro root={rootfs}" and the other of +// which boots the system with "ro root={rootfs} single", where "{rootfs}" is the +// filesystem identifier associated with the "/" line in /etc/fstab. +static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { + UINTN TokenCount, i; + REFIT_FILE *Options = NULL, *Fstab = NULL; + EFI_STATUS Status; + CHAR16 **TokenList, Line[513], Root[100]; + + if (FileExists(Volume->RootDir, L"\\etc\\fstab")) { + Options = AllocateZeroPool(sizeof(REFIT_FILE)); + Fstab = AllocateZeroPool(sizeof(REFIT_FILE)); + Status = ReadFile(Volume->RootDir, L"\\etc\\fstab", Fstab, &i); + if (CheckError(Status, L"while reading /etc/fstab")) { + if (Options != NULL) + FreePool(Options); + if (Fstab != NULL) + FreePool(Fstab); + Options = NULL; + Fstab = NULL; + } else { // File read; locate root fs and create entries + Options->Encoding = ENCODING_UTF16_LE; + Line[0] = '\0'; + while ((TokenCount = ReadTokenLine(Fstab, &TokenList)) > 0) { + if (TokenCount > 2) { + Root[0] = '\0'; + if (StriCmp(TokenList[1], L"\\") == 0) { + SPrint(Root, 99, L"%s", TokenList[0]); + } else if (StriCmp(TokenList[2], L"\\") == 0) { + SPrint(Root, 99, L"%s=%s", TokenList[0], TokenList[1]); + } // if/elseif/elseif + if (Root[0] != L'\0') { + for (i = 0; i < StrLen(Root); i++) + if (Root[i] == '\\') + Root[i] = '/'; + SPrint(Line, 512, L"\"Boot with normal options\" \"ro root=%s\"\n", Root); + MergeStrings((CHAR16 **) &(Options->Buffer), Line, 0); + SPrint(Line, 512, L"\"Boot into single-user mode\" \"ro root=%s single\"\n", Root); + MergeStrings((CHAR16**) &(Options->Buffer), Line, 0); + Options->BufferSize = StrLen((CHAR16*) Options->Buffer) * sizeof(CHAR16); + } // if + } // if + FreeTokenLine(&TokenList, &TokenCount); + } // while + + Options->Current8Ptr = (CHAR8 *)Options->Buffer; + Options->End8Ptr = Options->Current8Ptr + Options->BufferSize; + Options->Current16Ptr = (CHAR16 *)Options->Buffer; + Options->End16Ptr = Options->Current16Ptr + (Options->BufferSize >> 1); + + MyFreePool(Fstab->Buffer); + MyFreePool(Fstab); + } // if/else file read error + } // if /etc/fstab exists + return Options; +} // GenerateOptionsFromEtcFstab() + + // Read a Linux kernel options file for a Linux boot loader into memory. The LoaderPath // and Volume variables identify the location of the options file, but not its name -- // you pass this function the filename of the Linux kernel, initial RAM disk, or other @@ -791,12 +850,15 @@ VOID ScanUserConfigured(CHAR16 *FileName) // kernel developers decided to use that name for a similar purpose, but with a // different file format. Thus, I'm migrating rEFInd to use the name refind_linux.conf, // but I want a migration period in which both names are used. +// If a rEFInd options file can't be found, try to generate minimal options from +// /etc/fstab on the same volume as the kernel. This typically works only if the +// kernel is being read from the Linux root filesystem. // // The return value is a pointer to the REFIT_FILE handle for the file, or NULL if // it wasn't found. REFIT_FILE * ReadLinuxOptionsFile(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume) { CHAR16 *OptionsFilename, *FullFilename; - BOOLEAN GoOn = TRUE; + BOOLEAN GoOn = TRUE, FileFound = FALSE; UINTN i = 0, size; REFIT_FILE *File = NULL; EFI_STATUS Status; @@ -809,17 +871,20 @@ REFIT_FILE * ReadLinuxOptionsFile(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume if (FileExists(Volume->RootDir, FullFilename)) { File = AllocateZeroPool(sizeof(REFIT_FILE)); Status = ReadFile(Volume->RootDir, FullFilename, File, &size); - GoOn = FALSE; if (CheckError(Status, L"while loading the Linux options file")) { if (File != NULL) FreePool(File); File = NULL; - GoOn = TRUE; - } // if error + } else { + GoOn = FALSE; + FileFound = TRUE; + } // if/else error } // if file exists } else { // a filename string is NULL GoOn = FALSE; } // if/else + if (!FileFound) + File = GenerateOptionsFromEtcFstab(Volume); MyFreePool(OptionsFilename); MyFreePool(FullFilename); OptionsFilename = FullFilename = NULL; diff --git a/refind/main.c b/refind/main.c index a11dea9..187e7c0 100644 --- a/refind/main.c +++ b/refind/main.c @@ -144,7 +144,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.11"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.11.2"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -718,7 +718,7 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume) { } // while MyFreePool(InitrdName); MyFreePool(File); - } // if Linux options file exists + } // if } else if (Entry->OSType == 'E') { // entries for ELILO SubEntry = InitializeLoaderEntry(Entry); @@ -2308,6 +2308,7 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) ScanVolumes(); ReadConfig(CONFIG_FILE_NAME); + PauseForKey(); InitScreen(); WarnIfLegacyProblems(); MainMenu.TimeoutSeconds = GlobalConfig.Timeout;