7. Kernel
OpenCore 安全配置,Kext 加载顺序以及屏蔽
由 Sukka、derbalkon、cike-567 整理,由 Sukka、derbalkon、cike-567 翻译。
本页面最后更新于 2023 年 06 月 13 日
在 GitHub 上编辑
7.1 简介
本章节介绍了如何在 Apple Kernel(XNU)上应用各种不同的内核空间修改,包括内核驱动程序(Kext)注入、修补以及屏蔽。
对 Kernel 和 Kext 的修补按照如下顺序执行:
- Block
- Add 和 Force
- Emulate 和 Quirks
- Patch
7.2 属性列表
1. Add
Type: plist array
Failsafe: Empty
Description: 从 OC/Kexts 目录加载选定的 Kext 驱动。
设计为使用 plist dict 数据填充以描述每个驱动程序。请参阅下述 Add 属性章节。
注 1:Kext 驱动程序加载的顺序遵照数组中项目的顺序,因此如 Lilu 这种其他驱动程序的依赖驱动应该位于前面。
注 2:可以通过检查 Kext 驱动中 Info.plist 的 OSBundleLibraries 值的方法来确定其依赖驱动的加载顺序。OSBundleLibraries 中的任何依赖驱动都必须在此 Kext 之前加载。
注 3:Kext 驱动的内部可能也附带另外的 Kext (Plug-Ins),每个内部的 Kext 也都必须单独添加,并遵循与其他 Kext 相同的全局排序规则。
2. Block
Type: plist array
Failsafe: Empty
Description: 从 Prelinked Kernel 中移除选定的 Kext。
设计为使用 plist dict 数据填充以描述每个驱动程序。请参阅下述 Block 属性章节。
3. Emulate
Type: plist dict
Description: 在内核空间中仿真选定的硬件。请参考下文 Emulate 属性。
4. Force
Type: plist array
Failsafe: Empty
Description: 如果内核驱动没有被缓存,则从系统卷宗强制加载内核驱动。
设计为使用 plist dict 值来填充,用于描述驱动程序。参见下面的 Force 属性部分。依赖其他驱动的驱动程序不能被缓存,该部分着重解决了这种驱动程序注入的难点。这个问题会映像到旧的操作系统,在旧的操作系统中存在各种依赖性的 Kext,比如 IOAudioFamily 和 IONetworkingFamily,可能默认不存在于内核缓存中。
注 1:加载的顺序是 Kexts 在 array 中出现的顺序。因此,依赖关系必须出现在依赖它们的 Kexts 之前。
注 2:Force 发生在 Add 之前。
注 3:”forced” 的 Kexts 的签名没有经过任何检查。这使得使用这个功能非常危险并且不适合安全启动。
注 4:在较新的操作系统中,这个功能可能在加密的分区上不起作用。
5. Patch
Type: plist array
Failsafe: Empty
Description: 在添加和删除驱动程序步骤之前执行的对现有 Kext 驱动程序的二进制修补。
设计为使用 plist dictionary 数据填充以描述每个驱动程序。请参阅下述 Patch 属性部分。
6. Quirks
Type: plist dict
Description: 应用下面的 Quirks 属性章节中描述的各个内核和驱动程序 Quirk。
7. Scheme
Type: plist dict
Description: 通过参数来定义内核空间的操作模式,具体参数见下面 Scheme 属性部分的描述。
7.3 Add 属性
1. Arch
Type: plist string
Failsafe: Any (适用于任何支持的架构)
Description: Kext 架构(i386, x86_64)。
2. BundlePath
Type: plist string
Failsafe: Empty
Description: Kext 相对于 EFI/OC/kexts/Other/ 的路径,如 Lilu.kext 或 MyKext.kext/Contents/PlugIns/MySubKext.kext。
译者注:如
VoodooPS2Controller.kext这种包括其他 Kext 驱动的,需要分别单独添加,如VoodooPS2Controller.kext/Contents/PlugIns/VoodooPS2Keyboard.kext。
3. Comment
Type: plist string
Failsafe: Empty
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。
4. Enabled
Type: plist boolean
Failsafe: false
Description: 设置为 true 以加载该驱动。
5. ExecutablePath
Type: plist string
Failsafe: Empty
Description: Kext 中实际可执行文件的路径(例如 Lilu.kext 中的可执行文件路径是 Contents/MacOS/Lilu)。
译者注:空壳 Kext 没有可执行文件(例如:
USBPorts.kext),此项留空即可。
6. MaxKernel
Type: plist string
Failsafe: Empty string
Description: 在小于等于指定的 macOS 版本或更高版本中添加该 Kext 驱动程序。
你可以使用 uname -r 指令获取当前内核版本,一般为三个整数、中间由半角句点分隔,如 18.7.0 代表的是 10.14.6。OpenCore 对内核版本解释的实现方式如下图所示:
内核版本比较的实现如下图所示:
将 Darwin 内核版本号字符串从左到右以 . 符号作为分隔符分割成三个整数,即为 ParseDarwinVersion 的三个参数。FindDarwinVersion 函数将会通过在内核镜像中查找形如 的字符串来定位 Darwin 内核版本号。
7. MinKernel
Type: plist string
Failsafe: Empty string
Description: 在大于等于指定的 macOS 版本中添加该 Kext 驱动程序。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
译者注:以上两个属性定义了这个驱动将在什么版本范围的 macOS 中加载。留空表示在所有的 macOS 版本下都加载。
8. PlistPath
Type: plist string
Failsafe: Empty
Description: Kext 中 Info.plist 文件的路径。例如:Contents/Info.plist。
7.4 Block 属性
1. Arch
Type: plist string
Failsafe: Any (适用于任何支持的架构)
Description: Kext block 架构(i386,x86_64)。
2. Comment
Type: plist string
Failsafe: Empty
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。
3. Enabled
Type: plist boolean
Failsafe: false
Description: 除非设置为 true,否则这个内核驱动不会被加载。
4. Identifier
Type: plist string
Failsafe: Empty
Description: Kext Bundle 标识符(例如:com.apple.driver.AppleTyMCEDriver)。
5. MaxKernel
Type: plist string
Failsafe: Empty
Description: 在小于等于指定的 macOS 版本中阻止 Kext 驱动程序。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
6. MinKernel
Type: plist string
Failsafe: Empty string
Description: 在大于等于指定的 macOS 版本中阻止 Kext 驱动程序。
7. Strategy
Type: plist string
Failsafe: Disable(强行让内核驱动 kmod 的启动代码返回失败)。
Description: 阻止内核驱动加载。
有效值:
- Disable - 强行让内核驱动的 kmod 启动代码返回失败。
- Exclude - 通过删除 plist entry 并填入
0,从内核缓存中删除内核驱动。
注 1:排除作为其他依赖项的 Kext 是有风险的。
注 2:目前排除仅适用于预链接内核和更新的机制。
注 3:在大多数情况下,删除内核驱动之后需要注入新的 Kext 作为替代品。
7.5 Emulate 属性
1. Cpuid1Data
Type: plist data, 16 bytes
Failsafe: All zero
Description: EAX、EBX、ECX、EDX 值的序列,用来取代 XNU 内核中的 CPUID (1) 调用。
该属性主要应用于以下三种需求:
- 对不支持的 CPU 型号启用支持(比如英特尔的奔腾处理器)。
- 对特定 macOS 版本(通常是旧版)不支持的 CPU 型号启用支持。
- 对不支持的 CPU Variant 启用 XCPM 支持。
注 1:还有一种可能的情况,即 CPU 型号是支持的,但其电源管理不支持(比如虚拟机)。在这种情况下,可以通过设置 MinKernel 和 MaxKernel 来限制特定 macOS 内核版本的 CPU 虚拟化和虚拟电源管理补丁。
注 2:通常来讲只需要处理 EAX 的值,因为它代表完整的 CPUID。剩余的字节要留为 0。字节顺序是小端字节序(Little Endian),比如 C3 06 03 00 代表 CPUID 0x0306C3 (Haswell)。
注 3:推荐使用下面的组合启用 XCPM 支持。请注意,需要设置与所安装的 CPU 相匹配的正确频率向量。:
- Haswell-E (
0x0306F2) to Haswell (0x0306C3):Cpuid1Data:C3 06 03 00 00 00 00 00 00 00 00 00 00 00 00 00Cpuid1Mask:FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 - Broadwell-E (
0x0406F1) to Broadwell (0x0306D4):Cpuid1Data:D4 06 03 00 00 00 00 00 00 00 00 00 00 00 00 00Cpuid1Mask:FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 - Comet Lake U62 (0x0A0660) to Comet Lake U42 (0x0806EC):
Cpuid1Data: EC 06 08 00 00 00 00 00 00 00 00 00 00 00 00 00Cpuid1Mask: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 - Rocket Lake (0x0A0670) to Comet Lake (0x0A0655):
Cpuid1Data: 55 06 0A 00 00 00 00 00 00 00 00 00 00 00 00 00Cpuid1Mask: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 - Alder Lake (0x090672) to Comet Lake (0x0A0655):
Cpuid1Data: 55 06 0A 00 00 00 00 00 00 00 00 00 00 00 00 00Cpuid1Mask: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
注 4:请记住,目前以下配置不被 XCPM 兼容(至少还没有人成功过):
- 消费级的 Ivy Bridge(
0x0306A9),因为苹果针对它禁用了 XCPM 并推荐用户使用传统的电源管理。如果要使用这一选项,你还需要手动添加_xcpm_patch二进制修补以强制启用 XCPM。 - 低端处理器(如基于 Haswell 或奔腾),因为它们不被 macOS 支持。如果要启用这些 CPU 请参阅 acidanthera/bugtracker#365 中的
Special NOTES相关内容。
2. Cpuid1Mask
Type: plist data, 16 bytes
Failsafe: All zero
Description: Cpuid1Data 中激活的 bit 的位掩码。
当每个 Cpuid1Mask bit 都设置为 0 时将使用原始的 CPU bit,否则取 Cpuid1Data 的值。
3. DummyPowerManagement
Type: plist boolean
Failsafe: false
Requirement: 10.4-12
Description: 禁用 AppleIntelCpuPowerManagement。
注 1:这一选项旨在替代 NullCpuPowerManagement.kext,用于 macOS 中没有相应电源管理驱动程序的 CPU。
注 2:虽然通常只有不支持的平台才需要启用这个选项来禁用 AppleIntelCpuPowerManagement,但是如果想要禁用这个 Kext 本身而不考虑其他情况(比如 Cpuid1Data 留空),也依然可以启用这个选项。
4. MaxKernel
Type: plist string
Failsafe: Empty string
Description: 模拟 CPUID,并在小于等于指定的 macOS 版本上使用 DummyPowerManagement。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
5. MinKernel
Type: plist string
Failsafe: Empty string
Description: 模拟 CPUID,并在大于等于指定的 macOS 版本上使用 DummyPowerManagement。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
7.6 Force 属性
1. Arch
Type: plist string
Failsafe: Any (适用于任何受支持的架构)
Description: Kext 架构(i386,x86_64)。
2. BundlePath
Type: plist string
Failsafe: Empty
Description: Kext 路径,例如:System/Library/Extensions/IONetworkingFamily.kext。
3. Comment
Type: plist string
Failsafe: Empty
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。
4. Enabled
Type: plist boolean
Failsafe: false
Description: 设置为 true 则在内核缓存中不存在时从系统卷加载此 kext 驱动程序。
5. ExecutablePath
Type: plist string
Failsafe: Empty
Description: Kext 中实际可执行文件的路径,例如:Contents/MacOS/IONetworkingFamily。
6. Identifier
Type: plist string
Failsafe: Empty
Description: Kext 标识符,以便在添加前检查是否存在,例如:com.apple.iokit.IONetworkingFamily。只有在缓存中找不到标识符的驱动程序才会被添加。
7. MaxKernel
Type: plist string
Failsafe: Empty
Description: 在小于等于指定的 macOS 版本中添加 Kext 驱动程序。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
8. MinKernel
Type: plist string
Failsafe: Empty
Description: 在大于等于指定的 macOS 版本中添加 Kext 驱动程序。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
9. PlistPath
Type: plist string
Failsafe: Empty
Description: Kext 中 Info.plist 文件的路径。一般为 Contents/Info.plist。
7.7 Patch 属性
1. Arch
Type: plist string
Failsafe: Any (适用于任何受支持的架构)
Description: Kext patch 架构(i386,x86_64)。
2. Base
Type: plist string
Failsafe: Empty (Ignored)
Description: 通过获取所提供的 Symbol 名称的地址,来选择 Symbol 匹配的 Base 进行补丁查找(或直接替换)。
3. Comment
Type: plist string
Failsafe: Empty
Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。
4. Count
Type: plist integer
Failsafe: 0
Description: 修补的次数,超过这一次数后便不再修补。0 表示修补所有查找到的地方。
5. Enabled
Type: plist boolean
Failsafe: false
Description: 除非设置为 true,否则不会使用此内核补丁。
6. Find
Type: plist data
Failsafe: Empty (Immediate replacement at base)
Description: 需要查找的数据。如果设置,则其大小必须等于 Replace。
7. Identifier
Type: plist string
Failsafe: Empty
Description: Kext Bundle 标识符(如 com.apple.driver.AppleHDA)或内核补丁的 kernel。
8. Limit
Type: plist integer
Failsafe: 0 (搜索整个 Kext 或内核)
Description: 搜索的最大字节数。
9. Mask
Type: plist data
Failsafe: Empty (Ignored)
Description: 在查找比较的过程中使用数据位掩码。允许通过忽略未被屏蔽的 bit(设置为 0)进行模糊搜索。如果设置,则其大小必须等于 Replace。
10. MaxKernel
Type: plist string
Failsafe: Empty string
Description: 在小于指定的或更早的 macOS 版本上打补丁。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
11. MinKernel
Type: plist string
Failsafe: Empty string
Description: 在大于等于指定的 macOS 版本上打补丁。
注:匹配逻辑请参阅 Add MaxKernel 的描述。
12. Replace
Type: plist data
Failsafe: Empty data
Description: 一个或多个字节的替换数据。
13. ReplaceMask
Type: plist data
Failsafe: Empty data
Description: 替换时使用的数据位掩码。允许通过更新掩码(设置为非 0)来进行模糊替换。若留空则代表忽略,否则其大小必须等于 Replace。
14. Skip
Type: plist integer
Failsafe: 0 (不跳过任何事件)
Description: 在替换前要跳过的发现事件数。
7.8 Quirks 属性
1. AppleCpuPmCfgLock
Type: plist boolean
Failsafe: false
Requirement: 10.4
Description: 禁用 AppleIntelCPUPowerManagement.kext 中的 PKG_CST_CONFIG_CONTROL (0xE2) 修改,从而避免早期 Kernel Panic。
注:AppleIntelCPUPowerManagement.kext 自 macOS 13 起,已被删除。但是,可以注入旧版本 AppleIntelCPUPowerManagement.kext 并使用此 quirk 进行修补。
某些固件会锁定 PKG_CST_CONFIG_CONTROL MSR 寄存器。可以使用附带的 ControlMsrE2 工具检查其状态。请注意,某些类型的固件仅将此寄存器锁定在某些内核上。由于现代固件已经提供了 CFG Lock 相关设置、从而可以配置 PKG_CST_CONFIG_CONTROL 寄存器锁定,此选项应该尽可能避免。
对于一些不显示 CFG Lock 配置的固件,可以按照下述配置进行修改:
- 下载 UEFITool 和 IFR-Extractor
- 使用 UEFITool 中打开固件镜像文件,找到 CFG Lock 的 Unicode 字符串。如果你没有找到,意味着你的固件可能不支持
CFG Lock解锁,那么你现在可以停下来了。 - 从 UEFITool 菜单中的
Extract Body选项提取Setup.bin中的 PE32 镜像部分。 - 对提取出来的文件执行 IFR-Extractor(
./ifrextract Setup.bin Setup.txt)。 - 从 Setup.txt 中找到
CFG Lock, VarStoreInfo (VarOffset/VarName):,记住紧随其后的偏移量值(例如0x123)。 - 下载并执行由 brainsucker 编译的 修改版 GRUB Shell。你也可以使用 datasone 制作的 新版 GRUB Shell。
- 在 GRUB Shell 中,使用
setup_var 0x123 0x00(其中0x123应该被替换为你在前几步找到的偏移值),然后重启电脑。
在选定的平台上,ControlMsrE2 工具也可以改变这种隐藏的选项。传递所需的参数:lock, unlock for CFG Lock。或者通过控制台来查找和修改其他隐藏选项。
作为最后的手段,考虑修补 BIOS(仅适用于高级用户)。
2. AppleXcpmCfgLock
Type: plist boolean
Failsafe: false
Requirement: 10.8 (not required for older)
Description: 禁用 XNU 内核对 PKG_CST_CONFIG_CONTROL (0xE2) 修改,从而避免早期 Kernel Panic(XCPM power management)。
注:这一选项应该避免被使用,请参考上文中关于 AppleCpuPmCfgLock 的介绍。
3. AppleXcpmExtraMsrs
Type: plist boolean
Failsafe: false
Requirement: 10.8 (not required for older)
Description: 对于没有 XCMP 支持的设备,禁用对选定 CPU 的多 MSR 访问。
通常将其与 Haswell-E,Broadwell-E,Skylake-SP 和类似 CPU 的 Emulate 结合使用。更多关于 XCPM 修补的信息可以在 acidanthera/bugtracker#365 找到。
注:Ivy Bridge 或 Pentium CPU 将需要其他未提供的补丁。建议对前者使用 AppleIntelCpuPowerManagement.kext。
4. AppleXcpmForceBoost
Type: plist boolean
Failsafe: false
Requirement: 10.8 (not required for older)
Description: 在 XCPM 模式下强制使用最大性能。
该补丁将 0xFF00 写入 MSR_IA32_PERF_CONTROL (0x199),有效地做到了一直保持最大倍数。
注:尽管有助于提高性能,但是在所有操作系统上都强烈建议不要启用这一选项,但明确专用于科学或媒体计算的系统除外。只有在某些 Xeon 型号的 CPU 才有可能从这个选项中受益。
5. CustomPciSerialDevice
Type: plist boolean
Failsafe: false
Requirement: 10.7
Description: 在一个定制的 PCI 串行设备上修改 PMIO 寄存器的基本地址。
该补丁改变了 XNU 内核用于串行输入和输出的 PMIO 寄存器基址,从默认的内置COM1串行端口 0x3F8,改为存储在指定 PCI 设备的第一个 IO BAR 中的基址,或者是一个特定的基址(例如 0x2F8 用于 COM2)。
注 1:默认情况下,串行日志是禁用的。 启动参数 serial=3,启用串行输入和输出,使 XNU 将日志打印到串行端口。
注 2:除此修补程序外,应防止 kext Apple16X50PCI0 连接,以使 kprintf 方法正常工作。这可以通过使用 PCIeSerialDisable 实现。此外,对于某些雷电卡,IOKit personality IOPCITunnelCompatible 也需要设置为 true,这可以由 Acidantarea/bugtracker#2003 上附带的 PCIeSerialThunderboltEnable.kext 完成。
注 3:要正确应用这个补丁,必须启用 Override,并在 Custom 中正确设置所有的选项。在 Misc->Serial 部分。
注 4:这个补丁是为了支持 PMIO,因此如果 Misc->Serial->Custom 部分的 UseMmio 为 false,则不适用。对于 MMIO,有启动参数 pcie_mmio_uart=ADDRESS 和 mmio_uart=ADDRESS,允许内核使用 MMIO 来访问串行端口。
注 5:串行波特率必须在 Misc->Serial->Custom 部分的 BaudRate 和通过启动参数 serialbaud=VALUE 正确设置。这两个参数应该相互匹配。默认的波特率是 115200。
6. CustomSMBIOSGuid
Type: plist boolean
Failsafe: false
Requirement: 10.4
Description: 对 UpdateSMBIOSMode 自定义模式执行 GUID 修补,通常用于戴尔笔记本电脑。
7. DisableIoMapper
Type: plist boolean
Failsafe: false
Requirement: 10.8 (not required for older)
Description: 禁用 XNU (VT-d) 中的 IOMapper 支持,这可能与固件的实现相冲突。
注 1:该选项是直接在 ACPI 表中删除 DMAR 和在固件首选项中禁用 VT-d 的首选替代方案。不会妨碍其他操作系统中的 VT-d 支持。
注 2:固件中错误配置的 IOMMU 可能导致设备损坏,如以太网或 Wi-Fi 适配器。例如,以太网适配器可能会无限在连接-断开中循环,Wi-Fi 适配器可能无法发现网络。技嘉是出现这些问题的最常见的 OEM 厂商之一。
8. DisableIoMapperMapping
Type: plist boolean
Failsafe: false
Requirement: 13.3(not required for older)
Description: 在 IOMMU(VT-d) 中禁止映射 PCI 桥接设备内存。
这个选项解决了在原生 DMAR 表包含一个或多个保留内存区域且安装了超过 16 GB 内存的系统上启用 AppleVTD 时与 Wi-Fi、以太网和 Thunderbolt 设备的兼容性问题。在某些系统上,只有在启用 iGPU 时才需要这个 Quirk。
注 1:在 AMD 系统上不需要这个选项。
9. DisableLinkeditJettison
Type: plist boolean
Failsafe: false
Requirement: 11
Description: 禁止丢弃 __LINKEDIT。
这个选项能让 Lilu.kext 和其他一些可能的 kext 在 macOS Big Sur 中以最佳性能运行,而不需要 keepsyms=1 启动参数。
9. DisableRtcChecksum
Type: plist boolean
Failsafe: false
Requirement: 10.4
Description: 禁用 AppleRTC 初始校验和(0x58-0x59)写入。
注 1:这个选项不能确保其他区域不被覆盖,如有需要,请使用 RTCMemoryFixup。
注 2:这个选项不能确保区域在固件阶段不被覆盖(例如 macOS bootloader)。如有需要,请参阅 AppleRtcRam 协议描述。
10. ExtendBTFeatureFlags
Type: plist boolean
Failsafe: false
Requirement: 10.8-11
Description: 将 FeatureFlags 设置为 0x0F,以实现蓝牙的全部功能(包括连续互通功能)。
注:此选项是 BT4LEContinuityFixup.kext 的替代品。由于补丁进度较晚,无法正常工作。
11. ExternalDiskIcons
Type: plist boolean
Failsafe: false
Requirement: 10.4
Description: 修补 AppleAHCIPort.kext 图标,使 macOS 将所有 AHCI 存储设备显示为内部硬盘。
注:这一选项应尽量避免使用。现代固件通常情况下都是兼容的。
12. ForceAquantiaEthernet
Type: plist boolean
Failsafe: false
Requirement: 10.15.4
Description: 启用基于 Aquantia AQtion 的 10GbE 网卡支持。
这个选项可以使基于 Aquantia AQtion 的 10GbE 网卡得到支持,在macOS 10.15.4之前,这些网卡是原生支持的。
注 1:为了使 Aquantia 卡正常工作,必须禁用 DisableIoMapper,不得丢弃 DMAR ACPI 表,并且必须在 BIOS 中启用 VT-d。
注 2:虽然此补丁应支持所有 Aquantia AQtion 系列的以太网卡,但它仅在基于 AQC-107s 的 10GbE 网卡上进行了测试。
注 3:为了解决 AppleVTD 在应用这个 Quirk 后的不兼容问题,DMAR ACPI表中相应设备的保留内存区域部分可能被删除。这个表应该被拆解和编辑,然后用 iASL 工具重新编译成 AML。为了添加修补后的 DMAR 表,应该删除原来的表。更多细节可以在 commit 2441455 中找到。
13. ForceSecureBootScheme
Type: plist boolean
Failsafe: false
Requirement: 11
Description: 强制采用 x86 方案进行 IMG4 核查。
注:在虚拟机上使用 x86legacy 以外的 SecureBootModel 时需要开启此选项。
14. IncreasePciBarSize
Type: plist boolean
Failsafe: false
Requirement: 10.10
Description: 允许 IOPCIFamily 用 2GB PCI BAR 启动
通常情况下,macOS 将 PCI BAR 限制为 1GB。启用这个选项(仍然)并不能让 macOS 实际使用具有更大 PCI BAR 的设备。
注:你应该尽可能避免使用这一选项。通常这一选项只需要在配置错误或损坏的固件上开启。
译者注:如果你的 BIOS 中存在
Above4GDecoding选项,请直接在 BIOS 中启用。
15. LapicKernelPanic
Type: plist boolean
Failsafe: false
Requirement: 10.6 (64-bit)
Description: 禁用 LAPIC 中断导致的 Kernal Panic。
译者注:惠普电脑可能需要启用这一选项。
16. LegacyCommpage
Type: plist boolean
Failsafe: false
Requirement: 10.4 - 10.6
Description: 默认的 64 位 commpage bcopy 的实现需要 SSSE3,这个选项把它替换为「不需要 SSSE3」的实现,这对于不支持 SSSE3 的旧平台很有必要,防止因不存在「不需要 SSSE3 的 64 位 bcopy 函数」而导致的 commpage no match for last Panic。
17. PanicNoKextDump
Type: plist boolean
Failsafe: false
Requirement: 10.13 (not required for older)
Description: 在发生内核崩溃时阻止输出 Kext 列表,提供可供排错参考的崩溃日志。该 Quirk 在 10.13 及以上起作用。
18. PowerTimeoutKernelPanic
Type: plist boolean
Failsafe: false
Requirement: 10.15 (not required for older)
Description: 修复 macOS Catalina 中由于设备电源状态变化超时而导致的内核崩溃。
macOS Catalina 新增了一项额外的安全措施,导致在电源切换超时的时候会出现 Kernel Panic。配置错误的硬件可能会因此出现问题,特别是数字音频、有的时候会导致睡眠唤醒的问题。这一 Quirk 和引导参数 setpowerstate_panic=0 功能大部分一致,但是后者只应该用于调试用途。
19. ProvideCurrentCpuInfo
Type: plist boolean
Failsafe: false
Requirement: 10.4 (10.14)
Description: 向内核提供当前的 CPU 信息。
这个 Quirk 的工作方式因 CPU 不同而不同:
- 对于微软的 Hyper-V,它向内核提供正确的 TSC 和 FSB 值,以及禁用 CPU 拓扑验证(10.8以上)。
- 对于 KVM 和其他管理程序,它提供预计算的 MSR 35h 值,解决内核在
-cpu host下的 kernel panic。 - 对于英特尔 CPU 来说,它通过将核心数与线程数打补丁的方式,增加了对非对称 SMP 系统(例如:Intel Alder Lake)的支持,同时还补充了所需的补充修改(10.14以上)。当使用 10.4 时,还提供了缓存大小和缓存行大小的值,因为 Intel Penryn 和更新的产品可能只有 CPUID leaf 0x4 中的缓存信息,而 10.4 是不支持的。
20. SetApfsTrimTimeout
Type: plist integer
Failsafe: -1
Requirement: 10.14 (not required for older)
Description: 为 SSD 上的 APFS 文件系统设置微秒级的 trim 超时时间。
APFS 文件系统的设计方式是,空间由 Spaceman (The Space Manager) 结构控制,要么为已使用,要么为空闲。而其他文件系统,则可以被标记为 已使用、空闲 或 未映射。macOS 启动时,所有空闲的空间都会被 trim 处理。由于 DSM 命令的特性,每个命令最多拥有 256 个范围,因此 NVMe 驱动器的 trim 过程发生在 LBA 范围内。硬盘上存储的内容越分散,就需要越多的命令对所有空闲空间进行 trim。
Trim 过程耗时取决于 SSD 控制器和硬盘碎片,可能需要相当长的时间,导致启动时间肉眼可见地变长,APFS 驱动程序忽略之前未映射的区域,并在启动时一次又一次地对这些区域进行 trim。为了解决开机速度慢的问题,macOS 驱动引入了一个超时时间(9.999999 秒)来中止未能及时完成的 trim 操作。
在一些控制器上(如三星)解除分配的过程较慢,很容易达到超时时间。从本质上讲,这意味着碎片级别很高,macOS 会尝试 trim 之前已经解除分配的低位区块,但永远没有足够的时间去解除分配高位区块。这意味着这些 SSD 安装后不久,trim 指令就会不起作用,导致闪存的额外损耗,甚至损坏。
解决这个问题的方法之一是将超时时间设置为一个非常高的值(例如:4294967295),这样将会以较长的启动时间(数分钟)为代价来确保所有的区块都被 trim 处理。另一种方法是利用超额配置(如果支持),或者创建一个专用的未映射分区,控制器可以在该分区中找到保留块。在这种情况下,可以设置一个非常低的超时时间来禁止 trim 操作,例如:999。更多细节详见 这篇文章。
注 1:Failsafe -1 表示不应用此补丁,这样 apfs.ext 将保持不动。
注 2:在 macOS 12.0 及以上版本中,不再可能指定 trim 超时时间。但可以通过设置为 0 来禁用 trim。
注 3:trim 操作只在启动阶段受到影响,当启动卷被加载时。无论是指定超时时间,或者设置为 0 完全禁用 trim,都不会影响正常的 MacOS 运行。
译者注:设置为
0完全禁用 trim 只影响进入系统的启动阶段,对系统启动之后无影响。设置为0或999基本上没有差别,主要是 macOS 12.0 及以上版本,只有设置为0才能禁用 trim。
21. ThirdPartyDrives
Type: plist boolean
Failsafe: false
Requirement: 10.6 (not required for older)
Description: 修补 IOAHCIDeleteStorage.kext,为第三方驱动器启用 TRIM、硬盘休眠等功能。
注:NVMe SSD 通常无需这一修改。对于 AHCI SSD(如 SATA SSD),macOS 从 10.15 开始提供 trimforce,可以将 01 00 00 00 值写入 APPLE_BOOT_VARIABLE_GUID 命名空间中的 EnableTRIM 变量。
22. XhciPortLimit
Type: plist boolean
Failsafe: false
Requirement: 10.11 (not required for older)
Description: 修补 AppleUSBXHCI.kext、AppleUSBXHCIPCI.kext、IOUSBHostFamily.kext 以移除 15 端口限制。
注:请尽可能避免使用这一选项。USB 端口数量限制是由 locationID 的 bit 决定的,想要移除限制就需要对操作系统进行大量修改。真正长期有效的解决方案是限制可用的 USB 端口个数在 15 以下(通过 USB 定制的方法)。详细信息请参考AppleLife.ru。
7.9 Scheme 属性
这些属性对于旧版 macOS 操作系统尤为重要。更多关于如何安装此类 macOS 及相关排错的详细信息,请参考 旧版 Apple 操作系统。
1. CustomKernel
Type: plist boolean
Failsafe: false
Description: 使用位于 ESP 分区下的 Kernels 目录下的定制内核缓存。
不支持的平台,包括 Atom 和 AMD,需要修改的 XNU 内核版本才能启动。这个选项提供了使用定制内核缓存的可能性,其中包含来自 ESP 分区的这种修改。
2. FuzzyMatch
Type: plist boolean
Failsafe: false
Description: 在可用时使用校验值不同的 kernelcache。
在 macOS 10.6 和更早的版本中,kernelcache 文件名有一个校验值,本质上是对 SMBIOS 产品名称和 EfiBoot 设备路径进行 adler32 校验和的计算。在某些固件上,由于 ACPI 或硬件的特殊性,UEFI 和 macOS 的 EfiBoot 设备路径不同,使得 kernelcache 的校验和总是不同。
这一设置可以在无后缀的 kernelcache 不可用时,将最新的 kernelcache 与合适的架构进行匹配,从而提高 macOS 10.6 在多个平台上的启动性能。
3. KernelArch
Type: plist string
Failsafe: Auto (自动选择首选架构)
Description: 如果可用,优先选择指定的内核架构(i386, i386-user32, x86_64)。
macOS 10.7 和更早版本中,XNU 内核可能不会使用 x86_64 架构来启动。当 macOS 和配置支持时,该设置将使用指定的架构来启动 macOS:
i386— 如果可用,则使用i386(32 位)内核。i386-user32— 在可用的情况下使用i386(32 位)内核,并在 64 位处理器上强制使用 32 位用户空间(前提是系统支持)。- 在 macOS 上,64 位处理器会被认为支持
SSSE3指令集,但对于较老的 64 位奔腾处理器来说,实际情况并非如此,因此会导致一些应用程序在 macOS 10.6 上崩溃。该行为对应-legacy内核启动参数。 - 由于 XNU 内核中存在一段未被初始化的 64 位片段,导致 AppleEFIRuntime 错误地将 64 位代码作为 16 位来执行,因此该选项对于 64 位固件上运行的 10.4 和 10.5 系统是不可用的。
- 在 macOS 上,64 位处理器会被认为支持
x86_64— 如果可用,则使用x86_64(64 位)内核。
下面是确定内核架构的计算过程:
arch参数位于映像参数(比如从 UEFI Shell 启动时)或boot-args变量中,覆盖兼容性检查,强制指定架构,并完成此计算过程。- 对于 32 位 CPU Variant,OpenCore 会将架构兼容性限制在
i386和i386-user32模式。 - 确定 EfiBoot 版本所限制的架构:
- 10.4-10.5 —
i386或i386-user32(仅限用于 32 位固件) - 10.6 —
i386、i386-user32或x86_64 - 10.7 —
i386或x86_64 - 10.8 及更新的版本 —
x86_64
- 10.4-10.5 —
- 如果
KernelArch被设置为Auto,并且 CPU 不支持SSSE3指令集, 则兼容性会被限制为i386-user32(如果 EfiBoot 支持的话)。 - 主板标识符(来自 SMBIOS)基于 EfiBoot 版本,如果有任何
i386的 CPU Variant 与之兼容,就会在不支持的机型上禁用x86_64架构。Auto不参与这个过程,因为在 EfiBoot 中,该列表是不可覆盖的。 - 当没有设置为
Auto时,KernelArch会把系统支持限制在明确指定的架构(如果该架构兼容)。 - 按以下顺序选择参数可以获得最佳的架构支持:
x86_64、i386、i386-user32。
macOS 10.7 只会将特定的主板标识符视为仅 i386 架构的设备,macOS 10.5 或更早版本的内核则不支持 x86_64,而 macOS 10.6 非常特殊,与这二者都不同。macOS 10.6 上的架构选择取决于很多因素,不仅包括主板标识符,还包括 macOS 的类型(客户端 或 服务器端)、macOS 发布时间和内存容量。检测这些因素很复杂,也不实用,因为好几个发布版本都有 bug,不能在第一时间正确地进行服务器检测。因此,对于 macOS 10.6,无论主板支持情况如何,OpenCore 都会回退到 x86_64 架构,就像 macOS 10.7 那样。以下是 64 位 Mac 型号的兼容性介绍,对应于 macOS 10.6.8 和 10.7.5 EfiBoot 的实际行为:
| Model | 10.6 (minimal) | 10.6 (client) | 10.6 (server) | 10.7 (any) |
|---|---|---|---|---|
| Macmini | 4,x (Mid 2010) | 5,x (Mid 2011) | 4,x (Mid 2010) | 3,x (Early 2009) |
| MacBook | Unsupported | Unsupported | Unsupported | 5,x (2009/09) |
| MacBookAir | Unsupported | Unsupported | Unsupported | 2,x (Late 2008) |
| MacBookPro | 4,x (Early 2008) | 8,x (Early 2011) | 8,x (Early 2011) | 3,x (Mid 2007) |
| iMac | 8,x (Early 2008) | 12,x (Mid 2011) | 12,x (Mid 2011) | 7,x (Mid 2007) |
| MacPro | 3,x (Early 2008) | 5,x (Mid 2010) | 3,x (Early 2008) | 3,x (Early 2008) |
| Xserve | 2,x (Early 2008) | 2,x (Early 2008) | 2,x (Early 2008) | 2,x (Early 2008) |
注:不支持用热键 3+2 和 6+4 来选择偏好架构,这是因为这个热键是由 EfiBoot 处理的,很难正确地检测到。
3. KernelCache
Type: plist string
Failsafe: Auto
Description: 如果可用,优先选择指定的内核缓存(Kernel Cache)类型(Auto, Cacheless, Mkext, Prelinked)。
macOS 的版本不同,支持的内核缓存变量也不同,其目的是提高启动性能。如果出于调试和稳定性的考虑,可利用这个设置防止使用较快的内核缓存变量。举个例子,如果指定 Mkext,那么会为 10.6 禁用 Prelinked,10.7 则不受影响。
可用的内核缓存类型及其当前在 OpenCore 中的支持情况列表如下:
| macOS | i386 NC | i386 MK | i386 PK | x86_64 NC | x86_64 MK | x86_64 PK | x86_64 KC |
|---|---|---|---|---|---|---|---|
| 10.4 | YES | YES (V1) | NO (V1) | — | — | — | — |
| 10.5 | YES | YES (V1) | NO (V1) | — | — | — | — |
| 10.6 | YES | YES (V2) | YES (V2) | YES | YES (V2) | YES (V2) | — |
| 10.7 | YES | — | YES (V3) | YES | — | YES (V3) | — |
| 10.8-10.9 | — | — | — | YES | — | YES (V3) | — |
| 10.10-10.15 | — | — | — | — | — | YES (V3) | — |
| 11+ | — | — | — | — | — | YES (V3) | YES |
注:不支持第一个版本(V1)的 32 位 prelinkedkernel ,因为 Kext 符号表被工具破坏了,在这个版本中 Auto 会阻止 prelinkedkernel 启动。同时,这也会使 keepsyms=1 在这些系统上不可用。