Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
258fb83e
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,发现更多精彩内容 >>
未验证
提交
258fb83e
编写于
11月 13, 2020
作者:
V
Vitaly Cheptsov
提交者:
GitHub
11月 13, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcAfterBootCompatLib: Implement relocation block support (#153)
closes acidanthera/bugtracker#1125
上级
e8cc05f5
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
756 addition
and
12 deletion
+756
-12
Changelog.md
Changelog.md
+1
-0
Docs/Configuration.pdf
Docs/Configuration.pdf
+0
-0
Docs/Configuration.tex
Docs/Configuration.tex
+30
-0
Docs/Differences/Differences.pdf
Docs/Differences/Differences.pdf
+0
-0
Docs/Differences/Differences.tex
Docs/Differences/Differences.tex
+36
-2
Docs/Errata/Errata.pdf
Docs/Errata/Errata.pdf
+0
-0
Docs/Sample.plist
Docs/Sample.plist
+2
-0
Docs/SampleCustom.plist
Docs/SampleCustom.plist
+2
-0
Include/Acidanthera/Library/OcAfterBootCompatLib.h
Include/Acidanthera/Library/OcAfterBootCompatLib.h
+5
-0
Include/Acidanthera/Library/OcBootManagementLib.h
Include/Acidanthera/Library/OcBootManagementLib.h
+4
-0
Include/Acidanthera/Library/OcConfigurationLib.h
Include/Acidanthera/Library/OcConfigurationLib.h
+1
-0
Library/OcAfterBootCompatLib/BootCompatInternal.h
Library/OcAfterBootCompatLib/BootCompatInternal.h
+130
-0
Library/OcAfterBootCompatLib/CustomSlide.c
Library/OcAfterBootCompatLib/CustomSlide.c
+39
-2
Library/OcAfterBootCompatLib/KernelSupport.c
Library/OcAfterBootCompatLib/KernelSupport.c
+41
-1
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c
+2
-1
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf
+2
-0
Library/OcAfterBootCompatLib/RelocationBlock.c
Library/OcAfterBootCompatLib/RelocationBlock.c
+333
-0
Library/OcAfterBootCompatLib/RelocationCallGate.h
Library/OcAfterBootCompatLib/RelocationCallGate.h
+2
-0
Library/OcAfterBootCompatLib/RelocationCallGate.nasm
Library/OcAfterBootCompatLib/RelocationCallGate.nasm
+87
-0
Library/OcAfterBootCompatLib/ServiceOverrides.c
Library/OcAfterBootCompatLib/ServiceOverrides.c
+29
-6
Library/OcBootManagementLib/BootArguments.c
Library/OcBootManagementLib/BootArguments.c
+8
-0
Library/OcConfigurationLib/OcConfigurationLib.c
Library/OcConfigurationLib/OcConfigurationLib.c
+1
-0
Platform/OpenCore/OpenCoreUefi.c
Platform/OpenCore/OpenCoreUefi.c
+1
-0
未找到文件。
Changelog.md
浏览文件 @
258fb83e
...
...
@@ -11,6 +11,7 @@ OpenCore Changelog
-
Updated builtin firmware versions for SMBIOS and the rest
-
Fixed ACPI patches not applying if tables are in locked memory
-
Fixed
`EnableSafeModeSlide`
on macOS 11.0
-
Added
`AllowRelocationBlock`
quirk for older macOS and safe mode
#### v0.6.3
-
Added support for xml comments in plist files
...
...
Docs/Configuration.pdf
浏览文件 @
258fb83e
无法预览此类型文件
Docs/Configuration.tex
浏览文件 @
258fb83e
...
...
@@ -1308,6 +1308,36 @@ To view their current state use \texttt{pmset -g} command in Terminal.
\begin{enumerate}
\item
\texttt
{
AllowRelocationBlock
}
\\
\textbf
{
Type
}
:
\texttt
{
plist
\
boolean
}
\\
\textbf
{
Failsafe
}
:
\texttt
{
false
}
\\
\textbf
{
Description
}
: Allows booting macOS through a relocation block.
Relocation block is a scratch buffer allocated in lower 4 GB to be used for
loading the kernel and related structures by EfiBoot on firmwares where
lower memory is otherwise occupied by the (assumed to be) non-runtime data.
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. Relocation block can be used when:
\begin{itemize}
\tightlist
\item
No better slide exists (all the memory is used)
\item
\texttt
{
slide=0
}
is forced (by an argument or safe mode)
\item
KASLR (slide) is unsupported (this is macOS 10.7 or older)
\end{itemize}
This quirk requires
\texttt
{
ProvideCustomSlide
}
to also be enabled
and generally needs
\texttt
{
AvoidRuntimeDefrag
}
to work correctly.
Hibernation is not supported when booting with a relocation block
(but relocation block is not always used when the quirk is enabled).
\emph
{
Note
}
: While this quirk is required to run older macOS versions
on platforms with used lower memory it is not compatible with some
hardware and macOS 11. In this case you may try to use
\texttt
{
EnableSafeModeSlide
}
instead.
\item
\texttt
{
AvoidRuntimeDefrag
}
\\
\textbf
{
Type
}
:
\texttt
{
plist
\
boolean
}
\\
...
...
Docs/Differences/Differences.pdf
浏览文件 @
258fb83e
无法预览此类型文件
Docs/Differences/Differences.tex
浏览文件 @
258fb83e
\documentclass
[]
{
article
}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL PreviousConfiguration.tex Wed Nov 4 05:07:23 2020
%DIF ADD ../Configuration.tex
Sat Nov 7 17:18:06
2020
%DIF ADD ../Configuration.tex
Fri Nov 13 19:29:14
2020
\usepackage
{
lmodern
}
\usepackage
{
amssymb,amsmath
}
...
...
@@ -1369,7 +1369,41 @@ To view their current state use \texttt{pmset -g} command in Terminal.
\begin{enumerate}
\item
\texttt
{
AvoidRuntimeDefrag
}
\\
\DIFaddbegin
\texttt
{
\DIFadd
{
AllowRelocationBlock
}}
\\
\textbf
{
\DIFadd
{
Type
}}
\DIFadd
{
:
}
\texttt
{
\DIFadd
{
plist
\
boolean
}}
\\
\textbf
{
\DIFadd
{
Failsafe
}}
\DIFadd
{
:
}
\texttt
{
\DIFadd
{
false
}}
\\
\textbf
{
\DIFadd
{
Description
}}
\DIFadd
{
: Allows booting macOS through a relocation block.
}
\DIFadd
{
Relocation block is a scratch buffer allocated in lower 4 GB to be used for
loading the kernel and related structures by EfiBoot on firmwares where
lower memory is otherwise occupied by the (assumed to be) non-runtime data.
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. Relocation block can be used when:
}
\begin{itemize}
\tightlist
\item
\DIFadd
{
No better slide exists (all the memory is used)
}
\item
\texttt
{
\DIFadd
{
slide=0
}}
\DIFadd
{
is forced (by an argument or safe mode)
}
\item
\DIFadd
{
KASLR (slide) is unsupported (this is macOS 10.7 or older)
}
\end{itemize}
\DIFadd
{
This quirk requires
}
\texttt
{
\DIFadd
{
ProvideCustomSlide
}}
\DIFadd
{
to also be enabled
and generally needs
}
\DIFaddend
\texttt
{
AvoidRuntimeDefrag
}
\DIFaddbegin
\DIFadd
{
to work correctly.
Hibernation is not supported when booting with a relocation block
(but relocation block is not always used when the quirk is enabled).
}
\emph
{
\DIFadd
{
Note
}}
\DIFadd
{
: While this quirk is required to run older macOS versions
on platforms with used lower memory it is not compatible with some
hardware and macOS 11. In this case you may try to use
}
\texttt
{
\DIFadd
{
EnableSafeModeSlide
}}
\DIFadd
{
instead.
}
\item
\texttt
{
\DIFadd
{
AvoidRuntimeDefrag
}}
\DIFaddend
\\
\textbf
{
Type
}
:
\texttt
{
plist
\
boolean
}
\\
\textbf
{
Failsafe
}
:
\texttt
{
false
}
\\
\textbf
{
Description
}
: Protect from boot.efi runtime memory defragmentation.
...
...
Docs/Errata/Errata.pdf
浏览文件 @
258fb83e
无法预览此类型文件
Docs/Sample.plist
浏览文件 @
258fb83e
...
...
@@ -242,6 +242,8 @@
</array>
<key>
Quirks
</key>
<dict>
<key>
AllowRelocationBlock
</key>
<false/>
<key>
AvoidRuntimeDefrag
</key>
<true/>
<key>
DevirtualiseMmio
</key>
...
...
Docs/SampleCustom.plist
浏览文件 @
258fb83e
...
...
@@ -242,6 +242,8 @@
</array>
<key>
Quirks
</key>
<dict>
<key>
AllowRelocationBlock
</key>
<false/>
<key>
AvoidRuntimeDefrag
</key>
<true/>
<key>
DevirtualiseMmio
</key>
...
...
Include/Acidanthera/Library/OcAfterBootCompatLib.h
浏览文件 @
258fb83e
...
...
@@ -59,6 +59,11 @@ typedef struct OC_ABC_SETTINGS_ {
///
BOOLEAN
EnableSafeModeSlide
;
///
/// Try to relocate memory to different address space when KASLR is disabled
/// and lower memory is unavailable.
///
BOOLEAN
AllowRelocationBlock
;
///
/// Attempt to protect certain memory regions from being incorrectly mapped:
/// - CSM region could get used by the kernel due to being BS data,
/// which caused caused wake issues on older firmware.
...
...
Include/Acidanthera/Library/OcBootManagementLib.h
浏览文件 @
258fb83e
...
...
@@ -1099,6 +1099,10 @@ typedef struct OC_BOOT_ARGUMENTS_ {
UINT32
*
MemoryMapDescriptorSize
;
UINT32
*
MemoryMapDescriptorVersion
;
CHAR8
*
CommandLine
;
UINT32
*
KernelAddrP
;
UINT32
*
SystemTableP
;
UINT32
*
RuntimeServicesPG
;
UINT64
*
RuntimeServicesV
;
UINT32
*
DeviceTreeP
;
UINT32
*
DeviceTreeLength
;
UINT32
*
CsrActiveConfig
;
...
...
Include/Acidanthera/Library/OcConfigurationLib.h
浏览文件 @
258fb83e
...
...
@@ -112,6 +112,7 @@
OC_DECLARE
(
OC_BOOTER_WL_ARRAY
)
#define OC_BOOTER_QUIRKS_FIELDS(_, __) \
_(BOOLEAN , AllowRelocationBlock , , FALSE , ()) \
_(BOOLEAN , AvoidRuntimeDefrag , , FALSE , ()) \
_(BOOLEAN , DevirtualiseMmio , , FALSE , ()) \
_(BOOLEAN , DisableSingleUser , , FALSE , ()) \
...
...
Library/OcAfterBootCompatLib/BootCompatInternal.h
浏览文件 @
258fb83e
...
...
@@ -52,6 +52,11 @@
**/
#define RT_DESC_ENTRY_NUM ((UINTN) 64)
/**
Kernel static vaddr mapping base.
**/
#define KERNEL_STATIC_VADDR ((UINT64) 0xFFFFFF8000000000ULL)
/**
Kernel __HIB segment virtual address.
**/
...
...
@@ -103,6 +108,8 @@
/**
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
...
...
@@ -133,6 +140,18 @@ UINTN
IN
UINTN
EntryPoint
);
/**
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.
**/
...
...
@@ -301,6 +320,24 @@ typedef struct KERNEL_SUPPORT_STATE_ {
/// 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 firmwares where
/// lower memory is otherwise occupied (assumed to be) 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
;
}
KERNEL_SUPPORT_STATE
;
/**
...
...
@@ -535,4 +572,97 @@ AppleSlideRestore (
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] BootCompat Boot compatibility context.
@param[in] Args Case-specific kernel argument handle.
@param[in] CallGate Kernel call gate address.
@param[in] EntryPoint Case-specific kernel entry point.
@returns Case-specific value if any.
**/
UINTN
AppleRelocationCallGate
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
KERNEL_CALL_GATE
CallGate
,
IN
UINTN
Args
,
IN
UINTN
EntryPoint
);
#endif // BOOT_COMPAT_INTERNAL_H
Library/OcAfterBootCompatLib/CustomSlide.c
浏览文件 @
258fb83e
...
...
@@ -801,8 +801,9 @@ AppleSlideGetVariable (
Data
);
}
else
if
(
StrCmp
(
VariableName
,
L"boot-args"
)
==
0
&&
!
BootCompat
->
ServiceState
.
AppleCustomSlide
&&
ShouldUseCustomSlideOffset
(
&
BootCompat
->
SlideSupport
,
GetMemoryMap
,
FilterMap
,
FilterMapContext
))
{
&&
(
!
BootCompat
->
ServiceState
.
AppleCustomSlide
||
BootCompat
->
Settings
.
AllowRelocationBlock
)
&&
ShouldUseCustomSlideOffset
(
&
BootCompat
->
SlideSupport
,
GetMemoryMap
,
FilterMap
,
FilterMapContext
)
&&
!
BootCompat
->
ServiceState
.
AppleCustomSlide
)
{
//
// When we cannot allow some KASLR values due to used address we generate
// a random slide value among the valid options, which we we pass via boot-args.
...
...
@@ -815,6 +816,9 @@ AppleSlideGetVariable (
// on the only (so far) problematic X99 and X299 we have no free region for our pool anyway.
// In any case, the current APTIOFIX_SPECULATED_KERNEL_SIZE value appears to work reliably.
//
// Note, when relocation block support is enabled, we always do the slide analysis
// (even when slide=0 is requested) to understand whether we need it or not at a later stage.
//
return
GetVariableBootArgs
(
&
BootCompat
->
SlideSupport
,
GetVariable
,
...
...
@@ -854,3 +858,36 @@ AppleSlideRestore (
//
HideSlideFromOs
(
SlideSupport
,
BootArgs
);
}
UINTN
AppleSlideGetRelocationSize
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
)
{
SLIDE_SUPPORT_STATE
*
SlideSupport
;
SlideSupport
=
&
BootCompat
->
SlideSupport
;
//
// When we could not have performed the analysis we have nothing to offer.
//
if
(
!
SlideSupport
->
HasMemoryMapAnalysis
)
{
return
0
;
}
//
// When we have no slides available we assume 0 is also unavailable.
//
if
(
SlideSupport
->
ValidSlideCount
==
0
)
{
return
BootCompat
->
SlideSupport
.
EstimatedKernelArea
;
}
//
// If the first slide is not zero, then zero is unavailable.
//
if
(
SlideSupport
->
ValidSlides
[
0
]
!=
0
)
{
return
BootCompat
->
SlideSupport
.
EstimatedKernelArea
;
}
return
0
;
}
Library/OcAfterBootCompatLib/KernelSupport.c
浏览文件 @
258fb83e
...
...
@@ -366,6 +366,20 @@ AppleMapPrepareForBooting (
}
}
if
(
BootCompat
->
KernelState
.
RelocationBlock
!=
0
)
{
//
// When using Relocation Block EfiBoot will not virtualize the addresses since they
// cannot be mapped 1:1 due to any region from the relocation block being outside
// of static XNU vaddr to paddr mapping. This causes a clean early exit in their
// SetVirtualAddressMap calling routine avoiding gRT->SetVirtualAddressMap.
//
// For this reason we need to perform it ourselves right here before we restored
// runtime memory protections as we also need to defragment EFI_SYSTEM_TABLE memory
// to be accessible from XNU.
//
AppleRelocationVirtualize
(
BootCompat
,
&
BA
);
}
if
(
BootCompat
->
Settings
.
AvoidRuntimeDefrag
)
{
MemoryMapSize
=
*
BA
.
MemoryMapSize
;
MemoryMap
=
(
EFI_MEMORY_DESCRIPTOR
*
)(
UINTN
)
(
*
BA
.
MemoryMap
);
...
...
@@ -401,6 +415,10 @@ AppleMapPrepareForBooting (
);
}
}
if
(
BootCompat
->
KernelState
.
RelocationBlock
!=
0
)
{
AppleRelocationRebase
(
BootCompat
,
&
BA
);
}
}
/**
...
...
@@ -462,6 +480,11 @@ AppleMapPrepareForHibernateWake (
return
;
}
//
// TODO: If we try to work on hibernation support with relocation block
// We will need to add a call similar to AppleRelocationVirtualize here.
//
if
(
BootCompat
->
Settings
.
AvoidRuntimeDefrag
)
{
//
// I think we should not be there, but ideally all quirks are relatively independent.
...
...
@@ -480,6 +503,11 @@ AppleMapPrepareForHibernateWake (
Handoff
=
(
IOHibernateHandoff
*
)
((
UINTN
)
Handoff
+
sizeof
(
Handoff
)
+
Handoff
->
bytecount
);
}
//
// TODO: To support hibernation with relocation block we will need to add a call similar
// to AppleRelocationRebase here.
//
}
VOID
...
...
@@ -582,7 +610,9 @@ AppleMapPrepareKernelJump (
//
// There is no reason to patch the kernel when we do not need it.
//
if
(
!
BootCompat
->
Settings
.
AvoidRuntimeDefrag
&&
!
BootCompat
->
Settings
.
DiscardHibernateMap
)
{
if
(
!
BootCompat
->
Settings
.
AvoidRuntimeDefrag
&&
!
BootCompat
->
Settings
.
DiscardHibernateMap
&&
!
BootCompat
->
Settings
.
AllowRelocationBlock
)
{
return
;
}
...
...
@@ -701,5 +731,15 @@ AppleMapPrepareKernelState (
CallGate
=
(
KERNEL_CALL_GATE
)(
UINTN
)
(
BootCompatContext
->
ServiceState
.
KernelCallGate
+
CALL_GATE_JUMP_SIZE
);
if
(
BootCompatContext
->
KernelState
.
RelocationBlock
!=
0
)
{
return
AppleRelocationCallGate
(
BootCompatContext
,
CallGate
,
Args
,
EntryPoint
);
}
return
CallGate
(
Args
,
EntryPoint
);
}
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c
浏览文件 @
258fb83e
...
...
@@ -111,7 +111,8 @@ OcAbcInitialize (
DEBUG
((
DEBUG_INFO
,
"OCABC: RTDFRG %d DEVMMIO %d NOSU %d NOVRWR %d NOSB %d NOHBMAP %d SMSLIDE %d WRUNPROT %d
\n
"
,
"OCABC: ALRBL %d RTDFRG %d DEVMMIO %d NOSU %d NOVRWR %d NOSB %d NOHBMAP %d SMSLIDE %d WRUNPROT %d
\n
"
,
Settings
->
AllowRelocationBlock
,
Settings
->
AvoidRuntimeDefrag
,
Settings
->
DevirtualiseMmio
,
Settings
->
DisableSingleUser
,
...
...
Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf
浏览文件 @
258fb83e
...
...
@@ -35,6 +35,8 @@
CustomSlide.c
KernelSupport.c
OcAfterBootCompatLib.c
RelocationBlock.c
RelocationCallGate.h
ServiceOverrides.c
[Packages]
...
...
Library/OcAfterBootCompatLib/RelocationBlock.c
0 → 100644
浏览文件 @
258fb83e
/** @file
Copyright (C) 2013, dmazar. All rights reserved.
Copyright (C) 2020, 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 <Guid/OcVariable.h>
#include <IndustryStandard/AppleHibernate.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcDeviceTreeLib.h>
#include <Library/OcMachoLib.h>
#include <Library/OcMemoryLib.h>
#include <Library/OcMiscLib.h>
#include <Library/OcStringLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
STATIC
CONST
UINT8
mAsmRelocationCallGate
[]
=
{
#include "RelocationCallGate.h"
};
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
)
{
EFI_STATUS
Status
;
UINTN
EssentialSize
;
EssentialSize
=
AppleSlideGetRelocationSize
(
BootCompat
);
if
(
EssentialSize
==
0
)
{
return
EFI_UNSUPPORTED
;
}
//
// Operating systems up to macOS 10.15 allocate starting with TEXT segment (2MB).
// macOS 11.0 allocates starting with HIB segment (1MB), but it does not support
// this quirk anyway due to AllocatePages in AllocateAddress mode Address pointer
// no longer being reread after the allocation in EfiBoot.
//
if
(
*
Memory
==
KERNEL_TEXT_PADDR
&&
BootCompat
->
KernelState
.
RelocationBlock
==
0
)
{
BootCompat
->
KernelState
.
RelocationBlock
=
BASE_4GB
;
Status
=
OcAllocatePagesFromTop
(
EfiLoaderData
,
EFI_SIZE_TO_PAGES
(
EssentialSize
),
&
BootCompat
->
KernelState
.
RelocationBlock
,
GetMemoryMap
,
AllocatePages
,
NULL
);
if
(
EFI_ERROR
(
Status
))
{
DEBUG
((
DEBUG_INFO
,
"OCABC: Relocation block (0x%Lx) allocation failure - %r
\n
"
,
EssentialSize
,
Status
));
return
Status
;
}
BootCompat
->
KernelState
.
RelocationBlockUsed
=
0
;
}
//
// Not our allocation.
//
if
(
BootCompat
->
KernelState
.
RelocationBlock
==
0
||
*
Memory
<
KERNEL_BASE_PADDR
||
*
Memory
>=
KERNEL_BASE_PADDR
+
EssentialSize
)
{
return
EFI_INVALID_PARAMETER
;
}
//
// Track actually occupied memory.
//
EssentialSize
=
(
UINTN
)
(
*
Memory
-
KERNEL_BASE_PADDR
+
EFI_PAGES_TO_SIZE
(
NumberOfPages
));
if
(
EssentialSize
>
BootCompat
->
KernelState
.
RelocationBlockUsed
)
{
BootCompat
->
KernelState
.
RelocationBlockUsed
=
EssentialSize
;
}
//
// Assume that EfiBoot does not try to reallocate memory.
//
*
Memory
=
*
Memory
-
KERNEL_BASE_PADDR
+
BootCompat
->
KernelState
.
RelocationBlock
;
return
EFI_SUCCESS
;
}
EFI_STATUS
AppleRelocationRelease
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
)
{
EFI_STATUS
Status
;
UINTN
EssentialSize
;
EssentialSize
=
AppleSlideGetRelocationSize
(
BootCompat
);
if
(
EssentialSize
==
0
)
{
return
EFI_UNSUPPORTED
;
}
if
(
BootCompat
->
KernelState
.
RelocationBlock
==
0
)
{
return
EFI_INVALID_PARAMETER
;
}
Status
=
gBS
->
FreePages
(
BootCompat
->
KernelState
.
RelocationBlock
,
EFI_SIZE_TO_PAGES
(
EssentialSize
)
);
BootCompat
->
KernelState
.
RelocationBlock
=
0
;
BootCompat
->
KernelState
.
RelocationBlockUsed
=
0
;
return
Status
;
}
EFI_STATUS
AppleRelocationVirtualize
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
OUT
OC_BOOT_ARGUMENTS
*
BA
)
{
EFI_STATUS
Status
;
UINTN
MemoryMapSize
;
UINTN
DescriptorSize
;
UINT32
DescriptorVersion
;
EFI_MEMORY_DESCRIPTOR
*
MemoryMap
;
EFI_PHYSICAL_ADDRESS
KernelRTAddress
;
UINTN
NumEntries
;
UINTN
Index
;
EFI_MEMORY_DESCRIPTOR
*
Desc
;
UINTN
BlockSize
;
UINT8
*
KernelRTBlock
;
MemoryMapSize
=
*
BA
->
MemoryMapSize
;
DescriptorSize
=
*
BA
->
MemoryMapDescriptorSize
;
DescriptorVersion
=
*
BA
->
MemoryMapDescriptorVersion
;
MemoryMap
=
(
EFI_MEMORY_DESCRIPTOR
*
)(
UINTN
)
*
BA
->
MemoryMap
;
KernelRTAddress
=
EFI_PAGES_TO_SIZE
(
*
BA
->
RuntimeServicesPG
)
-
(
UINT32
)
(
BootCompat
->
KernelState
.
RelocationBlock
-
KERNEL_BASE_PADDR
);
//
// (1) Assign virtual addresses to all runtime blocks (but reserved).
//
Desc
=
MemoryMap
;
NumEntries
=
MemoryMapSize
/
DescriptorSize
;
for
(
Index
=
0
;
Index
<
NumEntries
;
++
Index
)
{
BlockSize
=
EFI_PAGES_TO_SIZE
((
UINTN
)
Desc
->
NumberOfPages
);
if
(
Desc
->
Type
==
EfiReservedMemoryType
)
{
Desc
->
Attribute
&=
~
EFI_MEMORY_RUNTIME
;
}
else
if
((
Desc
->
Attribute
&
EFI_MEMORY_RUNTIME
)
!=
0
)
{
Desc
->
VirtualStart
=
KernelRTAddress
+
KERNEL_STATIC_VADDR
;
KernelRTAddress
+=
BlockSize
;
}
Desc
=
NEXT_MEMORY_DESCRIPTOR
(
Desc
,
DescriptorSize
);
}
//
// (2) Transition to virtual memory.
//
Status
=
gRT
->
SetVirtualAddressMap
(
MemoryMapSize
,
DescriptorSize
,
DescriptorVersion
,
MemoryMap
);
//
// (3) Perform quick dirty defragmentation similarly to EfiBoot to make vaddr = paddr
// for critical areas like EFI_SYSTEM_TABLE.
//
Desc
=
MemoryMap
;
for
(
Index
=
0
;
Index
<
NumEntries
;
++
Index
)
{
if
(
Desc
->
Type
==
EfiRuntimeServicesCode
||
Desc
->
Type
==
EfiRuntimeServicesData
)
{
//
// Get physical address from statically mapped virtual.
//
KernelRTBlock
=
(
UINT8
*
)(
UINTN
)
(
Desc
->
VirtualStart
&
(
BASE_1GB
-
1
));
BlockSize
=
EFI_PAGES_TO_SIZE
((
UINTN
)
Desc
->
NumberOfPages
);
CopyMem
(
KernelRTBlock
+
(
BootCompat
->
KernelState
.
RelocationBlock
-
KERNEL_BASE_PADDR
),
(
VOID
*
)(
UINTN
)
Desc
->
PhysicalStart
,
BlockSize
);
ZeroMem
((
VOID
*
)(
UINTN
)
Desc
->
PhysicalStart
,
BlockSize
);
//
// (4) Sync changes to EFI_SYSTEM_TABLE location with boot args.
//
if
(
Desc
->
PhysicalStart
<=
*
BA
->
SystemTableP
&&
*
BA
->
SystemTableP
<=
LAST_DESCRIPTOR_ADDR
(
Desc
))
{
*
BA
->
SystemTableP
=
(
UINT32
)((
UINTN
)
KernelRTBlock
+
(
*
BA
->
SystemTableP
-
Desc
->
PhysicalStart
)
+
(
BootCompat
->
KernelState
.
RelocationBlock
-
KERNEL_BASE_PADDR
));
}
//
// Mark old RT block in MemMap as free memory and remove RT attribute.
//
Desc
->
Type
=
EfiConventionalMemory
;
Desc
->
Attribute
=
Desc
->
Attribute
&
(
~
EFI_MEMORY_RUNTIME
);
}
Desc
=
NEXT_MEMORY_DESCRIPTOR
(
Desc
,
DescriptorSize
);
}
return
Status
;
}
VOID
AppleRelocationRebase
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
OUT
OC_BOOT_ARGUMENTS
*
BA
)
{
EFI_STATUS
Status
;
DTEntry
MemMap
;
CHAR8
*
PropName
;
DTMemMapEntry
*
PropValue
;
OpaqueDTPropertyIterator
OPropIter
;
DTPropertyIterator
PropIter
;
UINT32
RelocDiff
;
PropIter
=
&
OPropIter
;
RelocDiff
=
(
UINT32
)
(
BootCompat
->
KernelState
.
RelocationBlock
-
KERNEL_BASE_PADDR
);
DTInit
((
DTEntry
)(
UINTN
)
*
BA
->
DeviceTreeP
,
BA
->
DeviceTreeLength
);
Status
=
DTLookupEntry
(
NULL
,
"/chosen/memory-map"
,
&
MemMap
);
if
(
!
EFI_ERROR
(
Status
))
{
Status
=
DTCreatePropertyIterator
(
MemMap
,
&
OPropIter
);
if
(
!
EFI_ERROR
(
Status
))
{
while
(
!
EFI_ERROR
(
DTIterateProperties
(
PropIter
,
&
PropName
)))
{
//
// /chosen/memory-map props have DTMemMapEntry values (address, length).
// We need to correct the addresses in matching types.
//
//
// Filter entries with different size right away.
//
if
(
PropIter
->
CurrentProperty
->
Length
!=
sizeof
(
DTMemMapEntry
))
{
continue
;
}
//
// Filter enteries out of the relocation range.
//
PropValue
=
(
DTMemMapEntry
*
)((
UINT8
*
)
PropIter
->
CurrentProperty
+
sizeof
(
DTProperty
));
if
(
PropValue
->
Address
<
BootCompat
->
KernelState
.
RelocationBlock
||
PropValue
->
Address
>=
BootCompat
->
KernelState
.
RelocationBlock
+
BootCompat
->
KernelState
.
RelocationBlockUsed
)
{
continue
;
}
//
// Patch the addresses up.
//
PropValue
->
Address
-=
RelocDiff
;
}
}
}
*
BA
->
MemoryMap
-=
RelocDiff
;
*
BA
->
KernelAddrP
-=
RelocDiff
;
*
BA
->
SystemTableP
-=
RelocDiff
;
*
BA
->
RuntimeServicesPG
-=
EFI_SIZE_TO_PAGES
(
RelocDiff
);
//
// Note, this one does not seem to be used by XNU but we set it anyway.
//
*
BA
->
RuntimeServicesV
=
EFI_PAGES_TO_SIZE
(
*
BA
->
RuntimeServicesPG
)
+
KERNEL_STATIC_VADDR
;
*
BA
->
DeviceTreeP
-=
RelocDiff
;
}
UINTN
AppleRelocationCallGate
(
IN
OUT
BOOT_COMPAT_CONTEXT
*
BootCompat
,
IN
KERNEL_CALL_GATE
CallGate
,
IN
UINTN
Args
,
IN
UINTN
EntryPoint
)
{
UINT8
*
Payload
;
RELOCATION_CALL_GATE
ReloGate
;
//
// Shift kernel arguments back.
//
Args
-=
(
UINTN
)
(
BootCompat
->
KernelState
.
RelocationBlock
-
KERNEL_BASE_PADDR
);
//
// Provide copying payload that will not be overwritten.
//
Payload
=
(
VOID
*
)(
UINTN
)
CallGate
;
Payload
+=
ESTIMATED_CALL_GATE_SIZE
;
CopyMem
(
Payload
,
mAsmRelocationCallGate
,
sizeof
(
mAsmRelocationCallGate
));
//
// Transition to payload.
//
ReloGate
=
(
RELOCATION_CALL_GATE
)(
UINTN
)
Payload
;
return
ReloGate
(
BootCompat
->
KernelState
.
RelocationBlockUsed
/
sizeof
(
UINT64
),
EntryPoint
,
BootCompat
->
KernelState
.
RelocationBlock
,
Args
);
}
Library/OcAfterBootCompatLib/RelocationCallGate.h
0 → 100644
浏览文件 @
258fb83e
0xfa
,
0xfc
,
0x4c
,
0x89
,
0xc6
,
0xbf
,
0x00
,
0x00
,
0x10
,
0x00
,
0xf3
,
0x48
,
0xa5
,
0x48
,
0x89
,
0xf4
,
0x4c
,
0x89
,
0xc9
,
0xe9
,
0xe8
,
0xfe
,
0xff
,
0xff
Library/OcAfterBootCompatLib/RelocationCallGate.nasm
0 → 100644
浏览文件 @
258fb83e
;------------------------------------------------------------------------------
; @file
; Copyright (C) 2020, 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
;------------------------------------------------------------------------------
; Copied from BootCompatInternal.h, keep in sync.
;------------------------------------------------------------------------------
%define ESTIMATED_CALL_GATE_SIZE 256
%define KERNEL_BASE_PADDR 0x100000
;------------------------------------------------------------------------------
; Copy kernel memory to lower memory and jump back to kernel call gate.
;
; To generate the binary blob execute the following command:
; nasm RelocationCallGate.nasm -o /dev/stdout | xxd -i > RelocationCallGate.h
;
; @param[in] QWordCount Number of QWORDS to copy (rcx).
; @param[in] EntryPoint Kernel entry point (rdx).
; @param[in] Source Relocation block address to copy from (r8).
; @param[in] Args Kernel arguments (r9).
;
; Kernel call gate resides ESTIMATED_CALL_GATE_SIZE above and expects
; Args (rcx), EntryPoint (rdx) arguments to be passed.
;
; UINTN
; EFIAPI
; AsmCopySelf (
; IN UINTN QWordCount,
; IN UINTN EntryPoint,
; IN EFI_PHYSICAL_ADDRESS Source,
; IN UINTN Args
; );
;------------------------------------------------------------------------------
AsmRelocationCallGate:
; Disable interrupts just in case UEFI timer kills us.
cli
; Perform copying with direction reset.
cld
mov rsi, r8
mov edi, KERNEL_BASE_PADDR
rep movsq
; Update stack pointer to point to the relocation block (just in case).
mov rsp, rsi
; Print K and die (useful for testing).
; mov cl, 0x4b
; mov dx, 0x3fd
;ready1:
; in al, dx
; test al, 0x20
; je ready1
; mov dx, 0x3f8
; mov al, cl
; out dx, al
; mov cl, 0xa
; mov dx, 0x3fd
;ready2:
; in al, dx
; test al, 0x20
; je ready2
; mov dx, 0x3f8
; mov al, cl
; out dx, al
;freeze:
; jmp freeze
; Move Args to the first argument.
mov rcx, r9
; Jump back to the Apple call gate.
jmp AsmRelocationCallGate - ESTIMATED_CALL_GATE_SIZE
Library/OcAfterBootCompatLib/ServiceOverrides.c
浏览文件 @
258fb83e
...
...
@@ -367,12 +367,31 @@ OcAllocatePages (
IsCallGateAlloc
=
TRUE
;
}
Status
=
BootCompat
->
ServicePtrs
.
AllocatePages
(
Type
,
MemoryType
,
NumberOfPages
,
Memory
);
if
(
BootCompat
->
Settings
.
AllowRelocationBlock
&&
BootCompat
->
ServiceState
.
AppleBootNestedCount
>
0
&&
Type
==
AllocateAddress
&&
MemoryType
==
EfiLoaderData
)
{
Status
=
AppleRelocationAllocatePages
(
BootCompat
,
BootCompat
->
ServicePtrs
.
GetMemoryMap
,
BootCompat
->
ServicePtrs
.
AllocatePages
,
NumberOfPages
,
Memory
);
}
else
{
Status
=
EFI_UNSUPPORTED
;
}
if
(
EFI_ERROR
(
Status
))
{
Status
=
BootCompat
->
ServicePtrs
.
AllocatePages
(
Type
,
MemoryType
,
NumberOfPages
,
Memory
);
}
DEBUG
((
DEBUG_VERBOSE
,
"OCABC: AllocPages %u 0x%Lx (%u) - %r
\n
"
,
Type
,
*
Memory
,
NumberOfPages
,
Status
));
if
(
!
EFI_ERROR
(
Status
))
{
FixRuntimeAttributes
(
BootCompat
,
MemoryType
);
...
...
@@ -761,6 +780,10 @@ OcStartImage (
// We failed but other operating systems should be loadable.
//
--
BootCompat
->
ServiceState
.
AppleBootNestedCount
;
if
(
BootCompat
->
ServiceState
.
AppleBootNestedCount
==
0
)
{
AppleRelocationRelease
(
BootCompat
);
}
}
return
Status
;
...
...
Library/OcBootManagementLib/BootArguments.c
浏览文件 @
258fb83e
...
...
@@ -45,6 +45,10 @@ OcParseBootArgs (
Arguments
->
CommandLine
=
&
BA1
->
CommandLine
[
0
];
Arguments
->
KernelAddrP
=
&
BA1
->
kaddr
;
Arguments
->
SystemTableP
=
&
BA1
->
efiSystemTable
;
Arguments
->
RuntimeServicesPG
=
&
BA1
->
efiRuntimeServicesPageStart
;
Arguments
->
RuntimeServicesV
=
&
BA1
->
efiRuntimeServicesVirtualPageStart
;
Arguments
->
DeviceTreeP
=
&
BA1
->
deviceTreeP
;
Arguments
->
DeviceTreeLength
=
&
BA1
->
deviceTreeLength
;
Arguments
->
SystemTable
=
(
EFI_SYSTEM_TABLE
*
)(
UINTN
)
BA1
->
efiSystemTable
;
...
...
@@ -59,6 +63,10 @@ OcParseBootArgs (
Arguments
->
CommandLine
=
&
BA2
->
CommandLine
[
0
];
Arguments
->
KernelAddrP
=
&
BA2
->
kaddr
;
Arguments
->
SystemTableP
=
&
BA2
->
efiSystemTable
;
Arguments
->
RuntimeServicesPG
=
&
BA2
->
efiRuntimeServicesPageStart
;
Arguments
->
RuntimeServicesV
=
&
BA2
->
efiRuntimeServicesVirtualPageStart
;
Arguments
->
DeviceTreeP
=
&
BA2
->
deviceTreeP
;
Arguments
->
DeviceTreeLength
=
&
BA2
->
deviceTreeLength
;
Arguments
->
SystemTable
=
(
EFI_SYSTEM_TABLE
*
)(
UINTN
)
BA2
->
efiSystemTable
;
...
...
Library/OcConfigurationLib/OcConfigurationLib.c
浏览文件 @
258fb83e
...
...
@@ -172,6 +172,7 @@ mBooterWhitelistSchema = OC_SCHEMA_DICT (NULL, mBooterWhitelistEntrySchema);
STATIC
OC_SCHEMA
mBooterQuirksSchema
[]
=
{
OC_SCHEMA_BOOLEAN_IN
(
"AllowRelocationBlock"
,
OC_GLOBAL_CONFIG
,
Booter
.
Quirks
.
AllowRelocationBlock
),
OC_SCHEMA_BOOLEAN_IN
(
"AvoidRuntimeDefrag"
,
OC_GLOBAL_CONFIG
,
Booter
.
Quirks
.
AvoidRuntimeDefrag
),
OC_SCHEMA_BOOLEAN_IN
(
"DevirtualiseMmio"
,
OC_GLOBAL_CONFIG
,
Booter
.
Quirks
.
DevirtualiseMmio
),
OC_SCHEMA_BOOLEAN_IN
(
"DisableSingleUser"
,
OC_GLOBAL_CONFIG
,
Booter
.
Quirks
.
DisableSingleUser
),
...
...
Platform/OpenCore/OpenCoreUefi.c
浏览文件 @
258fb83e
...
...
@@ -458,6 +458,7 @@ OcLoadBooterUefiSupport (
AbcSettings
.
DisableVariableWrite
=
Config
->
Booter
.
Quirks
.
DisableVariableWrite
;
AbcSettings
.
ProtectSecureBoot
=
Config
->
Booter
.
Quirks
.
ProtectSecureBoot
;
AbcSettings
.
DiscardHibernateMap
=
Config
->
Booter
.
Quirks
.
DiscardHibernateMap
;
AbcSettings
.
AllowRelocationBlock
=
Config
->
Booter
.
Quirks
.
AllowRelocationBlock
;
AbcSettings
.
EnableSafeModeSlide
=
Config
->
Booter
.
Quirks
.
EnableSafeModeSlide
;
AbcSettings
.
EnableWriteUnprotector
=
Config
->
Booter
.
Quirks
.
EnableWriteUnprotector
;
AbcSettings
.
ForceExitBootServices
=
Config
->
Booter
.
Quirks
.
ForceExitBootServices
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录