mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
In GRUB2+blscfg mode: - Allow grub vars in 'initrd' as well as in 'options' - Allow multiple initrd files on one 'initrd' line - Initialise empty $tuned_params and $tuned_initrd grub vars if no values present, on an optional flag enabled by default (since we want to make booting major distros easy) In GRUB2+blscfg mode (seem to be allowed now, not required for fix): - Allow multiple 'initrd' lines - Allow multiple 'options' lines Add variant of OcParseVars which can parse as value-only tokens. Signed-off-by: Mike Beaton <mjsbeaton@gmail.com>
405 lines
8.0 KiB
C
405 lines
8.0 KiB
C
/** @file
|
|
Copyright (C) 2021, Mike Beaton. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-3-Clause
|
|
**/
|
|
|
|
#ifndef LINUX_BOOT_INTERNAL_H
|
|
#define LINUX_BOOT_INTERNAL_H
|
|
|
|
/*
|
|
Standard attached drives on OVMF appear as MBR, so it can be convenient when
|
|
debugging to allow entries with incorrect (i.e. specifies no/every drive)
|
|
root=... .
|
|
*/
|
|
// #define LINUX_ALLOW_MBR
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/OcBootManagementLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
|
|
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
|
|
#define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
|
|
|
|
/*
|
|
Allow scan of ESP.
|
|
*/
|
|
#define LINUX_BOOT_SCAN_ESP BIT0
|
|
|
|
/*
|
|
Allow scan of XBOOTLDR.
|
|
*/
|
|
#define LINUX_BOOT_SCAN_XBOOTLDR BIT1
|
|
|
|
/*
|
|
Allow scan of Linux Root filesystems.
|
|
*/
|
|
#define LINUX_BOOT_SCAN_LINUX_ROOT BIT2
|
|
|
|
/*
|
|
Allow scan of Linux Data filesystems.
|
|
*/
|
|
#define LINUX_BOOT_SCAN_LINUX_DATA BIT3
|
|
|
|
/*
|
|
Some space for additional file systems.
|
|
*/
|
|
/*
|
|
Allow scan of any filesystem not explicitly mentioned
|
|
(including but not limited FAT other than ESP, and NTFS).
|
|
*/
|
|
#define LINUX_BOOT_SCAN_OTHER BIT7
|
|
|
|
/*
|
|
Allow autodetect of vmlinuz-{version} and matching init*-{version},
|
|
if scan for usable /loader/entries fails.
|
|
*/
|
|
#define LINUX_BOOT_ALLOW_AUTODETECT BIT8
|
|
|
|
/*
|
|
Define entry id by the first part (to dash) of the filename
|
|
from which it was created. Results in the first matching entry (after sorting)
|
|
always being the default entry, which results in updated Linux becoming the
|
|
new default automatically.
|
|
*/
|
|
#define LINUX_BOOT_USE_LATEST BIT9
|
|
|
|
/*
|
|
If set, add "ro" as initial option to all distros. Can be specified per
|
|
FS by using argument autoopts:{partuuid}+=ro instead.
|
|
*/
|
|
#define LINUX_BOOT_ADD_RO BIT10
|
|
|
|
/*
|
|
If set, add "rw" as initial option to all distros. Can be specified per
|
|
FS by using argument autoopts:{partuuid}+=rw instead.
|
|
*/
|
|
#define LINUX_BOOT_ADD_RW BIT11
|
|
|
|
/*
|
|
TODO: (?) Both blspec-style and autodetect can make use of grub.cfg info if this flag is set.
|
|
These are currently parsed when needed for GRUB2+blscfg, i.e. if we find /loader/entries and /grub2/grub.cfg.
|
|
*/
|
|
// #define LINUX_BOOT_ALLOW_PARSE_GRUB BIT12
|
|
|
|
/*
|
|
Add root= option if missing in loader/entries *.conf options.
|
|
*/
|
|
#define LINUX_BOOT_ALLOW_CONF_AUTO_ROOT BIT13
|
|
|
|
/*
|
|
Add some additional log info.
|
|
*/
|
|
#define LINUX_BOOT_LOG_VERBOSE BIT14
|
|
|
|
/*
|
|
Prepend filesystem type and first 8 hex digits of PARTUUID to discovered
|
|
entry titles, to help in debugging where entries came from.
|
|
*/
|
|
#define LINUX_BOOT_ADD_DEBUG_INFO BIT15
|
|
|
|
/*
|
|
Trace grub var processing.
|
|
*/
|
|
#define LINUX_BOOT_LOG_GRUB_VARS BIT16
|
|
|
|
/*
|
|
Fix TuneD processing by initialising its grub variables if they are not present.
|
|
*/
|
|
#define LINUX_BOOT_FIX_TUNED BIT17
|
|
|
|
#define LINUX_BOOT_ALL ( \
|
|
LINUX_BOOT_SCAN_ESP | \
|
|
LINUX_BOOT_SCAN_XBOOTLDR | \
|
|
LINUX_BOOT_SCAN_LINUX_ROOT | \
|
|
LINUX_BOOT_SCAN_LINUX_DATA | \
|
|
LINUX_BOOT_SCAN_OTHER | \
|
|
LINUX_BOOT_ALLOW_AUTODETECT | \
|
|
LINUX_BOOT_USE_LATEST | \
|
|
LINUX_BOOT_ADD_RO | \
|
|
LINUX_BOOT_ADD_RW | \
|
|
LINUX_BOOT_ALLOW_CONF_AUTO_ROOT | \
|
|
LINUX_BOOT_LOG_VERBOSE | \
|
|
LINUX_BOOT_ADD_DEBUG_INFO | \
|
|
LINUX_BOOT_LOG_GRUB_VARS | \
|
|
LINUX_BOOT_FIX_TUNED \
|
|
)
|
|
|
|
/*
|
|
GRUB var error codes.
|
|
*/
|
|
#define VAR_ERR_NONE (0)
|
|
#define VAR_ERR_INDENTED BIT0 // Naive detection of GRUB conditional logic
|
|
#define VAR_ERR_HAS_VARS BIT1 // We do not support nested vars (in name or value), even though GRUB does
|
|
|
|
/*
|
|
Global flags for this instance of OpenLinuxBoot.efi.
|
|
*/
|
|
extern UINTN gLinuxBootFlags;
|
|
|
|
/*
|
|
Boot picker context.
|
|
*/
|
|
extern OC_PICKER_CONTEXT *gPickerContext;
|
|
|
|
/*
|
|
The array of loader entries, either really from *.conf files or generated by autodetect.
|
|
*/
|
|
extern OC_FLEX_ARRAY *gLoaderEntries;
|
|
|
|
/*
|
|
The current partuuid.
|
|
*/
|
|
extern EFI_GUID gPartuuid;
|
|
|
|
/*
|
|
Human readable ascii name of current file system type.
|
|
*/
|
|
extern CHAR8 *gFileSystemType;
|
|
|
|
// TODO: Are all of the below types used outside a single file?
|
|
// TODO: Is this file sensibly ordered?
|
|
|
|
/*
|
|
Forward declaration of GRUB_VAR structure.
|
|
*/
|
|
typedef struct GRUB_VAR_ GRUB_VAR;
|
|
|
|
/*
|
|
Forward declaration of LOADER_ENTRY structure.
|
|
*/
|
|
typedef struct LOADER_ENTRY_ LOADER_ENTRY;
|
|
|
|
/*
|
|
GRUB vars.
|
|
*/
|
|
EFI_STATUS
|
|
InternalInitGrubVars (
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
InternalFreeGrubVars (
|
|
VOID
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalSetGrubVar (
|
|
CHAR8 *Key,
|
|
CHAR8 *Value,
|
|
UINTN Errors
|
|
);
|
|
|
|
BOOLEAN
|
|
InternalHasGrubVars (
|
|
CHAR8 *Options
|
|
);
|
|
|
|
GRUB_VAR *
|
|
InternalGetGrubVar (
|
|
IN CONST CHAR8 *Key
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalExpandGrubVarsForArray (
|
|
IN OUT OC_FLEX_ARRAY *Options
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalExpandGrubVars (
|
|
IN CONST CHAR8 *Options,
|
|
IN OUT CHAR8 **Result
|
|
);
|
|
|
|
/*
|
|
Process grubenv file.
|
|
*/
|
|
EFI_STATUS
|
|
InternalProcessGrubEnv (
|
|
IN OUT CHAR8 *Content,
|
|
IN CONST UINTN Length
|
|
);
|
|
|
|
/*
|
|
Process grub.cfg file.
|
|
*/
|
|
EFI_STATUS
|
|
InternalProcessGrubCfg (
|
|
IN OUT CHAR8 *Content
|
|
);
|
|
|
|
LOADER_ENTRY *
|
|
InternalAllocateLoaderEntry (
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
InternalFreeLoaderEntry (
|
|
LOADER_ENTRY *Entry
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalProcessLoaderEntryFile (
|
|
IN CONST CHAR16 *FileName,
|
|
IN OUT CHAR8 *Content,
|
|
OUT LOADER_ENTRY *Entry,
|
|
IN CONST BOOLEAN Grub2
|
|
);
|
|
|
|
/*
|
|
GRUB variable.
|
|
*/
|
|
struct GRUB_VAR_ {
|
|
//
|
|
// Points within loaded file memory.
|
|
//
|
|
CHAR8 *Key;
|
|
//
|
|
// Points within loaded file memory, may be empty string.
|
|
//
|
|
CHAR8 *Value;
|
|
//
|
|
// GRUB var error code flags.
|
|
//
|
|
UINTN Errors;
|
|
};
|
|
|
|
/*
|
|
Loader entries.
|
|
*/
|
|
|
|
VOID
|
|
InternalFreePickerEntry (
|
|
IN OC_PICKER_ENTRY *Entry
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalConvertLoaderEntriesToBootEntries (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalScanLoaderEntries (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalIdVersionFromFileName (
|
|
IN OUT LOADER_ENTRY *Entry,
|
|
IN CHAR16 *FileName
|
|
);
|
|
|
|
/*
|
|
BLSpec / blscfg loader entry.
|
|
Some items within here probably don't need to be allocated and could stay
|
|
pointing within the source file as long as that is in memory (specifically
|
|
Version and Linux, which are probably never going to be modified), but to
|
|
keep things sane everything is (re)allocated.
|
|
*/
|
|
struct LOADER_ENTRY_ {
|
|
//
|
|
// Version.
|
|
// Must come first since used for sorting.
|
|
//
|
|
CHAR8 *Version;
|
|
//
|
|
// Title.
|
|
//
|
|
CHAR8 *Title;
|
|
//
|
|
// Linux kernel filename.
|
|
//
|
|
CHAR8 *Linux;
|
|
//
|
|
// Options.
|
|
//
|
|
OC_FLEX_ARRAY *Options;
|
|
//
|
|
// Initrds.
|
|
//
|
|
OC_FLEX_ARRAY *Initrds;
|
|
//
|
|
// OpenCore entry id.
|
|
// 'id' line is not read from .conf files even if present.
|
|
//
|
|
CHAR8 *OcId;
|
|
//
|
|
// Flavour.
|
|
//
|
|
CHAR8 *OcFlavour;
|
|
//
|
|
// Is this an auxiliary entry for OpenCore?
|
|
//
|
|
BOOLEAN OcAuxiliary;
|
|
//
|
|
// Has this already been scanned whilst assigned main and auxiliary entries?
|
|
//
|
|
BOOLEAN DuplicateIdScanned;
|
|
};
|
|
|
|
typedef struct VMLINUZ_FILE_ {
|
|
CHAR16 *FileName;
|
|
CHAR16 *Version;
|
|
UINTN StrLen;
|
|
} VMLINUZ_FILE;
|
|
|
|
/*
|
|
Autodetect options.
|
|
*/
|
|
typedef struct AUTOOPTS_ {
|
|
EFI_GUID Guid;
|
|
CHAR16 *Opts;
|
|
BOOLEAN PlusOpts;
|
|
} AUTOOPTS;
|
|
|
|
/*
|
|
Load autoopts.
|
|
*/
|
|
EFI_STATUS
|
|
InternalPreloadAutoOpts (
|
|
IN OC_FLEX_ARRAY *Options
|
|
);
|
|
|
|
/*
|
|
Autodetect.
|
|
*/
|
|
EFI_STATUS
|
|
InternalAutodetectLinux (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
/*
|
|
Insert root=PARTUUID=... option.
|
|
*/
|
|
EFI_STATUS
|
|
InsertRootOption (
|
|
IN OC_FLEX_ARRAY *Options
|
|
);
|
|
|
|
/*
|
|
Sorts versions low to high.
|
|
*/
|
|
INTN
|
|
EFIAPI
|
|
InternalVersionCompare (
|
|
IN CONST VOID *Version1,
|
|
IN CONST VOID *Version2
|
|
);
|
|
|
|
/*
|
|
Sorts versions high to low.
|
|
*/
|
|
INTN
|
|
EFIAPI
|
|
InternalReverseVersionCompare (
|
|
IN CONST VOID *Version1,
|
|
IN CONST VOID *Version2
|
|
);
|
|
|
|
#endif // LINUX_BOOT_INTERNAL_H
|