mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
This quirk is needed to boot macOS 10.6 (and probably older) with 32-bit kernel in 32-bit OVMF. Similar to 64-bit mode, hibernation wake is not compatible with this quirk. This change also partially fixes compatibility with a few other quirks (e.g. AvoidRuntimeDefrag), but they are not really tested.
794 lines
23 KiB
C
794 lines
23 KiB
C
/** @file
|
|
Copyright (C) 2019, vit9696. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#ifndef BOOT_COMPAT_INTERNAL_H
|
|
#define BOOT_COMPAT_INTERNAL_H
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <IndustryStandard/AppleBootArgs.h>
|
|
#include <IndustryStandard/AppleEfiBootRtInfo.h>
|
|
|
|
#include <Library/OcAfterBootCompatLib.h>
|
|
#include <Library/OcBootManagementLib.h>
|
|
#include <Library/OcDebugLogLib.h>
|
|
#include <Library/OcMemoryLib.h>
|
|
|
|
#include <Protocol/LoadedImage.h>
|
|
#include <Protocol/OcFirmwareRuntime.h>
|
|
|
|
//
|
|
// The kernel is normally allocated at base 0x100000 + slide address.
|
|
//
|
|
// For slide=0x1~0x7F the kernel is allocated from
|
|
// 0x100000 + 0x200000 till 0x100000 + 0xFE00000.
|
|
//
|
|
// For slide = 0x80~0xFF on Sandy Bridge or Ivy Bridge CPUs from
|
|
// 0x100000 + 0x20200000 till 0x100000? + 0x30000000??.
|
|
//
|
|
// For slide = 0x80~0xFF on Other CPUs from
|
|
// 0x100000 + 0x10000000 till 0x100000 + 0x1FE00000.
|
|
//
|
|
|
|
/**
|
|
Maximum number of supported runtime reloc protection areas.
|
|
Currently hardocded for simplicity.
|
|
**/
|
|
#define RT_RELOC_PROTECT_MAX_NUM ((UINTN) 64)
|
|
|
|
/**
|
|
Runtime descriptor number to virtualise.
|
|
Currently hardocded for simplicity.
|
|
**/
|
|
#define RT_DESC_ENTRY_NUM ((UINTN) 64)
|
|
|
|
/**
|
|
Kernel static vaddr mapping base.
|
|
**/
|
|
#define KERNEL_STATIC_VADDR ((UINT64) 0xFFFFFF8000000000ULL)
|
|
|
|
/**
|
|
Kernel __HIB segment virtual address.
|
|
**/
|
|
#define KERNEL_HIB_VADDR ((UINTN) (0xFFFFFF8000100000ULL & MAX_UINTN))
|
|
|
|
/**
|
|
Kernel __TEXT segment virtual address (macOS 10.6 and higher).
|
|
**/
|
|
#define KERNEL_TEXT_VADDR ((UINTN) (0xFFFFFF8000200000ULL & MAX_UINTN))
|
|
|
|
/**
|
|
Kernel __TEXT segment virtual address (macOS 10.4 and 10.5).
|
|
**/
|
|
#define KERNEL_TEXT_VADDR_LEGACY 0x111000
|
|
|
|
/**
|
|
Kernel physical base address.
|
|
**/
|
|
#define KERNEL_BASE_PADDR ((UINT32) (KERNEL_HIB_VADDR & MAX_UINT32))
|
|
|
|
/**
|
|
Kernel __TEXT physical base address (macOS 10.6 and higher).
|
|
**/
|
|
#define KERNEL_TEXT_PADDR ((UINT32) (KERNEL_TEXT_VADDR & MAX_UINT32))
|
|
|
|
/**
|
|
Kernel __TEXT physical base address (macOS 10.4 and 10.5).
|
|
**/
|
|
#define KERNEL_TEXT_PADDR_LEGACY (KERNEL_TEXT_VADDR_LEGACY)
|
|
|
|
/**
|
|
Slide offset per slide entry
|
|
**/
|
|
#define SLIDE_GRANULARITY ((UINTN) SIZE_2MB)
|
|
|
|
/**
|
|
Total possible number of KASLR slide offsets.
|
|
**/
|
|
#define TOTAL_SLIDE_NUM ((UINTN) 0x100)
|
|
|
|
/**
|
|
Slide errate number to skip range from.
|
|
**/
|
|
#define SLIDE_ERRATA_NUM ((UINTN) 0x80)
|
|
|
|
/**
|
|
Sandy/Ivy skip slide range for Intel HD graphics.
|
|
**/
|
|
#define SLIDE_ERRATA_SKIP_RANGE ((UINTN) 0x10200000)
|
|
|
|
/**
|
|
Assume the kernel is roughly 128 MBs.
|
|
And the recovery introduced with Big Sur has roughly 200 MBs.
|
|
See 11.0b10 EB.MM.AKMR function (EfiBoot.MemoryMap.AllocateKernelMemoryRecovery),
|
|
it has 0xC119 pages requested. This value is likely calculated from KC size.
|
|
**/
|
|
#define ESTIMATED_KERNEL_SIZE ((UINTN) (200 * SIZE_1MB))
|
|
|
|
/**
|
|
Assume call gate (normally a little over 100 bytes) can be up to 256 bytes.
|
|
It is allocated in its own page and is relocatable.
|
|
|
|
WARNING: Keep this in sync with RelocationCallGate assembly!
|
|
**/
|
|
#define ESTIMATED_CALL_GATE_SIZE 256
|
|
|
|
/**
|
|
Size of jump from call gate inserted before Call Gate to jump to our code.
|
|
**/
|
|
#define CALL_GATE_JUMP_SIZE (sizeof (CALL_GATE_JUMP))
|
|
|
|
/*
|
|
Minimum size of the patched call gate.
|
|
*/
|
|
#define CALL_GATE_MIN_SIZE (ESTIMATED_CALL_GATE_SIZE + CALL_GATE_JUMP_SIZE)
|
|
|
|
/**
|
|
Command used to perform an absolute 64-bit jump from Call Gate to our code.
|
|
**/
|
|
#pragma pack(push,1)
|
|
typedef struct CALL_GATE_JUMP_ {
|
|
struct {
|
|
UINT8 Command[3];
|
|
UINT32 Argument;
|
|
} LeaRip;
|
|
struct {
|
|
UINT16 Command;
|
|
UINT32 Argument;
|
|
UINT64 Address;
|
|
} Jmp;
|
|
} CALL_GATE_JUMP;
|
|
STATIC_ASSERT (sizeof (CALL_GATE_JUMP) == 7 + 14, "Invalid CALL_GATE_JUMP size");
|
|
#pragma pack(pop)
|
|
|
|
/**
|
|
Kernel call gate prototype.
|
|
**/
|
|
typedef
|
|
UINTN
|
|
(EFIAPI *KERNEL_CALL_GATE)(
|
|
IN UINTN Arg1,
|
|
IN UINTN Arg2
|
|
);
|
|
|
|
/**
|
|
Relocation call gate prototype.
|
|
**/
|
|
typedef
|
|
UINTN
|
|
(EFIAPI *RELOCATION_CALL_GATE)(
|
|
IN UINTN QWordCount,
|
|
IN UINTN EntryPoint,
|
|
IN EFI_PHYSICAL_ADDRESS Source,
|
|
IN UINTN Args
|
|
);
|
|
|
|
/**
|
|
Preserved relocation entry.
|
|
**/
|
|
typedef struct RT_RELOC_PROTECT_INFO_ {
|
|
///
|
|
/// Physical address of descriptor start.
|
|
///
|
|
EFI_PHYSICAL_ADDRESS PhysicalStart;
|
|
///
|
|
/// Physical address of descriptor end.
|
|
///
|
|
EFI_PHYSICAL_ADDRESS PhysicalEnd;
|
|
///
|
|
/// Descriptor original memory type.
|
|
///
|
|
EFI_MEMORY_TYPE Type;
|
|
} RT_RELOC_PROTECT_INFO;
|
|
|
|
/**
|
|
Preserved relocation entry list.
|
|
**/
|
|
typedef struct RT_RELOC_PROTECT_DATA_ {
|
|
///
|
|
/// Number of currently used methods in the table.
|
|
///
|
|
UINTN NumEntries;
|
|
///
|
|
/// Reloc entries fitted.
|
|
///
|
|
RT_RELOC_PROTECT_INFO RelocInfo[RT_RELOC_PROTECT_MAX_NUM];
|
|
} RT_RELOC_PROTECT_DATA;
|
|
|
|
/**
|
|
UEFI Boot & Runtime Services original pointers.
|
|
**/
|
|
typedef struct UEFI_SERVICES_POINTERS_ {
|
|
///
|
|
/// Original page allocator. We override it to obtain
|
|
/// the location macOS kernel and hibernation images.
|
|
///
|
|
EFI_ALLOCATE_PAGES AllocatePages;
|
|
///
|
|
/// Original page deallocator. We override it to fix memory
|
|
/// attributes table as it is updated after page dealloc.
|
|
///
|
|
EFI_FREE_PAGES FreePages;
|
|
///
|
|
/// Original memory map function. We override it to make
|
|
/// memory map shrinking and CSM region protection.
|
|
///
|
|
EFI_GET_MEMORY_MAP GetMemoryMap;
|
|
///
|
|
/// Original pool allocator. We override it to fix memory
|
|
/// attributes table as it is updated after pool alloc.
|
|
///
|
|
EFI_ALLOCATE_POOL AllocatePool;
|
|
///
|
|
/// Original pool deallocator. We override it to fix memory
|
|
/// attributes table as it is updated after pool dealloc.
|
|
///
|
|
EFI_FREE_POOL FreePool;
|
|
///
|
|
/// Original exit boot services function. We override it
|
|
/// to ensure we always succeed exiting boot services.
|
|
///
|
|
EFI_EXIT_BOOT_SERVICES ExitBootServices;
|
|
///
|
|
/// Image loading routine. We override it to catch bootrt.efi
|
|
/// loading and enable the kernel call gate hook.
|
|
///
|
|
EFI_IMAGE_LOAD LoadImage;
|
|
///
|
|
/// Image starting routine. We override it to catch boot.efi
|
|
/// loading and enable the rest of functions.
|
|
///
|
|
EFI_IMAGE_START StartImage;
|
|
///
|
|
/// Original get variable function. We override it to alter
|
|
/// boot.efi boot arguments for custom KASLR slide.
|
|
///
|
|
EFI_GET_VARIABLE GetVariable;
|
|
} UEFI_SERVICES_POINTERS;
|
|
|
|
/**
|
|
UEFI services override internal state.
|
|
**/
|
|
typedef struct SERVICES_OVERRIDE_STATE_ {
|
|
///
|
|
/// GetVariable arrival event.
|
|
///
|
|
EFI_EVENT GetVariableEvent;
|
|
///
|
|
/// Firmware runtime protocol instance.
|
|
///
|
|
OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime;
|
|
///
|
|
/// Kernel call gate is an assembly function that takes boot arguments (rcx)
|
|
/// and kernel entry point (rdx) and jumps to the kernel (pstart) in 32-bit mode.
|
|
///
|
|
/// It is only used for normal booting, so for general interception we do not
|
|
/// use call gate but rather patch the kernel entry point. However, when it comes
|
|
/// to booting with relocation block (it does not support hibernation) we need
|
|
/// to update kernel entry point with the relocation block offset and that can
|
|
/// only be done in the call gate as it will otherwise jump to lower memory.
|
|
///
|
|
/// This stores only the old-style kernel call gate before macOS 13 Developer
|
|
/// Beta 1. The new-style call gate is handled separately.
|
|
///
|
|
EFI_PHYSICAL_ADDRESS OldKernelCallGate;
|
|
///
|
|
/// Last descriptor size obtained from GetMemoryMap.
|
|
///
|
|
UINTN MemoryMapDescriptorSize;
|
|
///
|
|
/// Amount of nested boot.efi detected.
|
|
///
|
|
UINTN AppleBootNestedCount;
|
|
///
|
|
/// The loaded image structure of the last started Apple booter.
|
|
///
|
|
EFI_LOADED_IMAGE_PROTOCOL *LastAppleBootImage;
|
|
///
|
|
/// TRUE if we are doing boot.efi hibernate wake.
|
|
///
|
|
BOOLEAN AppleHibernateWake;
|
|
///
|
|
/// TRUE if we are using custom KASLR slide (via boot arg).
|
|
///
|
|
BOOLEAN AppleCustomSlide;
|
|
///
|
|
/// TRUE if we are done reporting MMIO cleanup.
|
|
///
|
|
BOOLEAN ReportedMmio;
|
|
///
|
|
/// TRUE if we are waiting for performance memory allocation.
|
|
///
|
|
BOOLEAN AwaitingPerfAlloc;
|
|
} SERVICES_OVERRIDE_STATE;
|
|
|
|
/**
|
|
Apple kernel support internal state..
|
|
**/
|
|
typedef struct KERNEL_SUPPORT_STATE_ {
|
|
///
|
|
/// Custom kernel UEFI System Table.
|
|
///
|
|
EFI_PHYSICAL_ADDRESS SysTableRtArea;
|
|
///
|
|
/// Custom kernel UEFI System Table size in bytes.
|
|
///
|
|
UINTN SysTableRtAreaSize;
|
|
///
|
|
/// Physical configuration table location.
|
|
///
|
|
EFI_CONFIGURATION_TABLE *ConfigurationTable;
|
|
///
|
|
/// Virtual memory mapper context.
|
|
///
|
|
OC_VMEM_CONTEXT VmContext;
|
|
///
|
|
/// Virtual memory map containing partial memory map with runtime areas only.
|
|
/// Actual number of entries may be less than RT_DESC_ENTRY_NUM due to DescriptorSize
|
|
/// being potentially bigger than sizeof (EFI_MEMORY_DESCRIPTOR).
|
|
///
|
|
EFI_MEMORY_DESCRIPTOR VmMap[RT_DESC_ENTRY_NUM];
|
|
///
|
|
/// Virtual memory map size in bytes.
|
|
///
|
|
UINTN VmMapSize;
|
|
///
|
|
/// Virtual memory map descriptor size in bytes.
|
|
///
|
|
UINTN VmMapDescSize;
|
|
///
|
|
/// Relocation block is a scratch buffer allocated in lower 4GB to be used for
|
|
/// loading the kernel and related structures by EfiBoot on firmware where the
|
|
/// lower memory region is otherwise occupied by (assumed) non-runtime data.
|
|
/// Relocation block can be used when:
|
|
/// - no better slide exists (all the memory is used)
|
|
/// - slide=0 is forced (by an argument or safe mode)
|
|
/// - KASLR (slide) is unsupported (macOS 10.7 or older)
|
|
/// Right before kernel startup the relocation block is copied back to lower
|
|
/// addresses. Similarly all the other addresses pointing to relocation block
|
|
/// are also carefully adjusted.
|
|
///
|
|
EFI_PHYSICAL_ADDRESS RelocationBlock;
|
|
///
|
|
/// Real amount of memory used in the relocation block.
|
|
/// This value should match ksize in XNU BootArgs.
|
|
///
|
|
UINTN RelocationBlockUsed;
|
|
///
|
|
/// Relocation block is being used on macOS 10.4 or 10.5.
|
|
///
|
|
BOOLEAN RelocationBlockLegacy;
|
|
} KERNEL_SUPPORT_STATE;
|
|
|
|
/**
|
|
Apple booter KASLR slide support internal state.
|
|
**/
|
|
typedef struct SLIDE_SUPPORT_STATE_ {
|
|
///
|
|
/// Memory map analysis status determining slide usage.
|
|
///
|
|
BOOLEAN HasMemoryMapAnalysis;
|
|
///
|
|
/// TRUE if we are running on Intel Sandy or Ivy bridge.
|
|
///
|
|
BOOLEAN HasSandyOrIvy;
|
|
///
|
|
/// TRUE if CsrActiveConfig was set.
|
|
///
|
|
BOOLEAN HasCsrActiveConfig;
|
|
///
|
|
/// TRUE if BootArgs was set.
|
|
///
|
|
BOOLEAN HasBootArgs;
|
|
///
|
|
/// Read or assumed csr-arctive-config variable value.
|
|
///
|
|
UINT32 CsrActiveConfig;
|
|
///
|
|
/// Max slide value provided.
|
|
///
|
|
UINT8 ProvideMaxSlide;
|
|
///
|
|
/// Valid slides to choose from when using custom slide.
|
|
///
|
|
UINT8 ValidSlides[TOTAL_SLIDE_NUM];
|
|
///
|
|
/// Number of entries in ValidSlides.
|
|
///
|
|
UINT32 ValidSlideCount;
|
|
///
|
|
/// Apple kernel boot arguments read from boot-args variable and then
|
|
/// modified with an additional slide parameter in case custom slide is used.
|
|
///
|
|
CHAR8 BootArgs[BOOT_LINE_LENGTH];
|
|
///
|
|
/// BootArgs data size.
|
|
///
|
|
UINTN BootArgsSize;
|
|
///
|
|
/// Estimated size for kernel itself, device tree, memory map, and rt pages.
|
|
///
|
|
UINTN EstimatedKernelArea;
|
|
} SLIDE_SUPPORT_STATE;
|
|
|
|
/**
|
|
Apple Boot Compatibility context.
|
|
**/
|
|
typedef struct BOOT_COMPAT_CONTEXT_ {
|
|
///
|
|
/// Apple Boot Compatibility settings.
|
|
///
|
|
OC_ABC_SETTINGS Settings;
|
|
///
|
|
/// Runtime relocations.
|
|
///
|
|
RT_RELOC_PROTECT_DATA RtReloc;
|
|
///
|
|
/// UEFI Boot & Runtime Services original pointers.
|
|
///
|
|
UEFI_SERVICES_POINTERS ServicePtrs;
|
|
///
|
|
/// UEFI services override internal state.
|
|
///
|
|
SERVICES_OVERRIDE_STATE ServiceState;
|
|
///
|
|
/// Apple kernel support internal state.
|
|
///
|
|
KERNEL_SUPPORT_STATE KernelState;
|
|
///
|
|
/// Apple booter KASLR slide support internal state.
|
|
///
|
|
SLIDE_SUPPORT_STATE SlideSupport;
|
|
///
|
|
/// CPU information.
|
|
///
|
|
OC_CPU_INFO *CpuInfo;
|
|
} BOOT_COMPAT_CONTEXT;
|
|
|
|
/**
|
|
Obtain Apple Boot Compatibility context. This function must only
|
|
be called from wrapped services, where passing context arguments
|
|
is not possible.
|
|
|
|
@retval Apple Boot Compatibility context (not null).
|
|
**/
|
|
BOOT_COMPAT_CONTEXT *
|
|
GetBootCompatContext (
|
|
VOID
|
|
);
|
|
|
|
/**
|
|
Install UEFI services overrides as necessary.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
**/
|
|
VOID
|
|
InstallServiceOverrides (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat
|
|
);
|
|
|
|
/**
|
|
Prepare virtual memory management environment for later usage.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareMemoryPool (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat
|
|
);
|
|
|
|
/**
|
|
Prepare environment for Apple UEFI bootloader. See more details inside.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] LoadedImage UEFI loaded image protocol instance.
|
|
@param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareBooterState (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN OUT EFI_LOADED_IMAGE *LoadedImage,
|
|
IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareKernelJump32 (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat
|
|
);
|
|
|
|
/**
|
|
Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in] CallGate Kernel call gate address.
|
|
@param[in] HookAddress The function address to jump to when
|
|
entering the kernel call gate.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareKernelJump64 (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN EFI_PHYSICAL_ADDRESS CallGate,
|
|
IN UINTN HookAddress
|
|
);
|
|
|
|
/**
|
|
Prepare environment for normal booting. Called when boot.efi jumps to kernel.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] BootArgs Apple kernel boot arguments.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareForBooting (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN OUT VOID *BootArgs
|
|
);
|
|
|
|
/**
|
|
Prepare environment for hibernate wake. Called when boot.efi jumps to kernel.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] ImageHeaderPage Apple hibernate image page number.
|
|
**/
|
|
VOID
|
|
AppleMapPrepareForHibernateWake (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN UINTN ImageHeaderPage
|
|
);
|
|
|
|
/**
|
|
Prepare memory state and perform virtual address translation.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in] MemoryMapSize SetVirtualAddresses memory map size argument.
|
|
@param[in] DescriptorSize SetVirtualAddresses descriptor size argument.
|
|
@param[in] DescriptorVersion SetVirtualAddresses descriptor version argument.
|
|
@param[in] MemoryMap SetVirtualAddresses memory map argument.
|
|
**/
|
|
EFI_STATUS
|
|
AppleMapPrepareMemState (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN UINTN MemoryMapSize,
|
|
IN UINTN DescriptorSize,
|
|
IN UINT32 DescriptorVersion,
|
|
IN EFI_MEMORY_DESCRIPTOR *MemoryMap
|
|
);
|
|
|
|
/**
|
|
Assembly wrapper for AppleMapPrepareKernelState32.
|
|
Used to convert calling conventions and fixup registers.
|
|
**/
|
|
VOID
|
|
AsmAppleMapPrepareKernelState32 (
|
|
VOID
|
|
);
|
|
|
|
/**
|
|
Prepare environment for Apple kernel bootloader in boot or wake cases.
|
|
This callback arrives when boot.efi jumps to kernel entry point.
|
|
Should transfer control to restored kernel entry point with the same arguments.
|
|
|
|
@param[in] Args Case-specific kernel argument handle.
|
|
|
|
@returns Case-specific value if any.
|
|
**/
|
|
UINTN
|
|
EFIAPI
|
|
AppleMapPrepareKernelState32 (
|
|
IN UINTN Args
|
|
);
|
|
|
|
/**
|
|
Prepare environment for Apple kernel bootloader in boot or wake cases.
|
|
This callback arrives when boot.efi jumps to kernel call gate.
|
|
Should transfer control to kernel call gate + CALL_GATE_JUMP_SIZE
|
|
with the same arguments.
|
|
|
|
This uses the new (as of macOS 13 Developer Beta 1) prototype. This is due to
|
|
EfiBootRt wrapping the actual kernel call gate.
|
|
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
@param[in,out] KcgArguments Arguments to the kernel call gate.
|
|
@param[in] CallGate The kernel call gate.
|
|
|
|
@retval EFI_ABORTED The kernel could not be started.
|
|
@retval other On success, this function does not return.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AppleMapPrepareKernelStateNew64 (
|
|
IN UINTN SystemTable,
|
|
IN OUT APPLE_EFI_BOOT_RT_KCG_ARGS *KcgArguments,
|
|
IN KERNEL_CALL_GATE CallGate
|
|
);
|
|
|
|
/**
|
|
Prepare environment for Apple kernel bootloader in boot or wake cases.
|
|
This callback arrives when boot.efi jumps to kernel call gate.
|
|
Should transfer control to kernel call gate + CALL_GATE_JUMP_SIZE
|
|
with the same arguments.
|
|
|
|
This uses the old (prior to macOS 13 Developer Beta 1) prototype.
|
|
|
|
@param[in] Args Case-specific kernel argument handle.
|
|
@param[in] EntryPoint Case-specific kernel entry point.
|
|
@param[in] CallGate The kernel call gate.
|
|
|
|
@returns Case-specific value if any.
|
|
**/
|
|
UINTN
|
|
EFIAPI
|
|
AppleMapPrepareKernelStateOld64 (
|
|
IN UINTN Args,
|
|
IN UINTN EntryPoint,
|
|
IN KERNEL_CALL_GATE CallGate
|
|
);
|
|
|
|
/**
|
|
Patch boot.efi to support random and passed slide values in safe mode.
|
|
|
|
@param[in,out] ImageBase Apple booter image base.
|
|
@param[in] ImageSize Apple booter image size.
|
|
**/
|
|
VOID
|
|
AppleSlideUnlockForSafeMode (
|
|
IN OUT UINT8 *ImageBase,
|
|
IN UINTN ImageSize
|
|
);
|
|
|
|
/**
|
|
Primary custom KASLR support handler. This gets called on every
|
|
UEFI RuntimeServices GetVariable call and thus is useful to
|
|
perform KASLR slide injection through boot-args.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in] GetVariable Original UEFI GetVariable service.
|
|
@param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional.
|
|
@param[in] FilterMap GetMemoryMap result filter, optional.
|
|
@param[in] FilterMapContext FilterMap context, optional.
|
|
@param[in] VariableName GetVariable variable name argument.
|
|
@param[in] VendorGuid GetVariable vendor GUID argument.
|
|
@param[out] Attributes GetVariable attributes argument.
|
|
@param[in,out] DataSize GetVariable data size argument.
|
|
@param[out] Data GetVariable data argument.
|
|
|
|
@retval GetVariable status code.
|
|
**/
|
|
EFI_STATUS
|
|
AppleSlideGetVariable (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN EFI_GET_VARIABLE GetVariable,
|
|
IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL,
|
|
IN OC_MEMORY_FILTER FilterMap OPTIONAL,
|
|
IN VOID *FilterMapContext OPTIONAL,
|
|
IN CHAR16 *VariableName,
|
|
IN EFI_GUID *VendorGuid,
|
|
OUT UINT32 *Attributes OPTIONAL,
|
|
IN OUT UINTN *DataSize,
|
|
OUT VOID *Data
|
|
);
|
|
|
|
/**
|
|
Ensures that the original csr-active-config is passed to the kernel,
|
|
and removes customised slide value for security reasons.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] BootArgs Apple kernel boot arguments.
|
|
**/
|
|
VOID
|
|
AppleSlideRestore (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN OUT OC_BOOT_ARGUMENTS *BootArgs
|
|
);
|
|
|
|
/**
|
|
Get calculated relocation block size for booting with slide=0
|
|
(e.g. Safe Mode) or without KASLR (older macOS) when it is
|
|
otherwise impossible.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
|
|
@returns Size of the relocation block (maximum).
|
|
@retval 0 otherwise.
|
|
**/
|
|
UINTN
|
|
AppleSlideGetRelocationSize (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat
|
|
);
|
|
|
|
/**
|
|
Allocate memory from a relocation block when zero slide is unavailable.
|
|
EfiLoaderData at address.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional.
|
|
@param[in] AllocatePages Unmodified AllocatePages pointer.
|
|
@param[in] NumberOfPages Number of pages to allocate.
|
|
@param[in,out] Memory Memory address to allocate, may be updated.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
@retval EFI_UNSUPPORTED when zero slide is available.
|
|
**/
|
|
EFI_STATUS
|
|
AppleRelocationAllocatePages (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN EFI_GET_MEMORY_MAP GetMemoryMap,
|
|
IN EFI_ALLOCATE_PAGES AllocatePages,
|
|
IN UINTN NumberOfPages,
|
|
IN OUT EFI_PHYSICAL_ADDRESS *Memory
|
|
);
|
|
|
|
/**
|
|
Release relocation block if present.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
@retval EFI_UNSUPPORTED when zero slide is available.
|
|
**/
|
|
EFI_STATUS
|
|
AppleRelocationRelease (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat
|
|
);
|
|
|
|
/**
|
|
Transitions to virtual memory for the relocation block.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] BootArgs Apple kernel boot arguments.
|
|
**/
|
|
EFI_STATUS
|
|
AppleRelocationVirtualize (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN OUT OC_BOOT_ARGUMENTS *BA
|
|
);
|
|
|
|
/**
|
|
Transition from relocation block address space to normal low
|
|
memory address space in the relevant XNU areas.
|
|
|
|
@param[in,out] BootCompat Boot compatibility context.
|
|
@param[in,out] BootArgs Apple kernel boot arguments.
|
|
**/
|
|
VOID
|
|
AppleRelocationRebase (
|
|
IN OUT BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN OUT OC_BOOT_ARGUMENTS *BA
|
|
);
|
|
|
|
/**
|
|
Boot Apple Kernel through relocation block.
|
|
|
|
@param[in,out] Args On input, the un-relocated kernel argument handle.
|
|
On output, the relocated kernel argument handle.
|
|
@param[in] BootCompat Boot compatibility context.
|
|
@param[in] CallGate Kernel call gate address.
|
|
@param[in] KcgArg1 Pointer to the first kernel call gate argument.
|
|
@param[in] KcgArg2 Second kernel call gate argument.
|
|
**/
|
|
VOID
|
|
AppleRelocationCallGate64 (
|
|
IN OUT UINTN *Args,
|
|
IN BOOT_COMPAT_CONTEXT *BootCompat,
|
|
IN KERNEL_CALL_GATE CallGate,
|
|
IN UINTN *KcgArg1,
|
|
IN UINTN KcgArg2
|
|
);
|
|
|
|
#endif // BOOT_COMPAT_INTERNAL_H
|