提交 bd17802d 编写于 作者: V vit9696

OcAppleBootCompatLib: Implement RebuildAppleMemoryMap

上级 6f0a8a1a
......@@ -21,6 +21,9 @@ OpenCore Changelog
- Fixed `PowerTimeoutKernelPanic` on 10.15.4
- Fixed 4K section alignment in `OpenRuntime` to fix Linux booting on SKL
- Introduced `SyncRuntimePermissions` to fix Linux booting on CFL+
- Introduced `RebuildAppleMemoryMap` to fix macOS booting on Dell 5490
- Removed `ShrinkMemoryMap` in favour of more advanced `RebuildAppleMemoryMap`
- Marked `EnableWriteUnprotector` as deprecated on new systems (SKL+)
#### v0.5.6
- Various improvements to builtin text renderer
......
......@@ -1293,8 +1293,8 @@ To view their current state use \texttt{pmset -g} command in Terminal.
register during their execution. This quirk requires \texttt{OC\_FIRMWARE\_RUNTIME}
protocol implemented in \texttt{OpenRuntime.efi}.
\emph{Note}: The necessity of this quirk is determined by early boot crashes
of the firmware.
\emph{Note}: This quirk may potentially weaken firmware security, please use
\texttt{RebuildAppleMemoryMap} instead unless it fails for you.
\item
\texttt{ForceExitBootServices}\\
......@@ -1366,6 +1366,35 @@ To view their current state use \texttt{pmset -g} command in Terminal.
slide values are usable!} message in the debug log. If the message is present,
this option is to be enabled.
\item
\texttt{RebuildAppleMemoryMap}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Generate Memory Map compatible with macOS.
Apple kernel has several limitations in parsing UEFI memory map:
\begin{itemize}
\tightlist
\item Memory map size must not exceed 4096 bytes as Apple kernel maps
it as a single 4K page. Since some firmwares have very large memory maps
(approximately over 100 entries) Apple kernel will crash at boot.
\item Memory attributes table is ignored. \texttt{EfiRuntimeServicesCode}
memory statically gets \texttt{RX} permissions, and all other memory types
get \texttt{RW} permissions. Since some firmware drivers may write to global
variables at runtime, Apple kernel will crash at calling UEFI runtime services,
unless driver \texttt{.data} section has \texttt{EfiRuntimeServicesData}
type.
\end{itemize}
To workaround these limitations this quirk applies memory attributes table
permissions to memory map passed to Apple kernel and optionally attempts
to unify contiguous slots of similar types if the resulting memory map exceeds
4 KB.
\emph{Note}: The necessity of this quirk is determined by early boot failures.
This quirk replaces \texttt{EnableWriteUnprotector} on most platforms.
\item
\texttt{SetupVirtualMap}\\
\textbf{Type}: \texttt{plist\ boolean}\\
......@@ -1381,20 +1410,6 @@ To view their current state use \texttt{pmset -g} command in Terminal.
new firmwares with memory protection support (like OVMF) do not support this quirk due to
\href{https://github.com/acidanthera/bugtracker/issues/719}{acidanthera/bugtracker\#719}.
\item
\texttt{ShrinkMemoryMap}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Attempt to join similar memory map entries.
Select firmwares have very large memory maps, which do not fit into a single 4 KB
page, which is a requirement for Apple kernel. This quirk attempts to unify
contiguous slots of similar types to prevent boot failures.
\emph{Note}: The necessity of this quirk is determined by early boot failures.
It is rare to need this quirk on Haswell or newer. Do not use unless you fully
understand the consequences.
\item
\texttt{SignalAppleOS}\\
\textbf{Type}: \texttt{plist\ boolean}\\
......@@ -1405,6 +1420,18 @@ To view their current state use \texttt{pmset -g} command in Terminal.
For example, it is supposed to enable Intel GPU in Windows and Linux in some
dual-GPU MacBook models.
\item
\texttt{SyncRuntimePermissions}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Update memory permissions for \texttt{OpenRuntime} to function.
Some firmwares may incorrectly mark \texttt{OpenRuntime} as not executable, this quirks
updates memory map and memory attributes table to correct this.
\emph{Note}: The necessity of this quirk is determined by early boot failures either in
macOS or in Linux/Windows. In general only firmwares released in 2018 or later are affected.
\end{enumerate}
\section{DeviceProperties}\label{devprops}
......
\documentclass[]{article}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL PreviousConfiguration.tex Fri Mar 6 09:43:05 2020
%DIF ADD ../Configuration.tex Thu Apr 2 21:22:46 2020
%DIF ADD ../Configuration.tex Fri Apr 3 14:10:56 2020
\usepackage{lmodern}
\usepackage{amssymb,amsmath}
......@@ -1358,8 +1358,9 @@ To view their current state use \texttt{pmset -g} command in Terminal.
register during their execution. This quirk requires \texttt{OC\_FIRMWARE\_RUNTIME}
protocol implemented in \texttt{\DIFdelbegin \DIFdel{FwRuntimeServices}\DIFdelend \DIFaddbegin \DIFadd{OpenRuntime}\DIFaddend .efi}.
\emph{Note}: The necessity of this quirk is determined by early boot crashes
of the firmware.
\emph{Note}: \DIFdelbegin \DIFdel{The necessity of this quirk is determined by early boot crashes
of the firmware }\DIFdelend \DIFaddbegin \DIFadd{This quirk may potentially weaken firmware security, please use
}\texttt{\DIFadd{RebuildAppleMemoryMap}} \DIFadd{instead unless it fails for you}\DIFaddend .
\item
\texttt{ForceExitBootServices}\\
......@@ -1435,7 +1436,40 @@ To view their current state use \texttt{pmset -g} command in Terminal.
this option is to be enabled.
\item
\texttt{SetupVirtualMap}\\
\DIFaddbegin \texttt{\DIFadd{RebuildAppleMemoryMap}}\\
\textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ boolean}}\\
\textbf{\DIFadd{Failsafe}}\DIFadd{: }\texttt{\DIFadd{false}}\\
\textbf{\DIFadd{Description}}\DIFadd{: Generate Memory Map compatible with macOS.
}
\DIFadd{Apple kernel has several limitations in parsing UEFI memory map:
}
\begin{itemize}
\tightlist
\item \DIFadd{Memory map size must not exceed 4096 bytes as Apple kernel maps
it as a single 4K page. Since some firmwares have very large memory maps
(approximately over 100 entries) Apple kernel will crash at boot.
}\item \DIFadd{Memory attributes table is ignored. }\texttt{\DIFadd{EfiRuntimeServicesCode}}
\DIFadd{memory statically gets }\texttt{\DIFadd{RX}} \DIFadd{permissions, and all other memory types
get }\texttt{\DIFadd{RW}} \DIFadd{permissions. Since some firmware drivers may write to global
variables at runtime, Apple kernel will crash at calling UEFI runtime services,
unless driver }\texttt{\DIFadd{.data}} \DIFadd{section has }\texttt{\DIFadd{EfiRuntimeServicesData}}
\DIFadd{type.
}\end{itemize}
\DIFadd{To workaround these limitations this quirk applies memory attributes table
permissions to memory map passed to Apple kernel and optionally attempts
to unify contiguous slots of similar types if the resulting memory map exceeds
4 KB.
}
\emph{\DIFadd{Note}}\DIFadd{: The necessity of this quirk is determined by early boot failures.
This quirk replaces }\texttt{\DIFadd{EnableWriteUnprotector}} \DIFadd{on most platforms.
}
\item
\DIFaddend \texttt{SetupVirtualMap}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Setup virtual memory at \texttt{SetVirtualAddresses}.
......@@ -1450,22 +1484,39 @@ To view their current state use \texttt{pmset -g} command in Terminal.
\href{https://github.com/acidanthera/bugtracker/issues/719}{acidanthera/bugtracker\#719}.
\item
\texttt{ShrinkMemoryMap}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Attempt to join similar memory map entries.
\DIFdelbegin \texttt{\DIFdel{ShrinkMemoryMap}}%DIFAUXCMD
%DIFDELCMD < \\
%DIFDELCMD < %%%
\textbf{\DIFdel{Type}}%DIFAUXCMD
\DIFdel{: }\texttt{\DIFdel{plist\ boolean}}%DIFAUXCMD
%DIFDELCMD < \\
%DIFDELCMD < %%%
\textbf{\DIFdel{Failsafe}}%DIFAUXCMD
\DIFdel{: }\texttt{\DIFdel{false}}%DIFAUXCMD
%DIFDELCMD < \\
%DIFDELCMD < %%%
\textbf{\DIFdel{Description}}%DIFAUXCMD
\DIFdel{: Attempt to join similar memory map entries.
}%DIFDELCMD <
Select firmwares have very large memory maps, which do not fit \DIFdelbegin \DIFdel{Apple kernel, permitting up to }\texttt{\DIFdel{64}} %DIFAUXCMD
\DIFdel{slots for runtime memory}\DIFdelend \DIFaddbegin \DIFadd{into a single 4 KB
page, which is a requirement for Apple kernel}\DIFaddend . This quirk attempts to unify
%DIFDELCMD < %%%
\DIFdel{Select firmwares have very large memory maps, which do not fit Apple kernel,
permitting up to }\texttt{\DIFdel{64}} %DIFAUXCMD
\DIFdel{slots for runtime memory. This quirk attempts to unify
contiguous slots of similar types to prevent boot failures.
}%DIFDELCMD <
\emph{Note}: The necessity of this quirk is determined by early boot failures.
%DIFDELCMD < %%%
\emph{\DIFdel{Note}}%DIFAUXCMD
\DIFdel{: The necessity of this quirk is determined by early boot failures.
It is rare to need this quirk on Haswell or newer. Do not use unless you fully
understand the consequences.
}%DIFDELCMD <
\item
\texttt{SignalAppleOS}\\
%DIFDELCMD < \item
\item%DIFAUXCMD
%DIFDELCMD < %%%
\DIFdelend \texttt{SignalAppleOS}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Report macOS being loaded through OS Info for any OS.
......@@ -1474,7 +1525,22 @@ To view their current state use \texttt{pmset -g} command in Terminal.
For example, it is supposed to enable Intel GPU in Windows and Linux in some
dual-GPU MacBook models.
\end{enumerate}
\DIFaddbegin \item
\texttt{\DIFadd{SyncRuntimePermissions}}\\
\textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ boolean}}\\
\textbf{\DIFadd{Failsafe}}\DIFadd{: }\texttt{\DIFadd{false}}\\
\textbf{\DIFadd{Description}}\DIFadd{: Update memory permissions for }\texttt{\DIFadd{OpenRuntime}} \DIFadd{to function.
}
\DIFadd{Some firmwares may incorrectly mark }\texttt{\DIFadd{OpenRuntime}} \DIFadd{as not executable, this quirks
updates memory map and memory attributes table to correct this.
}
\emph{\DIFadd{Note}}\DIFadd{: The necessity of this quirk is determined by early boot failures either in
macOS or in Linux/Windows. In general only firmwares released in 2018 or later are affected.
}
\DIFaddend \end{enumerate}
\section{DeviceProperties}\label{devprops}
......
......@@ -260,10 +260,10 @@
<false/>
<key>ProvideCustomSlide</key>
<true/>
<key>RebuildAppleMemoryMap</key>
<false/>
<key>SetupVirtualMap</key>
<true/>
<key>ShrinkMemoryMap</key>
<false/>
<key>SignalAppleOS</key>
<false/>
<key>SyncRuntimePermissions</key>
......
......@@ -260,10 +260,10 @@
<false/>
<key>ProvideCustomSlide</key>
<true/>
<key>RebuildAppleMemoryMap</key>
<false/>
<key>SetupVirtualMap</key>
<true/>
<key>ShrinkMemoryMap</key>
<false/>
<key>SignalAppleOS</key>
<false/>
<key>SyncRuntimePermissions</key>
......
......@@ -60,9 +60,11 @@ typedef struct OC_ABC_SETTINGS_ {
///
BOOLEAN ProtectCsmRegion;
///
/// Attempt to reduce memory map entries through grouping to fit into Apple kernel.
/// Rebuild memory map to be compatible with Apple kernel.
/// - Apply memory attributes and split RT entries into code and data.
/// - Reduce memory map entries through grouping to fit into 4KB.
///
BOOLEAN ShrinkMemoryMap;
BOOLEAN RebuildAppleMemoryMap;
///
/// Ensure that ExitBootServices call succeeds even with outdated MemoryMap key.
///
......
......@@ -124,8 +124,8 @@
_(BOOLEAN , ProtectSecureBoot , , FALSE , ()) \
_(BOOLEAN , ProtectUefiServices , , FALSE , ()) \
_(BOOLEAN , ProvideCustomSlide , , FALSE , ()) \
_(BOOLEAN , RebuildAppleMemoryMap , , FALSE , ()) \
_(BOOLEAN , SetupVirtualMap , , FALSE , ()) \
_(BOOLEAN , ShrinkMemoryMap , , FALSE , ()) \
_(BOOLEAN , SignalAppleOS , , FALSE , ()) \
_(BOOLEAN , SyncRuntimePermissions , , FALSE , ())
OC_DECLARE (OC_BOOTER_QUIRKS)
......
......@@ -124,13 +124,13 @@ OcAbcInitialize (
DEBUG ((
DEBUG_INFO,
"OCABC: FEXITBS %d PRCSM %d CSLIDE %d PRSRV %d VMAP %d SHRMAP %d APPLOS %d RTPERMS %d\n",
"OCABC: FEXITBS %d PRCSM %d CSLIDE %d PRSRV %d RBMAP %d VMAP %d APPLOS %d RTPERMS %d\n",
Settings->ForceExitBootServices,
Settings->ProtectCsmRegion,
Settings->ProvideCustomSlide,
Settings->ProtectUefiServices,
Settings->RebuildAppleMemoryMap,
Settings->SetupVirtualMap,
Settings->ShrinkMemoryMap,
Settings->SignalAppleOS,
Settings->SyncRuntimePermissions
));
......
......@@ -362,9 +362,11 @@ OcGetMemoryMap (
BOOT_COMPAT_CONTEXT *BootCompat;
EFI_PHYSICAL_ADDRESS Address;
UINTN Pages;
UINTN OriginalSize;
BootCompat = GetBootCompatContext ();
OriginalSize = MemoryMapSize != 0 ? *MemoryMapSize : 0;
Status = BootCompat->ServicePtrs.GetMemoryMap (
MemoryMapSize,
MemoryMap,
......@@ -373,6 +375,14 @@ OcGetMemoryMap (
DescriptorVersion
);
//
// Reserve larger area for the memory map when we need to split it.
//
if (BootCompat->ServiceState.AppleBootNestedCount > 0 && Status == EFI_BUFFER_TOO_SMALL) {
*MemoryMapSize += OcCountSplitDescritptors () * *DescriptorSize;
return EFI_BUFFER_TOO_SMALL;
}
if (EFI_ERROR (Status)) {
return Status;
}
......@@ -411,7 +421,17 @@ OcGetMemoryMap (
);
}
if (BootCompat->Settings.ShrinkMemoryMap) {
if (BootCompat->Settings.RebuildAppleMemoryMap) {
Status2 = OcSplitMemoryMapByAttributes (
OriginalSize,
MemoryMapSize,
MemoryMap,
*DescriptorSize
);
if (EFI_ERROR (Status2) && Status != EFI_UNSUPPORTED) {
DEBUG ((DEBUG_INFO, "OCABC: Cannot rebuild memory map - %r\n", Status));
}
ShrinkMemoryMap (
MemoryMapSize,
MemoryMap,
......
......@@ -176,8 +176,8 @@ mBooterQuirksSchema[] = {
OC_SCHEMA_BOOLEAN_IN ("ProtectSecureBoot", OC_GLOBAL_CONFIG, Booter.Quirks.ProtectSecureBoot),
OC_SCHEMA_BOOLEAN_IN ("ProtectUefiServices", OC_GLOBAL_CONFIG, Booter.Quirks.ProtectUefiServices),
OC_SCHEMA_BOOLEAN_IN ("ProvideCustomSlide", OC_GLOBAL_CONFIG, Booter.Quirks.ProvideCustomSlide),
OC_SCHEMA_BOOLEAN_IN ("RebuildAppleMemoryMap", OC_GLOBAL_CONFIG, Booter.Quirks.RebuildAppleMemoryMap),
OC_SCHEMA_BOOLEAN_IN ("SetupVirtualMap", OC_GLOBAL_CONFIG, Booter.Quirks.SetupVirtualMap),
OC_SCHEMA_BOOLEAN_IN ("ShrinkMemoryMap", OC_GLOBAL_CONFIG, Booter.Quirks.ShrinkMemoryMap),
OC_SCHEMA_BOOLEAN_IN ("SignalAppleOS", OC_GLOBAL_CONFIG, Booter.Quirks.SignalAppleOS),
OC_SCHEMA_BOOLEAN_IN ("SyncRuntimePermissions", OC_GLOBAL_CONFIG, Booter.Quirks.SyncRuntimePermissions),
};
......
......@@ -363,8 +363,8 @@ OcLoadBooterUefiSupport (
AbcSettings.ProtectCsmRegion = Config->Booter.Quirks.ProtectCsmRegion;
AbcSettings.ProvideCustomSlide = Config->Booter.Quirks.ProvideCustomSlide;
AbcSettings.ProtectUefiServices = Config->Booter.Quirks.ProtectUefiServices;
AbcSettings.RebuildAppleMemoryMap = Config->Booter.Quirks.RebuildAppleMemoryMap;
AbcSettings.SetupVirtualMap = Config->Booter.Quirks.SetupVirtualMap;
AbcSettings.ShrinkMemoryMap = Config->Booter.Quirks.ShrinkMemoryMap;
AbcSettings.SignalAppleOS = Config->Booter.Quirks.SignalAppleOS;
AbcSettings.SyncRuntimePermissions = Config->Booter.Quirks.SyncRuntimePermissions;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册