From: srs5694 Date: Fri, 3 Mar 2017 01:38:30 +0000 (-0500) Subject: Added support for "%v" as a variable for the kernel version number in X-Git-Url: https://code.delx.au/refind/commitdiff_plain/0864ac754bdb02cb63e8d2323a2ad6b081fdc612 Added support for "%v" as a variable for the kernel version number in refind_linux.conf. --- diff --git a/NEWS.txt b/NEWS.txt index 7e218c1..13f18d5 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,18 @@ 0.10.5 (??/??/2017): -------------------- +- Two improvements to initrd detection for Linux kernels: + - If multiple initrd files match the kernel's version number, the file + with more matching characters after the version number is used, rather + than the first initrd file found. + - The "%v" string, if present in the refind_linux.conf file's second + field, will be replaced by the kernel version number. Thus, you can + specify options like: + "Boot with standard initrd" "ro root=/dev/sda2 initrd=initrd-%v-std" + "Boot with debug initrd" "ro root=/dev/sda2 initrd=initrd-%v-debug" + This enables using multiple initrd files per kernel, to be used for + different purposes. + - Minor code optimization. - Add new key mappings: Backspace (Delete on Mac keyboards) works the same diff --git a/refind/global.h b/refind/global.h index efb16d0..0da3ff3 100644 --- a/refind/global.h +++ b/refind/global.h @@ -197,6 +197,9 @@ #define NULL_GUID_VALUE { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; #define REFIND_GUID_VALUE { 0x36D08FA7, 0xCF0B, 0x42F5, {0x8F, 0x14, 0x68, 0xDF, 0x73, 0xED, 0x37, 0x40} }; +// Configuration file variables +#define KERNEL_VERSION L"%v" + // // global definitions // diff --git a/refind/main.c b/refind/main.c index bdfa6ac..eeb7719 100644 --- a/refind/main.c +++ b/refind/main.c @@ -757,7 +757,7 @@ REFIT_MENU_SCREEN *InitializeSubScreen(IN LOADER_ENTRY *Entry) { VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume, IN BOOLEAN GenerateReturn) { REFIT_MENU_SCREEN *SubScreen; LOADER_ENTRY *SubEntry; - CHAR16 *InitrdName; + CHAR16 *InitrdName, *KernelVersion = NULL; CHAR16 DiagsFileName[256]; REFIT_FILE *File; UINTN TokenCount; @@ -855,6 +855,8 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume, IN BOOLEAN if (File != NULL) { InitrdName = FindInitrd(Entry->LoaderPath, Volume); TokenCount = ReadTokenLine(File, &TokenList); + KernelVersion = FindNumbers(Entry->LoaderPath); + ReplaceSubstring(&(TokenList[1]), KERNEL_VERSION, KernelVersion); // first entry requires special processing, since it was initially set // up with a default title but correct options by InitializeSubScreen(), // earlier.... @@ -864,6 +866,7 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume, IN BOOLEAN } // if FreeTokenLine(&TokenList, &TokenCount); while ((TokenCount = ReadTokenLine(File, &TokenList)) > 1) { + ReplaceSubstring(&(TokenList[1]), KERNEL_VERSION, KernelVersion); SubEntry = InitializeLoaderEntry(Entry); SubEntry->me.Title = TokenList[0] ? StrDuplicate(TokenList[0]) : StrDuplicate(L"Boot Linux"); MyFreePool(SubEntry->LoadOptions); @@ -943,20 +946,24 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume, IN BOOLEAN if (GenerateReturn) AddMenuEntry(SubScreen, &MenuEntryReturn); Entry->me.SubScreen = SubScreen; + MyFreePool(KernelVersion); } // VOID GenerateSubScreen() // Returns options for a Linux kernel. Reads them from an options file in the // kernel's directory; and if present, adds an initrd= option for an initial // RAM disk file with the same version number as the kernel file. static CHAR16 * GetMainLinuxOptions(IN CHAR16 * LoaderPath, IN REFIT_VOLUME *Volume) { - CHAR16 *Options = NULL, *InitrdName, *FullOptions = NULL; + CHAR16 *Options = NULL, *InitrdName, *FullOptions = NULL, *KernelVersion; Options = GetFirstOptionsFromFile(LoaderPath, Volume); InitrdName = FindInitrd(LoaderPath, Volume); + KernelVersion = FindNumbers(InitrdName); + ReplaceSubstring(&Options, KERNEL_VERSION, KernelVersion); FullOptions = AddInitrdToOptions(Options, InitrdName); MyFreePool(Options); MyFreePool(InitrdName); + MyFreePool(KernelVersion); return (FullOptions); } // static CHAR16 * GetMainLinuxOptions() @@ -1143,16 +1150,19 @@ static LOADER_ENTRY * AddLoaderEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTit // Add a Linux kernel as a submenu entry for another (pre-existing) Linux kernel entry. static VOID AddKernelToSubmenu(LOADER_ENTRY * TargetLoader, CHAR16 *FileName, REFIT_VOLUME *Volume) { REFIT_FILE *File; - CHAR16 **TokenList = NULL, *InitrdName, *SubmenuName = NULL, *VolName = NULL, *Path = NULL, *Title; + CHAR16 **TokenList = NULL, *InitrdName, *SubmenuName = NULL, *VolName = NULL; + CHAR16 *Path = NULL, *Title, *KernelVersion; REFIT_MENU_SCREEN *SubScreen; LOADER_ENTRY *SubEntry; UINTN TokenCount; + KernelVersion = FindNumbers(FileName); File = ReadLinuxOptionsFile(TargetLoader->LoaderPath, Volume); if (File != NULL) { SubScreen = TargetLoader->me.SubScreen; InitrdName = FindInitrd(FileName, Volume); while ((TokenCount = ReadTokenLine(File, &TokenList)) > 1) { + ReplaceSubstring(&(TokenList[1]), KERNEL_VERSION, KernelVersion); SubEntry = InitializeLoaderEntry(TargetLoader); SplitPathName(FileName, &VolName, &Path, &SubmenuName); MergeStrings(&SubmenuName, L": ", '\0'); @@ -1176,6 +1186,7 @@ static VOID AddKernelToSubmenu(LOADER_ENTRY * TargetLoader, CHAR16 *FileName, RE MyFreePool(InitrdName); MyFreePool(File); } // if + MyFreePool(KernelVersion); } // static VOID AddKernelToSubmenu() // Returns -1 if (Time1 < Time2), +1 if (Time1 > Time2), or 0 if diff --git a/refind/mystrings.c b/refind/mystrings.c index 75e2d89..ca7a6a1 100644 --- a/refind/mystrings.c +++ b/refind/mystrings.c @@ -348,6 +348,29 @@ BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List) { return Found; } // BOOLEAN IsSubstringIn() +// Replace *SearchString in **MainString with *ReplString. +// Returns TRUE if replacement was done, FALSE otherwise. +BOOLEAN ReplaceSubstring(IN OUT CHAR16 **MainString, IN CHAR16 *SearchString, IN CHAR16 *ReplString) { + BOOLEAN WasReplaced = FALSE; + CHAR16 *FoundSearchString, *NewString, *EndString; + + FoundSearchString = MyStrStr(*MainString, SearchString); + if (FoundSearchString) { + NewString = AllocateZeroPool(sizeof(CHAR16) * StrLen(*MainString)); + if (NewString) { + EndString = &(FoundSearchString[StrLen(SearchString)]); + FoundSearchString[0] = L'\0'; + StrCpy(NewString, *MainString); + MergeStrings(&NewString, ReplString, L'\0'); + MergeStrings(&NewString, EndString, L'\0'); + MyFreePool(MainString); + *MainString = NewString; + WasReplaced = TRUE; + } // if + } // if + return WasReplaced; +} // BOOLEAN ReplaceSubstring() + // Returns TRUE if *Input contains nothing but valid hexadecimal characters, // FALSE otherwise. Note that a leading "0x" is NOT acceptable in the input! BOOLEAN IsValidHex(CHAR16 *Input) { diff --git a/refind/mystrings.h b/refind/mystrings.h index b79a4b7..d2ff7d7 100644 --- a/refind/mystrings.h +++ b/refind/mystrings.h @@ -51,6 +51,7 @@ UINTN NumCharsInCommon(IN CHAR16* String1, IN CHAR16* String2); CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index); BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List); BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List); +BOOLEAN ReplaceSubstring(IN OUT CHAR16 **MainString, IN CHAR16 *SearchString, IN CHAR16 *ReplString); BOOLEAN IsValidHex(CHAR16 *Input); UINT64 StrToHex(CHAR16 *Input, UINTN Position, UINTN NumChars);