mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
361 lines
8.3 KiB
C
361 lines
8.3 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
|
|
|
|
#if !defined(OC_TRACE_GRUB_VARS)
|
|
#define OC_TRACE_GRUB_VARS DEBUG_VERBOSE
|
|
#endif
|
|
|
|
#if !defined(OC_TRACE_KERNEL_OPTS)
|
|
#define OC_TRACE_KERNEL_OPTS DEBUG_VERBOSE
|
|
#endif
|
|
|
|
#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 sepcified per
|
|
FS by using argument partuuidopts:{partuuid}+=ro instead.
|
|
*/
|
|
#define LINUX_BOOT_ADD_RO BIT10
|
|
/*
|
|
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
|
|
|
|
#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_DEBUG_INFO \
|
|
)
|
|
|
|
/*
|
|
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;
|
|
|
|
/*
|
|
Stored parsed load options.
|
|
Would be freed at driver unload, if that happened.
|
|
*/
|
|
extern OC_FLEX_ARRAY *gParsedLoadOptions;
|
|
|
|
/*
|
|
The array of loader entries, either really from *.conf files or generated by autodetect.
|
|
*/
|
|
extern OC_FLEX_ARRAY *gNamedLoaderEntries;
|
|
|
|
/*
|
|
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;
|
|
|
|
/*
|
|
Forward declaration of NAMED_LOADER_ENTRY structure.
|
|
*/
|
|
typedef struct NAMED_LOADER_ENTRY_ NAMED_LOADER_ENTRY;
|
|
|
|
/*
|
|
Forward declaration of VMLINUZ_FILE structure.
|
|
*/
|
|
typedef struct VMLINUZ_FILE_ VMLINUZ_FILE;
|
|
|
|
/*
|
|
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.
|
|
*/
|
|
|
|
NAMED_LOADER_ENTRY *
|
|
InternalCreateNamedLoaderEntry (
|
|
IN LOADER_ENTRY *Entry,
|
|
IN CHAR16 *FileName
|
|
);
|
|
|
|
VOID
|
|
InternalFreePickerEntry (
|
|
IN OC_PICKER_ENTRY *Entry
|
|
);
|
|
|
|
VOID
|
|
InternalFreeNamedLoaderEntry (
|
|
NAMED_LOADER_ENTRY *Entry
|
|
);
|
|
|
|
EFI_STATUS
|
|
InternalConvertNamedLoaderEntriesToBootEntries (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
EFI_STATUS
|
|
ScanLoaderEntries (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
/*
|
|
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_ {
|
|
//
|
|
// First(blscfg)/last(sd-boot) title line encountered.
|
|
// Otherwise attempted autodetect "{Variant}" (e.g. "Ubuntu", "Fedora") from within kernel image.
|
|
// Otherwise "Linux".
|
|
//
|
|
CHAR8 *Title;
|
|
//
|
|
// First(blscfg)/last(sd-boot) version line encountered;
|
|
// Otherwise version-id from {machine-id}-{kernel-version}.conf or vmlinuz-{kernel-version} filename.
|
|
// Otherwise attempted autodetect from within kernel image.
|
|
//
|
|
CHAR8 *Version;
|
|
//
|
|
// First(blscfg)/last(sd-boot) linux line encountered.
|
|
// Required.
|
|
//
|
|
CHAR8 *Linux;
|
|
//
|
|
// Option lines encountered.
|
|
// In pure BLSpec (and in sd-boot) all are used; in blscfg only the first option line is used, so we match that.
|
|
// TODO: Test starting something (not really a Linux kernel?) with no options and no initrds.
|
|
//
|
|
OC_FLEX_ARRAY *Options;
|
|
//
|
|
// Initrd lines encountered.
|
|
// (All are used in both blscfg and sd-boot.)
|
|
//
|
|
OC_FLEX_ARRAY *Initrds;
|
|
//
|
|
// id line is not read from .conf file even if present.
|
|
// OcId is generated from .conf filename, to share machine-id between
|
|
// {machine-id}-{kernel-version}.conf files, in order to auto-boot the
|
|
// most recent kernel when a new one appears.
|
|
//
|
|
CHAR8 *OcId;
|
|
//
|
|
// Autodetect from within kernel image ("{Variant}:Linux").
|
|
// Otherwise just "Linux".
|
|
//
|
|
CHAR8 *OcFlavour;
|
|
//
|
|
// Is this an auxiliary entry for OpenCore?
|
|
//
|
|
BOOLEAN OcAuxiliary;
|
|
};
|
|
|
|
//
|
|
// Values for NAMED_LOADER_ENTRY DuplicateFlags.
|
|
// We previously implemented pure-Boot Loader Spec-style title disambiguation
|
|
// only when there is more than one entry with the same name, however
|
|
// within OC it works better to always disambiguate when
|
|
// HideAuxiliary is FALSE and never otherwise.
|
|
//
|
|
#define DUPLICATE_ID_SCANNED BIT0
|
|
|
|
/*
|
|
Loader entry associated with filename, for sorting.
|
|
*/
|
|
struct NAMED_LOADER_ENTRY_ {
|
|
CHAR16 *FileName;
|
|
LOADER_ENTRY *Entry;
|
|
UINTN DuplicateFlags;
|
|
};
|
|
|
|
struct VMLINUZ_FILE_ {
|
|
CHAR16 *FileName;
|
|
CHAR16 *Version;
|
|
UINTN StrLen;
|
|
};
|
|
|
|
/*
|
|
Autodetect.
|
|
*/
|
|
EFI_STATUS
|
|
AutodetectLinux (
|
|
IN EFI_FILE_PROTOCOL *RootDirectory,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
);
|
|
|
|
#endif // LINUX_BOOT_INTERNAL_H
|