Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
7eca5966
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7eca5966
编写于
8月 04, 2019
作者:
V
vit9696
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcAppleBootCompatLib: Initial version
上级
20120c7b
变更
20
展开全部
隐藏空白更改
内联
并排
Showing
20 changed file
with
2519 addition
and
4 deletion
+2519
-4
Include/Library/OcAppleBootCompatLib.h
Include/Library/OcAppleBootCompatLib.h
+67
-0
Include/Library/OcBootManagementLib.h
Include/Library/OcBootManagementLib.h
+28
-0
Include/Library/OcDebugLogLib.h
Include/Library/OcDebugLogLib.h
+5
-0
Include/Library/OcMiscLib.h
Include/Library/OcMiscLib.h
+9
-0
Include/Protocol/OcAppleBootCompat.h
Include/Protocol/OcAppleBootCompat.h
+37
-0
Library/OcAppleBootCompatLib/BootCompatInternal.h
Library/OcAppleBootCompatLib/BootCompatInternal.h
+335
-0
Library/OcAppleBootCompatLib/KernelSupport.c
Library/OcAppleBootCompatLib/KernelSupport.c
+655
-0
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.c
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.c
+114
-0
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf
+64
-0
Library/OcAppleBootCompatLib/ServiceOverrides.c
Library/OcAppleBootCompatLib/ServiceOverrides.c
+565
-0
Library/OcAppleBootCompatLib/X64/ContextSwitch.h
Library/OcAppleBootCompatLib/X64/ContextSwitch.h
+89
-0
Library/OcAppleBootCompatLib/X64/ContextSwitch.nasm
Library/OcAppleBootCompatLib/X64/ContextSwitch.nasm
+336
-0
Library/OcAppleBootCompatLib/X64/ContextSwitchSupport.c
Library/OcAppleBootCompatLib/X64/ContextSwitchSupport.c
+48
-0
Library/OcBootManagementLib/BootArguments.c
Library/OcBootManagementLib/BootArguments.c
+76
-0
Library/OcBootManagementLib/OcBootManagementLib.c
Library/OcBootManagementLib/OcBootManagementLib.c
+53
-0
Library/OcMemoryLib/VirtualMemory.c
Library/OcMemoryLib/VirtualMemory.c
+0
-4
Library/OcMiscLib/DirectReset.c
Library/OcMiscLib/DirectReset.c
+29
-0
Library/OcMiscLib/OcMiscLib.inf
Library/OcMiscLib/OcMiscLib.inf
+1
-0
OcSupportPkg.dec
OcSupportPkg.dec
+6
-0
OcSupportPkg.dsc
OcSupportPkg.dsc
+2
-0
未找到文件。
Include/Library/OcAppleBootCompatLib.h
0 → 100644
浏览文件 @
7eca5966
/** @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 OC_APPLE_BOOT_COMPAT_LIB_H
#define OC_APPLE_BOOT_COMPAT_LIB_H
/**
Apple Boot Compatibility layer configuration.
**/
typedef
struct
OC_ABC_SETTINGS_
{
///
/// Protect from boot.efi from defragmenting runtime memory and setup virtual memory
/// early mapping. This fixes NVRAM support on many firmwares.
///
BOOLEAN
SetupAppleMap
;
///
/// Provide custom Apple KASLR slide calculation for firmwares with polluted low memory ranges.
///
BOOLEAN
SetupAppleSlide
;
///
/// Discard UEFI memory map after waking from hibernation and preserve the original mapping.
///
BOOLEAN
DiscardAppleS4Map
;
///
/// Try to patch Apple bootloader to have KASLR enabled even in SafeMode.
///
BOOLEAN
EnableAppleSmSlide
;
///
/// Attempt to protect certain CSM memory regions from being used by the kernel .
/// On older firmwares this caused wake issues.
///
BOOLEAN
ProtectCsmRegion
;
///
/// Attempt to reduce memory map entries through grouping to fit into Apple kernel.
///
BOOLEAN
ShrinkMemoryMap
;
///
/// Ensure that ExitBootServices call succeeds even with outdated MemoryMap key.
///
BOOLEAN
ForceExitBootServices
;
}
OC_ABC_SETTINGS
;
/**
Initialize Apple Boot Compatibility layer. This layer is needed on partially
incompatible firmwares to prevent boot failure and UEFI services breakage.
@param[in] Settings Compatibility layer configuration.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcAbcInitialize
(
IN
OC_ABC_SETTINGS
*
Settings
);
#endif // OC_APPLE_BOOT_COMPAT_LIB_H
Include/Library/OcBootManagementLib.h
浏览文件 @
7eca5966
...
...
@@ -469,6 +469,16 @@ OcActivateHibernateWake (
IN
UINT32
HibernateMask
);
/**
Check if active hibernation is happening.
@retval TRUE on waking from hibernation.
**/
BOOLEAN
OcIsAppleHibernateWake
(
VOID
);
/**
Install missing boot policy, scan, and show simple boot menu.
...
...
@@ -547,6 +557,24 @@ OcParseBootArgs (
IN
VOID
*
BootArgs
);
/**
Check if boot argument is currently passed (via image options or NVRAM).
@param[in] LoadImage UEFI loaded image protocol instance, optional.
@param[in] GetVariable Preferred UEFI NVRAM reader, optional.
@param[in] Argument Argument, e.g. -v, slide=, debug=, etc.
@param[in] ArgumentLength Argument length, e.g. L_STR_LEN ("-v").
@retval TRUE if argument is present.
**/
BOOLEAN
OcCheckArgumentFromEnv
(
IN
EFI_LOADED_IMAGE
*
LoadedImage
OPTIONAL
,
IN
EFI_GET_VARIABLE
GetVariable
OPTIONAL
,
IN
CONST
CHAR8
*
Argument
,
IN
CONST
UINTN
ArgumentLength
);
/**
Get argument value from command line.
...
...
Include/Library/OcDebugLogLib.h
浏览文件 @
7eca5966
...
...
@@ -26,6 +26,11 @@
**/
#define DEBUG_BULK_INFO (DEBUG_VERBOSE|DEBUG_INFO)
/**
This is a place print debug messages when they happen after ExitBootServices.
**/
#define RUNTIME_DEBUG(x) do { } while (0)
/**
Install or update the OcLog protocol with specified options.
...
...
Include/Library/OcMiscLib.h
浏览文件 @
7eca5966
...
...
@@ -98,4 +98,13 @@ ReleaseUsbOwnership (
VOID
);
/**
Perform cold reboot directly bypassing UEFI services. Does not return.
Supposed to work in any modern physical or virtual environment.
**/
VOID
DirectRestCold
(
VOID
);
#endif // OC_MISC_LIB_H
Include/Protocol/OcAppleBootCompat.h
0 → 100644
浏览文件 @
7eca5966
/** @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 OC_APPLE_BOOT_COMPAT_PROTOCOL_H
#define OC_APPLE_BOOT_COMPAT_PROTOCOL_H
#define OC_APPLE_BOOT_COMPAT_PROTOCOL_REVISION 0x010000
//
// OC_APPLE_BOOT_COMPAT_PROTOCOL_GUID
// C7CBA84E-CC77-461D-9E3C-6BE0CB79A7C1
//
#define OC_APPLE_BOOT_COMPAT_PROTOCOL_GUID \
{ 0xC7CBA84E, 0xCC77, 0x461D, \
{ 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } }
//
// Includes a revision for debugging reasons
//
typedef
struct
{
UINTN
Revision
;
}
OC_APPLE_BOOT_COMPAT_PROTOCOL
;
extern
EFI_GUID
gOcAppleBootCompatProtocolGuid
;
#endif // OC_APPLE_BOOT_COMPAT_PROTOCOL_H
Library/OcAppleBootCompatLib/BootCompatInternal.h
0 → 100644
浏览文件 @
7eca5966
/** @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 <Library/OcAppleBootCompatLib.h>
#include <Library/OcDebugLogLib.h>
#include <Library/OcMemoryLib.h>
#include <Protocol/LoadedImage.h>
#ifdef MDE_CPU_X64
#include "X64/ContextSwitch.h"
#else
#error "Unsupported architecture!"
#endif
/**
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)
/**
Base kernel address.
**/
#define BASE_KERNEL_ADDR ((UINTN)0x100000)
/**
Slide offset per slide entry
**/
#define SLIDE_GRANULARITY ((UINTN)0x200000)
/**
Total possible number of KASLR slide offsets.
**/
#define TOTAL_SLIDE_NUM 256
/**
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 memory map function. We override it to make
/// memory map shrinking and CSM region protection.
///
EFI_GET_MEMORY_MAP
GetMemoryMap
;
///
/// Original exit boot services function. We override it
/// to ensure we always succeed exiting boot services.
///
EFI_EXIT_BOOT_SERVICES
ExitBootServices
;
///
/// Image starting routine. We override 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
;
///
/// Original virtual address mapping function. We override
/// it to perform runtime area protection to prevent boot.efi
/// defragmentation and setup virtual memory for firmwares
/// accessing it after exit boot services.
///
EFI_SET_VIRTUAL_ADDRESS_MAP
SetVirtualAddressMap
;
}
UEFI_SERVICES_POINTERS
;
/**
UEFI services override internal state.
**/
typedef
struct
SERVICES_OVERRIDE_STATE_
{
///
/// GetVariable arrival event.
///
EFI_EVENT
GetVariableEvent
;
///
/// Minimum address allocated by AlocatePages.
///
EFI_PHYSICAL_ADDRESS
MinAllocatedAddr
;
///
/// Maximum address allocated by AlocatePages.
///
EFI_PHYSICAL_ADDRESS
MaxAllocatedAddr
;
///
/// Apple hibernate image address allocated by AlocatePages.
///
EFI_PHYSICAL_ADDRESS
HibernateImageAddress
;
///
/// Last descriptor size obtained from GetMemoryMap.
///
UINTN
MemoryMapDescriptorSize
;
///
/// Amount of nested boot.efi detected.
///
UINTN
AppleBootNestedCount
;
///
/// TRUE if we are doing boot.efi hibernate wake.
///
BOOLEAN
AppleHibernateWake
;
///
/// TRUE if we are using custom KASLR slide (via boot arg).
///
BOOLEAN
AppleCustomSlide
;
}
SERVICES_OVERRIDE_STATE
;
/**
Apple kernel support internal state..
**/
typedef
struct
KERNEL_SUPPORT_STATE_
{
///
/// Assembly support internal state.
///
ASM_SUPPORT_STATE
AsmState
;
///
/// Kernel jump trampoline.
///
ASM_KERNEL_JUMP
KernelJump
;
///
/// Original kernel memory.
///
UINT8
KernelOrg
[
sizeof
(
ASM_KERNEL_JUMP
)];
///
/// Custom kernel UEFI System Table.
///
EFI_PHYSICAL_ADDRESS
SysTableRtArea
;
///
/// 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
;
}
KERNEL_SUPPORT_STATE
;
/**
Apple Boot Compatibility context.
**/
typedef
struct
BOOT_COMPAT_CONTEXT_
{
///
/// Apple Coot 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
;
}
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
*
ServicePtrs
);
/**
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
);
/**
Save UEFI environment state in implementation specific way.
@param[in,out] AsmState Assembly state to update, can be preserved.
@param[out] KernelJump Kernel jump trampoline to fill.
**/
VOID
AppleMapPlatformSaveState
(
IN
OUT
ASM_SUPPORT_STATE
*
AsmState
,
OUT
ASM_KERNEL_JUMP
*
KernelJump
);
/**
Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState.
@param[in,out] BootCompat Boot compatibility context.
@param[in] ImageAddress Kernel or hibernation image address.
@param[in] AppleHibernateWake TRUE when ImageAddress points to hibernation image.
**/
VOID
AppleMapPrepareKernelJump
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
UINTN
ImageAddress
,
IN
BOOLEAN
AppleHibernateWake
);
/**
Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState.
@param[in,out] BootCompat Boot compatibility context.
@param[in] ImageAddress Kernel or hibernation image address.
@param[in] AppleHibernateWake TRUE when ImageAddress points to hibernation image.
**/
EFI_STATUS
AppleMapPrepareVmState
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
UINTN
MemoryMapSize
,
IN
UINTN
DescriptorSize
,
IN
UINT32
DescriptorVersion
,
IN
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
);
/**
Prepare environment for Apple kernel bootloader in boot or wake cases.
This callback arrives when boot.efi jumps to kernel.
@param[in] Args Case-specific kernel argument handle.
@param[in] ModeX64 Debug flag about kernel context type, TRUE when X64.
@retval Args must be returned with the necessary modifications if any.
**/
UINTN
EFIAPI
AppleMapPrepareKernelState
(
IN
UINTN
Args
,
IN
BOOLEAN
ModeX64
);
#endif // BOOT_COMPAT_INTERNAL_H
Library/OcAppleBootCompatLib/KernelSupport.c
0 → 100644
浏览文件 @
7eca5966
此差异已折叠。
点击以展开。
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.c
0 → 100644
浏览文件 @
7eca5966
/** @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.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/OcDebugLogLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcAppleBootCompatLib.h>
#include <Library/OcDevicePathLib.h>
#include <Library/OcMiscLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/OcAppleBootCompat.h>
#include "BootCompatInternal.h"
/**
Apple Boot Compatibility protocol instance. Its GUID matches
with legacy AptioMemoryFix protocol, allowing us to avoid
conflicts between the two.
**/
STATIC
OC_APPLE_BOOT_COMPAT_PROTOCOL
mOcAppleBootCompatProtocol
=
{
OC_APPLE_BOOT_COMPAT_PROTOCOL_REVISION
};
/**
Apple Boot Compatibility context. This context is used throughout
the library. Must be accessed through GetBootCompatContext ().
**/
STATIC
BOOT_COMPAT_CONTEXT
mOcAppleBootCompatContext
;
STATIC
EFI_STATUS
InstallAbcProtocol
(
VOID
)
{
EFI_STATUS
Status
;
VOID
*
Interface
;
EFI_HANDLE
Handle
;
Status
=
gBS
->
LocateProtocol
(
&
gOcAppleBootCompatProtocolGuid
,
NULL
,
&
Interface
);
if
(
!
EFI_ERROR
(
Status
))
{
//
// Ensure we do not run with AptioMemoryFix.
// It also checks for attempts to install this protocol twice.
//
DEBUG
((
DEBUG_WARN
,
"OCABC: Found legacy AptioMemoryFix driver!
\n
"
));
return
EFI_ALREADY_STARTED
;
}
Handle
=
NULL
;
Status
=
gBS
->
InstallMultipleProtocolInterfaces
(
&
Handle
,
&
gOcAppleBootCompatProtocolGuid
,
&
mOcAppleBootCompatProtocol
,
NULL
);
if
(
EFI_ERROR
(
Status
))
{
DEBUG
((
DEBUG_WARN
,
"OCABC: protocol install failure - %r
\n
"
,
Status
));
return
Status
;
}
return
EFI_SUCCESS
;
}
BOOT_COMPAT_CONTEXT
*
GetBootCompatContext
(
VOID
)
{
return
&
mOcAppleBootCompatContext
;
}
EFI_STATUS
OcAbcInitialize
(
IN
OC_ABC_SETTINGS
*
Settings
)
{
EFI_STATUS
Status
;
Status
=
InstallAbcProtocol
();
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
InstallServiceOverrides
(
GetBootCompatContext
()
);
return
EFI_SUCCESS
;
}
Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf
0 → 100644
浏览文件 @
7eca5966
## @file
#
# Component description file for the library producing the Apple Device property protocol.
#
# Copyright (C) 2019, vit9696. All rights reserved.<BR>
#
# 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OcAppleBootCompatLib
FILE_GUID = A393F7CF-3966-4C7E-8763-3DD991681C9B
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = OcAppleBootCompatLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
BootCompatInternal.h
KernelSupport.c
OcAppleBootCompatLib.c
ServiceOverrides.c
[Sources.X64]
X64/ContextSwitch.nasm
X64/ContextSwitchSupport.c
[Packages]
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
EfiPkg/EfiPkg.dec
[Guids]
gAppleBootVariableGuid ## SOMETIMES_CONSUMES
[Protocols]
gOcAppleBootCompatProtocolGuid ## PRODUCES
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
DevicePathLib
MemoryAllocationLib
PrintLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
OcGuardLib
OcMemoryLib
Library/OcAppleBootCompatLib/ServiceOverrides.c
0 → 100644
浏览文件 @
7eca5966
/** @file
Copyright (C) 2013, dmazar. All rights reserved.
Copyright (C) 2017, 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.
**/
#include "BootCompatInternal.h"
#include <IndustryStandard/AppleHibernate.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcMemoryLib.h>
#include <Library/OcMiscLib.h>
#include <Library/OcStringLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/OcFirmwareRuntime.h>
/**
Helper function to call ExitBootServices that can handle outdated MapKey issues.
@param[in] ExitBootServices ExitBootServices function pointer, optional.
@param[in] GetMemoryMap GetMemoryMap function pointer, optional.
@param[in] ImageHandle Image handle to call ExitBootServices on.
@param[in] MapKey MapKey to call ExitBootServices on.
@retval EFI_SUCCESS on success.
**/
STATIC
EFI_STATUS
ForceExitBootServices
(
IN
EFI_HANDLE
ImageHandle
,
IN
UINTN
MapKey
,
IN
EFI_EXIT_BOOT_SERVICES
ExitBootServices
OPTIONAL
,
IN
EFI_GET_MEMORY_MAP
GetMemoryMap
OPTIONAL
)
{
EFI_STATUS
Status
;
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
;
UINTN
MemoryMapSize
;
UINTN
DescriptorSize
;
UINT32
DescriptorVersion
;
if
(
ExitBootServices
==
NULL
)
{
ExitBootServices
=
gBS
->
ExitBootServices
;
}
if
(
GetMemoryMap
==
NULL
)
{
GetMemoryMap
=
gBS
->
GetMemoryMap
;
}
//
// Firstly try the easy way.
//
Status
=
ExitBootServices
(
ImageHandle
,
MapKey
);
if
(
EFI_ERROR
(
Status
))
{
//
// It is too late to free memory map here, but it does not matter, because boot.efi has an old one
// and will freely use the memory.
// It is technically forbidden to allocate pool memory here, but we should not hit this code
// in the first place, and for older firmwares, where it was necessary (?), it worked just fine.
//
Status
=
GetCurrentMemoryMapAlloc
(
&
MemoryMapSize
,
&
MemoryMap
,
&
MapKey
,
&
DescriptorSize
,
&
DescriptorVersion
,
GetMemoryMap
,
NULL
);
if
(
Status
==
EFI_SUCCESS
)
{
//
// We have the latest memory map and its key, try again!
//
Status
=
ExitBootServices
(
ImageHandle
,
MapKey
);
if
(
EFI_ERROR
(
Status
))
{
DEBUG
((
DEBUG_WARN
,
"OCABC: ExitBootServices failed twice - %r
\n
"
,
Status
));
}
}
else
{
DEBUG
((
DEBUG_WARN
,
"OCABC: Failed to get MapKey for ExitBootServices - %r
\n
"
,
Status
));
Status
=
EFI_INVALID_PARAMETER
;
}
if
(
EFI_ERROR
(
Status
))
{
DEBUG
((
DEBUG_WARN
,
"OCABC: Waiting 10 secs...
\n
"
));
gBS
->
Stall
(
SECONDS_TO_MICROSECONDS
(
10
));
}
}
return
Status
;
}
/**
UEFI Boot Services StartImage override. Called to start an efi image.
If this is boot.efi, then our overrides are enabled.
**/
STATIC
EFI_STATUS
EFIAPI
OcStartImage
(
IN
EFI_HANDLE
ImageHandle
,
OUT
UINTN
*
ExitDataSize
,
OUT
CHAR16
**
ExitData
OPTIONAL
)
{
EFI_STATUS
Status
;
EFI_LOADED_IMAGE_PROTOCOL
*
AppleLoadedImage
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
AppleLoadedImage
=
OcGetAppleBootLoadedImage
(
ImageHandle
);
//
// Clear monitoring vars
//
BootCompat
->
ServiceState
.
MinAllocatedAddr
=
0
;
BootCompat
->
ServiceState
.
MaxAllocatedAddr
=
0
;
if
(
AppleLoadedImage
!=
NULL
)
{
//
// Report about macOS being loaded.
//
++
BootCompat
->
ServiceState
.
AppleBootNestedCount
;
BootCompat
->
ServiceState
.
AppleHibernateWake
=
OcIsAppleHibernateWake
();
BootCompat
->
ServiceState
.
AppleCustomSlide
=
OcCheckArgumentFromEnv
(
AppleLoadedImage
,
BootCompat
->
ServicePtrs
.
GetVariable
,
"slide="
,
L_STR_LEN
(
"slide="
)
);
if
(
BootCompat
->
Settings
.
EnableAppleSmSlide
)
{
// FIXME: Implement.
//UnlockSlideSupportForSafeMode (
// (UINT8 *) AppleLoadedImage->ImageBase,
// AppleLoadedImage->ImageSize
// );
}
if
(
BootCompat
->
Settings
.
SetupAppleMap
)
{
AppleMapPrepareBooterState
(
BootCompat
,
AppleLoadedImage
,
BootCompat
->
ServicePtrs
.
GetMemoryMap
);
}
}
Status
=
BootCompat
->
ServicePtrs
.
StartImage
(
ImageHandle
,
ExitDataSize
,
ExitData
);
if
(
AppleLoadedImage
!=
NULL
)
{
//
// We failed but other operating systems should be loadable.
//
--
BootCompat
->
ServiceState
.
AppleBootNestedCount
;
}
return
Status
;
}
/**
UEFI Boot Services AllocatePages override.
Returns pages from free memory block to boot.efi for kernel boot image.
**/
STATIC
EFI_STATUS
EFIAPI
OcAllocatePages
(
IN
EFI_ALLOCATE_TYPE
Type
,
IN
EFI_MEMORY_TYPE
MemoryType
,
IN
UINTN
NumberOfPages
,
IN
OUT
EFI_PHYSICAL_ADDRESS
*
Memory
)
{
EFI_STATUS
Status
;
EFI_PHYSICAL_ADDRESS
UpperAddr
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
Status
=
BootCompat
->
ServicePtrs
.
AllocatePages
(
Type
,
MemoryType
,
NumberOfPages
,
Memory
);
if
(
!
EFI_ERROR
(
Status
)
&&
BootCompat
->
ServiceState
.
AppleBootNestedCount
>
0
)
{
if
(
Type
==
AllocateAddress
&&
MemoryType
==
EfiLoaderData
)
{
//
// Called from boot.efi
//
UpperAddr
=
*
Memory
+
EFI_PAGES_TO_SIZE
(
NumberOfPages
);
//
// Store min and max mem: they can be used later to determine
// start and end of kernel boot or hibernation images.
//
if
(
BootCompat
->
ServiceState
.
MinAllocatedAddr
==
0
||
*
Memory
<
BootCompat
->
ServiceState
.
MinAllocatedAddr
)
{
BootCompat
->
ServiceState
.
MinAllocatedAddr
=
*
Memory
;
}
if
(
UpperAddr
>
BootCompat
->
ServiceState
.
MaxAllocatedAddr
)
{
BootCompat
->
ServiceState
.
MaxAllocatedAddr
=
UpperAddr
;
}
}
else
if
(
BootCompat
->
ServiceState
.
AppleHibernateWake
&&
Type
==
AllocateAnyPages
&&
MemoryType
==
EfiLoaderData
&&
BootCompat
->
ServiceState
.
HibernateImageAddress
==
0
)
{
//
// Called from boot.efi during hibernate wake,
// first such allocation is for hibernate image
//
BootCompat
->
ServiceState
.
HibernateImageAddress
=
*
Memory
;
}
}
return
Status
;
}
/**
UEFI Boot Services GetMemoryMap override.
Returns shrinked memory map as XNU can handle up to PMAP_MEMORY_REGIONS_SIZE (128) entries.
Also applies any further memory map alterations as necessary.
**/
STATIC
EFI_STATUS
EFIAPI
OcGetMemoryMap
(
IN
OUT
UINTN
*
MemoryMapSize
,
IN
OUT
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
,
OUT
UINTN
*
MapKey
,
OUT
UINTN
*
DescriptorSize
,
OUT
UINT32
*
DescriptorVersion
)
{
EFI_STATUS
Status
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
Status
=
BootCompat
->
ServicePtrs
.
GetMemoryMap
(
MemoryMapSize
,
MemoryMap
,
MapKey
,
DescriptorSize
,
DescriptorVersion
);
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
if
(
BootCompat
->
ServiceState
.
AppleBootNestedCount
>
0
)
{
if
(
BootCompat
->
Settings
.
ProtectCsmRegion
)
{
// FIXME: Implement.
//ProtectCsmRegion (
// *MemoryMapSize,
// MemoryMap,
// *DescriptorSize
// );
}
if
(
BootCompat
->
Settings
.
ShrinkMemoryMap
)
{
ShrinkMemoryMap
(
MemoryMapSize
,
MemoryMap
,
*
DescriptorSize
);
}
//
// Remember some descriptor size, since we will not have it later
// during hibernate wake to be able to iterate memory map.
//
BootCompat
->
ServiceState
.
MemoryMapDescriptorSize
=
*
DescriptorSize
;
}
return
Status
;
}
/**
UEFI Boot Services ExitBootServices override.
Patches kernel entry point with jump to our KernelEntryPatchJumpBack().
**/
STATIC
EFI_STATUS
EFIAPI
OcExitBootServices
(
IN
EFI_HANDLE
ImageHandle
,
IN
UINTN
MapKey
)
{
EFI_STATUS
Status
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
//
// For non-macOS operating systems return directly.
//
if
(
BootCompat
->
ServiceState
.
AppleBootNestedCount
==
0
)
{
return
BootCompat
->
ServicePtrs
.
ExitBootServices
(
ImageHandle
,
MapKey
);
}
//
// We need hibernate image address for wake, check it quickly before
// killing boot services to be able to print the error.
//
if
(
BootCompat
->
Settings
.
SetupAppleMap
&&
BootCompat
->
ServiceState
.
AppleHibernateWake
&&
BootCompat
->
ServiceState
.
HibernateImageAddress
==
0
)
{
DEBUG
((
DEBUG_ERROR
,
"OCABC: Failed to find hibernate image address
\n
"
));
gBS
->
Stall
(
SECONDS_TO_MICROSECONDS
(
5
));
return
EFI_INVALID_PARAMETER
;
}
if
(
BootCompat
->
Settings
.
ForceExitBootServices
)
{
Status
=
ForceExitBootServices
(
ImageHandle
,
MapKey
,
BootCompat
->
ServicePtrs
.
ExitBootServices
,
BootCompat
->
ServicePtrs
.
GetMemoryMap
);
}
else
{
Status
=
BootCompat
->
ServicePtrs
.
ExitBootServices
(
ImageHandle
,
MapKey
);
}
//
// Abort on error or when we are not supposed to do extra mapping.
//
if
(
EFI_ERROR
(
Status
)
||
!
BootCompat
->
Settings
.
SetupAppleMap
)
{
return
Status
;
}
if
(
!
BootCompat
->
ServiceState
.
AppleHibernateWake
)
{
AppleMapPrepareKernelJump
(
BootCompat
,
(
UINTN
)
BootCompat
->
ServiceState
.
MinAllocatedAddr
,
FALSE
);
}
else
{
AppleMapPrepareKernelJump
(
BootCompat
,
(
UINTN
)
BootCompat
->
ServiceState
.
HibernateImageAddress
,
TRUE
);
}
return
Status
;
}
/**
UEFI Runtime Services SetVirtualAddressMap override.
Fixes virtualizing of RT services.
**/
STATIC
EFI_STATUS
EFIAPI
OcSetVirtualAddressMap
(
IN
UINTN
MemoryMapSize
,
IN
UINTN
DescriptorSize
,
IN
UINT32
DescriptorVersion
,
IN
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
)
{
EFI_STATUS
Status
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
//
// This is the time for us to remove our hacks.
// Make SetVirtualAddressMap useable once again.
// We do not need to recover BS, since they already are invalid.
//
gRT
->
SetVirtualAddressMap
=
BootCompat
->
ServicePtrs
.
SetVirtualAddressMap
;
gRT
->
Hdr
.
CRC32
=
0
;
gRT
->
Hdr
.
CRC32
=
CalculateCrc32
(
gRT
,
gRT
->
Hdr
.
HeaderSize
);
//
// For non-macOS operating systems return directly.
// Also do nothing for custom mapping.
//
if
(
BootCompat
->
ServiceState
.
AppleBootNestedCount
==
0
||
!
BootCompat
->
Settings
.
SetupAppleMap
)
{
Status
=
gRT
->
SetVirtualAddressMap
(
MemoryMapSize
,
DescriptorSize
,
DescriptorVersion
,
MemoryMap
);
}
else
{
Status
=
AppleMapPrepareVmState
(
BootCompat
,
MemoryMapSize
,
DescriptorSize
,
DescriptorVersion
,
MemoryMap
);
}
return
Status
;
}
/**
UEFI Runtime Services GetVariable override.
Used to return customised values for boot-args and csr-active-config variables.
**/
STATIC
EFI_STATUS
EFIAPI
OcGetVariable
(
IN
CHAR16
*
VariableName
,
IN
EFI_GUID
*
VendorGuid
,
OUT
UINT32
*
Attributes
OPTIONAL
,
IN
OUT
UINTN
*
DataSize
,
OUT
VOID
*
Data
)
{
EFI_STATUS
Status
;
BOOT_COMPAT_CONTEXT
*
BootCompat
;
BootCompat
=
GetBootCompatContext
();
if
(
BootCompat
->
Settings
.
SetupAppleSlide
)
{
// FIXME: Implement
}
Status
=
BootCompat
->
ServicePtrs
.
GetVariable
(
VariableName
,
VendorGuid
,
Attributes
,
DataSize
,
Data
);
return
Status
;
}
/**
UEFI Runtime Services GetVariable override event handler.
We do not override GetVariable ourselves but let our runtime do that.
@param[in] Event Event handle.
@param[in] Context Services pointers context.
**/
STATIC
VOID
EFIAPI
SetGetVariableHookHandler
(
IN
EFI_EVENT
Event
,
IN
VOID
*
Context
)
{
EFI_STATUS
Status
;
OC_FIRMWARE_RUNTIME_PROTOCOL
*
FwRuntime
;
UEFI_SERVICES_POINTERS
*
ServicePtrs
;
ServicePtrs
=
(
UEFI_SERVICES_POINTERS
*
)
Context
;
if
(
ServicePtrs
->
GetVariable
==
NULL
)
{
Status
=
gBS
->
LocateProtocol
(
&
gOcFirmwareRuntimeProtocolGuid
,
NULL
,
(
VOID
**
)
&
FwRuntime
);
if
(
!
EFI_ERROR
(
Status
)
&&
FwRuntime
->
Revision
==
OC_FIRMWARE_RUNTIME_REVISION
)
{
FwRuntime
->
OnGetVariable
(
OcGetVariable
,
&
ServicePtrs
->
GetVariable
);
}
}
}
VOID
InstallServiceOverrides
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
)
{
EFI_STATUS
Status
;
VOID
*
Registration
;
UEFI_SERVICES_POINTERS
*
ServicePtrs
;
ServicePtrs
=
&
BootCompat
->
ServicePtrs
;
ServicePtrs
->
AllocatePages
=
gBS
->
AllocatePages
;
ServicePtrs
->
GetMemoryMap
=
gBS
->
GetMemoryMap
;
ServicePtrs
->
ExitBootServices
=
gBS
->
ExitBootServices
;
ServicePtrs
->
StartImage
=
gBS
->
StartImage
;
ServicePtrs
->
SetVirtualAddressMap
=
gRT
->
SetVirtualAddressMap
;
gBS
->
AllocatePages
=
OcAllocatePages
;
gBS
->
GetMemoryMap
=
OcGetMemoryMap
;
gBS
->
ExitBootServices
=
OcExitBootServices
;
gBS
->
StartImage
=
OcStartImage
;
gRT
->
SetVirtualAddressMap
=
OcSetVirtualAddressMap
;
gBS
->
Hdr
.
CRC32
=
0
;
gBS
->
Hdr
.
CRC32
=
CalculateCrc32
(
gBS
,
gBS
->
Hdr
.
HeaderSize
);
gRT
->
Hdr
.
CRC32
=
0
;
gRT
->
Hdr
.
CRC32
=
CalculateCrc32
(
gRT
,
gRT
->
Hdr
.
HeaderSize
);
//
// Allocate memory pool if needed.
//
if
(
BootCompat
->
Settings
.
SetupAppleMap
)
{
AppleMapPrepareMemoryPool
(
BootCompat
);
}
//
// Update GetVariable handle with the help of external runtime services.
//
SetGetVariableHookHandler
(
NULL
,
ServicePtrs
);
if
(
ServicePtrs
->
GetVariable
!=
NULL
)
{
return
;
}
Status
=
gBS
->
CreateEvent
(
EVT_NOTIFY_SIGNAL
,
TPL_NOTIFY
,
SetGetVariableHookHandler
,
ServicePtrs
,
&
BootCompat
->
ServiceState
.
GetVariableEvent
);
if
(
!
EFI_ERROR
(
Status
))
{
Status
=
gBS
->
RegisterProtocolNotify
(
&
gOcFirmwareRuntimeProtocolGuid
,
BootCompat
->
ServiceState
.
GetVariableEvent
,
&
Registration
);
if
(
EFI_ERROR
(
Status
))
{
gBS
->
CloseEvent
(
&
BootCompat
->
ServiceState
.
GetVariableEvent
);
}
}
}
Library/OcAppleBootCompatLib/X64/ContextSwitch.h
0 → 100644
浏览文件 @
7eca5966
/** @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 CONTEXT_SWITCH_H
#define CONTEXT_SWITCH_H
//
// Structure definitions shared with ASM code.
// Keep these definitions in sync with ContextSwitch.nasm!
//
/**
Assembly support state.
This state is used as an intermediate structure to hold UEFI environment
context and kernel environment context for switching between 32-bit
and 64-bit modes during booting as normal XNU boot still happens in 32-bit.
**/
typedef
struct
ASM_SUPPORT_STATE_
{
UINT64
SavedGDTR
;
UINT16
SavedGDTRLimit
;
UINT64
SavedIDTR
;
UINT16
SavedIDTRLimit
;
UINT64
SavedCR3
;
UINT16
SavedCS
;
UINT16
SavedDS
;
UINT16
SavedES
;
UINT16
SavedFS
;
UINT16
SavedGS
;
UINT16
SavedSS
;
UINT64
SavedGDTR32
;
UINT16
SavedGDTR32Limit
;
UINT64
SavedIDTR32
;
UINT16
SavedIDTR32Limit
;
UINT16
SavedCS32
;
UINT16
SavedDS32
;
UINT16
SavedES32
;
UINT16
SavedFS32
;
UINT16
SavedGS32
;
UINT16
SavedSS32
;
UINT32
SavedESP32
;
VOID
*
KernelEntry
;
}
ASM_SUPPORT_STATE
;
/**
Assembly kernel trampoline.
This structure contains encoded assembly to jump from kernel
code to UEFI code through AsmAppleMapPlatformPrepareKernelState
intermediate handler.
**/
typedef
struct
ASM_KERNEL_JUMP_
{
UINT8
MovInst
;
UINT32
Addr
;
UINT16
CallInst
;
}
ASM_KERNEL_JUMP
;
VOID
EFIAPI
AsmAppleMapPlatformSaveState
(
IN
OUT
ASM_SUPPORT_STATE
*
AsmState
);
/**
Assembly interface for backjump from kernel code.
Takes kernel arguments through RAX or EAX register.
**/
VOID
AsmAppleMapPlatformPrepareKernelState
(
);
/**
Assembly global variable containing ASM_SUPPORT_STATE address.
Must fit into lower 32-bit bytes due to 32-bit .
**/
extern
UINT32
gOcAbcAsmStateAddr32
;
#endif // CONTEXT_SWITCH_H
Library/OcAppleBootCompatLib/X64/ContextSwitch.nasm
0 → 100755
浏览文件 @
7eca5966
;------------------------------------------------------------------------------
; @file
; Copyright (C) 2013, dmazar. All rights reserved.
; 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.
;------------------------------------------------------------------------------
BITS 64
DEFAULT REL
;------------------------------------------------------------------------------
; Structure definitions shared with C code.
; Keep these definitions in sync with ContextSwitch.h!
;------------------------------------------------------------------------------
struc ASM_SUPPORT_STATE
;------------------------------------------------------------------------------
; 64-bit state
;------------------------------------------------------------------------------
.SavedGDTR resq 1
.SavedGDTRLimit resw 1
.SavedIDTR resq 1
.SavedIDTRLimit resw 1
.SavedCR3 resq 1
.SavedCS resw 1
.SavedDS resw 1
.SavedES resw 1
.SavedFS resw 1
.SavedGS resw 1
.SavedSS resw 1
;------------------------------------------------------------------------------
; 32-bit state
;------------------------------------------------------------------------------
.SavedGDTR32 resq 1
.SavedGDTR32Limit resw 1
.SavedIDTR32 resq 1
.SavedIDTR32Limit resw 1
.SavedCS32 resw 1
.SavedDS32 resw 1
.SavedES32 resw 1
.SavedFS32 resw 1
.SavedGS32 resw 1
.SavedSS32 resw 1
.SavedESP32 resd 1
;------------------------------------------------------------------------------
; Kernel entry address.
;------------------------------------------------------------------------------
.KernelEntry resq 1
.Size:
endstruc
struc ASM_KERNEL_JUMP
.MovInst resb 1
.Addr resd 1
.CallInst resw 1
.Size:
endstruc
;------------------------------------------------------------------------------
; C callback method called on jump to kernel after boot.efi finishes.
;------------------------------------------------------------------------------
extern ASM_PFX(AppleMapPrepareKernelState)
SECTION .text
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmAppleMapPlatformSaveState (
; OUT ASM_SUPPORT_STATE *AsmState
; );
;------------------------------------------------------------------------------
align 8
global ASM_PFX(AsmAppleMapSaveState)
ASM_PFX(AsmAppleMapSaveState):
BITS 64
sgdt [rcx + ASM_SUPPORT_STATE.SavedGDTR]
sidt [rcx + ASM_SUPPORT_STATE.SavedIDTR]
mov rax, cr3
mov [rcx + ASM_SUPPORT_STATE.SavedCR3], rax
mov word [rcx + ASM_SUPPORT_STATE.SavedCS], cs
mov word [rcx + ASM_SUPPORT_STATE.SavedDS], ds
mov word [rcx + ASM_SUPPORT_STATE.SavedES], es
mov word [rcx + ASM_SUPPORT_STATE.SavedFS], fs
mov word [rcx + ASM_SUPPORT_STATE.SavedGS], gs
mov word [rcx + ASM_SUPPORT_STATE.SavedSS], ss
ret
;------------------------------------------------------------------------------
; Long (far) return.
; retfq (lretq) - 64-bit encoding 48 CB
; retf (lret) - 32-bit encoding CB
;------------------------------------------------------------------------------
LONG_RET64:
db 048h
LONG_RET32:
db 0CBh
;------------------------------------------------------------------------------
; AsmAppleMapPlatformPrepareKernelState
;
; Callback from boot.efi - this is where we jump when boot.efi jumps to kernel.
; eax register contains boot arguments for the kernel.
;
; - test if we are in 32 bit or in 64 bit
; - if 64 bit, then jump to AsmJumpFromKernel64
; - else just continue with AsmJumpFromKernel32
;------------------------------------------------------------------------------
global ASM_PFX(AsmAppleMapPlatformPrepareKernelState)
ASM_PFX(AsmAppleMapPlatformPrepareKernelState):
BITS 32
push eax ; save bootArgs pointer to stack
mov dword ecx, 0C0000080h ; EFER MSR number.
rdmsr ; Read EFER.
bt eax, 8 ; Check if LME==1 -> CF=1.
pop eax
jc AsmJumpFromKernel64 ; LME==1 -> jump to 64 bit code
; otherwise, continue with AsmJumpFromKernel32
; Above 32-bit code must give the opcodes equivalent to following in 64-bit.
;BITS 64
; push rax ; save bootArgs pointer to stack
; mov ecx, C0000080h ; EFER MSR number.
; rdmsr ; Read EFER.
; bt eax, 8 ; Check if LME==1 -> CF=1.
; pop rax
; jc AsmJumpFromKernel64 ; LME==1 -> jump to 64 bit code
;------------------------------------------------------------------------------
; AsmJumpFromKernel32
;
; Callback from boot.efi in 32 bit mode.
;------------------------------------------------------------------------------
AsmJumpFromKernel32:
BITS 32
; Save bootArgs pointer to edi.
mov edi, eax
; Load ebx with AsmState - we'll access our saved data with it.
db 0BBh ; mov ebx, OFFSET DataBase
;------------------------------------------------------------------------------
; 32-bit pointer to AsmState used to reduce global variable access.
; Defined here becuase 32-bit mode does not support relative addressing.
; As both jumps can happen from 64-bit kernel, the address must fit in 4 bytes.
;------------------------------------------------------------------------------
global ASM_PFX(gOcAbcAsmStateAddr32)
ASM_PFX(gOcAbcAsmStateAddr32):
dd 0
; Store kernel entery point prior to hunk code.
pop ecx
sub ecx, ASM_KERNEL_JUMP.Size
mov dword [ebx + ASM_SUPPORT_STATE.KernelEntry], ecx
; Store 32-bit state to be able to recover it later.
sgdt [ebx + ASM_SUPPORT_STATE.SavedGDTR32]
sidt [ebx + ASM_SUPPORT_STATE.SavedIDTR32]
mov word [ebx + ASM_SUPPORT_STATE.SavedCS32], cs
mov word [ebx + ASM_SUPPORT_STATE.SavedDS32], ds
mov word [ebx + ASM_SUPPORT_STATE.SavedES32], es
mov word [ebx + ASM_SUPPORT_STATE.SavedFS32], fs
mov word [ebx + ASM_SUPPORT_STATE.SavedGS32], gs
mov word [ebx + ASM_SUPPORT_STATE.SavedSS32], ss
mov dword [ebx + ASM_SUPPORT_STATE.SavedESP32], esp
;
; Transition to 64-bit mode...
; FIXME: we should ensure interrupts are disabled here.
;
; Load saved UEFI GDT and IDT.
; They will become active after code segment is changed in long jump.
lgdt [ebx + ASM_SUPPORT_STATE.SavedGDTR]
lidt [ebx + ASM_SUPPORT_STATE.SavedIDTR]
; Enable the 64-bit page-translation-table entries by setting CR4.PAE=1.
mov eax, cr4
bts eax, 5
mov cr4, eax
; Set the long-mode page tables by reusing saved UEFI tables.
mov eax, dword [ebx + ASM_SUPPORT_STATE.SavedCR3]
mov cr3, eax
; Enable long mode (set EFER.LME=1).
mov ecx, 0C0000080h ; EFER MSR number.
rdmsr ; Read EFER.
bts eax, 8 ; Set LME=1.
wrmsr ; Write EFER.
; Enable paging to activate long mode (set CR0.PG=1).
mov eax, cr0 ; Read CR0.
bts eax, 31 ; Set PG=1.
mov cr0, eax ; Write CR0.
; Jump to the 64-bit code segment.
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedCS]
push eax
call LONG_RET32
BITS 64
;
; Done transitioning to 64-bit code.
;
; Set other segment selectors. In most firmwares all segment registers but cs
; point to the same selector, but we must not rely on it.
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedDS]
mov ds, ax
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedES]
mov es, ax
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedFS]
mov fs, ax
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedGS]
mov gs, ax
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedSS]
mov ss, ax
; Assume the stack is useasble but potentially misaligned.
and rsp, 0FFFFFFFFFFFFFFF0h
; Call AppleMapPrepareKernelState (rcx = rax = bootArgs, rdx = 0 = 32 bit kernel jump).
mov rcx, rdi
xor edx, edx
push rdx
push rdx
push rdx
push rcx
call ASM_PFX(AppleMapPrepareKernelState)
; Return value in rax is bootArgs pointer again.
mov rdi, rax
;
; Transition back to 32-bit.
;
; Load saved 32-bit GDT.
lgdt [rbx + ASM_SUPPORT_STATE.SavedGDTR32]
; Jump to the 32-bit code segment.
mov ax, word [rbx + ASM_SUPPORT_STATE.SavedCS32]
push rax
call LONG_RET64
BITS 32
;
; Done transitioning to 32-bit code.
;
; Disable paging (set CR0.PG=0).
mov eax, cr0 ; Read CR0.
btr eax, 31 ; Set PG=0.
mov cr0, eax ; Write CR0.
; Disable long mode (set EFER.LME=0).
mov ecx, 0C0000080h ; EFER MSR number.
rdmsr ; Read EFER.
btr eax, 8 ; Set LME=0.
wrmsr ; Write EFER.
jmp AsmJumpFromKernel32Compatibility
AsmJumpFromKernel32Compatibility:
;
; We are in 32-bit protected mode, no paging.
;
; Reload saved 32 bit state data.
lidt [ebx + ASM_SUPPORT_STATE.SavedIDTR32]
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedDS32]
mov ds, ax
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedES32]
mov es, ax
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedFS32]
mov fs, ax
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedGS32]
mov gs, ax
mov ax, word [ebx + ASM_SUPPORT_STATE.SavedSS32]
mov ss, ax ; disables interrupts for 1 instruction to load esp
mov esp, dword [ebx + ASM_SUPPORT_STATE.SavedESP32]
; Jump back to the kernel passing boot arguments in eax.
mov eax, edi
mov edx, dword [ebx + ASM_SUPPORT_STATE.KernelEntry]
jmp edx
;------------------------------------------------------------------------------
; AsmJumpFromKernel64
;
; Callback from boot.efi in 64 bit mode.
; State is prepared for kernel: 64 bit, pointer to bootArgs in rax.
;------------------------------------------------------------------------------
AsmJumpFromKernel64:
BITS 64
; Load rbx with AsmState - we'll access our saved data with it.
mov ebx, dword [ASM_PFX(gOcAbcAsmStateAddr32)]
; Store kernel entery point prior to hunk code.
pop rcx
sub rcx, ASM_KERNEL_JUMP.Size
mov qword [rbx + ASM_SUPPORT_STATE.KernelEntry], rcx
; Call AppleMapPrepareKernelState (rcx = rax = bootArgs, rdx = 1 = 64-bit kernel jump).
mov rcx, rax
xor edx, edx
push rdx
push rdx
push rdx
push rcx
inc edx
call ASM_PFX(AppleMapPrepareKernelState)
; Jump back to the kernel passing boot arguments in rax.
mov rdx, [rbx + ASM_SUPPORT_STATE.KernelEntry]
jmp rdx
Library/OcAppleBootCompatLib/X64/ContextSwitchSupport.c
0 → 100644
浏览文件 @
7eca5966
/** @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.
**/
#include "../BootCompatInternal.h"
#include <Library/DebugLib.h>
VOID
AppleMapPlatformSaveState
(
IN
OUT
ASM_SUPPORT_STATE
*
AsmState
,
OUT
ASM_KERNEL_JUMP
*
KernelJump
)
{
//
// Save current 64-bit state - will be used later in callback from kernel jump
// to be able to transition to 64-bit in case 32-bit kernel startup code is used.
//
AsmAppleMapPlatformSaveState
(
AsmState
);
//
// Assembly state must fit into 32-bit address as we may jumo from 32-bit kernel
// startup code. This is used instead of GetBootCompatContext.
//
ASSERT
((
UINT32
)(
UINTN
)
AsmState
==
(
UINTN
)
AsmState
);
gOcAbcAsmStateAddr32
=
(
UINT32
)(
UINTN
)
AsmState
;
//
// Kernel trampoline for jumping to kernel.
//
ASSERT
(
(
UINT32
)(
UINTN
)
AsmAppleMapPlatformPrepareKernelState
==
(
UINTN
)
AsmAppleMapPlatformPrepareKernelState
);
KernelJump
->
MovInst
=
0xB9
;
KernelJump
->
Addr
=
(
UINT32
)(
UINTN
)
AsmAppleMapPlatformPrepareKernelState
;
KernelJump
->
CallInst
=
0xD1FF
;
}
Library/OcBootManagementLib/BootArguments.c
浏览文件 @
7eca5966
...
...
@@ -12,11 +12,14 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Guid/AppleVariable.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcMiscLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
VOID
OcParseBootArgs
(
...
...
@@ -151,3 +154,76 @@ OcAppendArgumentToCmd (
AsciiStrnCpyS
(
CommandLine
,
ArgumentLength
+
1
,
Argument
,
ArgumentLength
+
1
);
return
TRUE
;
}
BOOLEAN
OcCheckArgumentFromEnv
(
IN
EFI_LOADED_IMAGE
*
LoadedImage
OPTIONAL
,
IN
EFI_GET_VARIABLE
GetVariable
OPTIONAL
,
IN
CONST
CHAR8
*
Argument
,
IN
CONST
UINTN
ArgumentLength
)
{
CHAR16
*
Options
;
UINTN
OptionsSize
;
CHAR8
BootArgsVar
[
BOOT_LINE_LENGTH
];
UINTN
BootArgsVarLen
;
EFI_STATUS
Status
;
UINTN
LastIndex
;
CHAR16
Last
;
BOOLEAN
HasArgument
;
HasArgument
=
FALSE
;
if
(
LoadedImage
!=
NULL
)
{
Options
=
(
CHAR16
*
)
LoadedImage
->
LoadOptions
;
OptionsSize
=
LoadedImage
->
LoadOptionsSize
/
sizeof
(
CHAR16
);
if
(
Options
!=
NULL
&&
OptionsSize
>
0
)
{
//
// Just in case we do not have 0-termination.
// This may cut some data with unexpected options, but it is not like we care.
//
LastIndex
=
OptionsSize
-
1
;
Last
=
Options
[
LastIndex
];
Options
[
LastIndex
]
=
'\0'
;
UnicodeStrToAsciiStrS
(
Options
,
BootArgsVar
,
BOOT_LINE_LENGTH
);
if
(
OcGetArgumentFromCmd
(
BootArgsVar
,
Argument
,
ArgumentLength
))
{
HasArgument
=
TRUE
;
}
//
// Options do not belong to us, restore the changed value.
//
Options
[
LastIndex
]
=
Last
;
}
}
if
(
!
HasArgument
)
{
//
// Important to avoid triggering boot-args wrapper too early if we have any.
//
BootArgsVarLen
=
sizeof
(
BootArgsVar
);
Status
=
(
GetVariable
!=
NULL
?
GetVariable
:
gRT
->
GetVariable
)
(
L"boot-args"
,
&
gAppleBootVariableGuid
,
NULL
,
&
BootArgsVarLen
,
BootArgsVar
);
if
(
!
EFI_ERROR
(
Status
)
&&
BootArgsVarLen
>
0
)
{
//
// Just in case we do not have 0-termination
//
BootArgsVar
[
BootArgsVarLen
-
1
]
=
'\0'
;
if
(
OcGetArgumentFromCmd
(
BootArgsVar
,
Argument
,
ArgumentLength
))
{
HasArgument
=
TRUE
;
}
}
}
return
HasArgument
;
}
Library/OcBootManagementLib/OcBootManagementLib.c
浏览文件 @
7eca5966
...
...
@@ -601,6 +601,59 @@ OcActivateHibernateWake (
return
EFI_NOT_FOUND
;
}
BOOLEAN
OcIsAppleHibernateWake
(
VOID
)
{
EFI_STATUS
Status
;
UINTN
ValueSize
;
//
// This is reverse engineered from boot.efi.
// To cancel hibernate wake it is enough to delete the variables.
// Starting with 10.13.6 boot-switch-vars is no longer supported.
//
ValueSize
=
0
;
Status
=
gRT
->
GetVariable
(
L"boot-signature"
,
&
gAppleBootVariableGuid
,
NULL
,
&
ValueSize
,
NULL
);
if
(
Status
==
EFI_BUFFER_TOO_SMALL
)
{
ValueSize
=
0
;
Status
=
gRT
->
GetVariable
(
L"boot-image-key"
,
&
gAppleBootVariableGuid
,
NULL
,
&
ValueSize
,
NULL
);
if
(
Status
==
EFI_BUFFER_TOO_SMALL
)
{
return
TRUE
;
}
}
else
{
ValueSize
=
0
;
Status
=
gRT
->
GetVariable
(
L"boot-switch-vars"
,
&
gAppleBootVariableGuid
,
NULL
,
&
ValueSize
,
NULL
);
if
(
Status
==
EFI_BUFFER_TOO_SMALL
)
{
return
TRUE
;
}
}
return
TRUE
;
}
EFI_STATUS
OcShowSimpleBootMenu
(
IN
OC_BOOT_ENTRY
*
BootEntries
,
...
...
Library/OcMemoryLib/VirtualMemory.c
浏览文件 @
7eca5966
...
...
@@ -160,8 +160,6 @@ VmAllocateMemoryPool (
if
(
!
EFI_ERROR
(
Status
))
{
Context
->
MemoryPool
=
(
UINT8
*
)
Addr
;
Context
->
FreePages
=
NumPages
;
}
else
{
DEBUG
((
DEBUG_ERROR
,
"OCVM: memory pool allocation failure - %r
\n
"
,
Status
));
}
return
Status
;
...
...
@@ -181,8 +179,6 @@ VmAllocatePages (
AllocatedPages
=
Context
->
MemoryPool
;
Context
->
MemoryPool
+=
EFI_PAGES_TO_SIZE
(
NumPages
);
Context
->
FreePages
-=
NumPages
;
}
else
{
DEBUG
((
DEBUG_ERROR
,
"OCVM: memory pool out of free pages
\n
"
));
}
return
AllocatedPages
;
...
...
Library/OcMiscLib/DirectReset.c
0 → 100644
浏览文件 @
7eca5966
/** @file
Reset System Library functions for OVMF
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
VOID
DirectRestCold
(
VOID
)
{
volatile
UINTN
Index
;
IoWrite8
(
0xCF9
,
BIT2
|
BIT1
);
// 1st choice: PIIX3 RCR, RCPU|SRST
for
(
Index
=
0
;
Index
<
100
;
++
Index
)
{
;
}
IoWrite8
(
0x64
,
0xfe
);
// 2nd choice: keyboard controller
CpuDeadLoop
();
}
Library/OcMiscLib/OcMiscLib.inf
浏览文件 @
7eca5966
...
...
@@ -46,6 +46,7 @@
[Sources]
Base64Decode.c
DataPatcher.c
DirectReset.c
ReleaseUsbOwnership.c
NullTextOutput.c
UninstallAllProtocolInterfaces.c
OcSupportPkg.dec
浏览文件 @
7eca5966
...
...
@@ -41,6 +41,9 @@
## Include/Protocol/OcLog.h
gOcLogProtocolGuid = { 0xDBB6008F, 0x89E4, 0x4272, { 0x98, 0x81, 0xCE, 0x3A, 0xFD, 0x97, 0x24, 0xD0 }}
# Include/Protocol/OcAppleBootCompat.h
gOcAppleBootCompatProtocolGuid = { 0xC7CBA84E, 0xCC77, 0x461D, { 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } }
## Include/Protocol/OcFirmwareRuntime.h
gOcFirmwareRuntimeProtocolGuid = { 0x9C820F96, 0xF16C, 0x4FFD, { 0xB2, 0x66, 0xDF, 0x0A, 0x8F, 0xDF, 0xC4, 0x55 }}
...
...
@@ -74,6 +77,9 @@
## @libraryclass
OcAcpiLib|Include/Library/OcAcpiLib.h
## @libraryclass
OcAppleBootCompatLib|Include/Library/OcAppleBootCompatLib.h
## @libraryclass
OcAppleBootPolicyLib|Include/Library/OcAppleBootPolicyLib.h
...
...
OcSupportPkg.dsc
浏览文件 @
7eca5966
...
...
@@ -51,6 +51,7 @@
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
OcAcpiLib|OcSupportPkg/Library/OcAcpiLib/OcAcpiLib.inf
OcAppleBootCompatLib|OcSupportPkg/Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf
OcAppleBootPolicyLib|OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf
OcAppleChunklistLib|OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
OcAppleDiskImageLib|OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf
...
...
@@ -85,6 +86,7 @@
[Components]
OcSupportPkg/Library/OcAcpiLib/OcAcpiLib.inf
OcSupportPkg/Library/OcAppleBootCompatLib/OcAppleBootCompatLib.inf
OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf
OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录