OpenCore 安装教程

· · 个人记录

介绍

1.1 OpenCore 简介

OpenCore 是一个非常好用的黑苹果(在非 Mac 上安装的 macOS 系统)工具。OpenCore 是类似于 Clover 的 UEFI 的引导器,OpenCore 提供了详细的日志系统,帮助黑苹果排错;其次 OpenCore 以更先进的方法注入第三方 Kext ,不破坏系统的 SIP ;再次,OpenCore 支持读取 NVRAM 等一系列特性,可以让黑苹果变得更“原生”,诸如选择启动器、Command Ctrl 互换,原生开启Option 键特性都可以实现。

现在 OpenCore 逐渐兴起,取代了老式而复杂的 Clover。即使这样,OpenCore 的学习成本也非常高,官方给出的教程也是英文版的。本人花费数天为大家编写了一套完整的 OpenCore 教程,本人亲测可以成功安装,本教程有深度,需要一定基础(建议不了解 macOS 启动机制和一些内部运转方法的人先在网上了解一下)。有一些专业术语,在 1.2 里面会讲到。

1.2 OpenCore 的优缺点

这个部分简要地概述了为什么社区正在向 OpenCore 过渡,而且目的是为了消除一些在社区中的错误观念。如果你只是想安装 macOS,可以跳过此页面。

OpenCore 的功能

软件支持

有人想从其他引导加载程序转换到 OpenCore 的最大原因实际上是软件支持:

内核扩展注入

为更好地理解 OpenCore 的内核扩展注入系统,我们需要先看一看 Clover 是怎样工作的:

  1. 使用补丁将系统完整性保护开放
  2. 使用布丁启用 XNU 的僵尸代码以进行内核扩展注入
  3. 修复注入内核扩展需要的竞态条件
  4. 注入内核扩展
  5. 使用补丁还原系统完整性保护

Clover 的方式中需要注意的地方:

现在来看看 OpenCore 的方式:

  1. 将现有的预链接的内核和内核扩展准备好注入
  2. 在带有新内核扩展的情况下重建 EFI 源内部的缓存
  3. 加入新的缓存

OpenCore 的方式中需要注意的地方:

OpenCore 的缺点

实际上大部分的 Clover 功能在 OpenCore 的一些类型的设置项中都被支持,然而当需要过渡到 OpenCore 时你应该着重关注 OpenCore 没有的功能是否会影响到你自己:

1.2 通用术语

配置

2.1 配置处理

如果 OpenCore 发现了 OC Config,则至少会读取并处理一次。根据 OpenCore 的引导机制的不同,如果存在多个 OC Config 文件,OpenCore 可能会读取其中任何一个或数个。如果硬盘中没有 OC Config,OpenCore 将会使用可选值和无效值的规则。

OC Config 有大小、嵌套和键值数量的限制。OC Config 的大小不得超过 16 MB,嵌套层数不得超过 8 层,每个 plist object 中最多有 16384 个节点(一个 plist dictionary 将被计为一对节点)。不符合上述规则的 OC Config 文件将可能导致未定义、非预期的行为。常见的 OC Config 错误格式包括:

我们建议(但非强制)遇到格式错误的 OC Config 时中止、当作 OC Config 不存在的情况来处理。为了能够向前兼容,我们建议(但非强制)对采用无效值的行为进行警告。采用无效值的建议做法是在使用的情况下遵守以下规则:

Type Value
plist string Empty string (<string></string>)
plist data Empty data (<data></data>)
plist integer 0 (<integer>0</integer>)
plist boolean False (<false/>)
plist tristate False (<false/>)

2.2 配置结构

OC Config 包括以下几个独立部分,将在本文档中分别进行介绍。默认情况下配置文件将尽可能不启用任何功能以及禁用某些功能。总的来说,这些配置一般由如下的操作构成:

配置文件分为以下几个独立部分:

设置

3.1 目录结构

ESP
├── EFI
│    ├── BOOT
│    │    └── BOOTx64.efi
│    └── OC
│        ├── ACPI
│        │    ├── DSDT.aml
│        │    ├── SSDT-1.aml
│        │    └── MYTABLE.aml
│        ├── Drivers
│        │    ├── MyDriver.efi
│        │    └── OtherDriver.efi
│        ├── Kexts
│        │    ├── MyKext.kext
│        │    └── OtherKext.kext
│        ├── Resources
│        │    ├── Audio
│        │    ├── Font
│        │    ├── Image
│        │    └── Label
│        ├── Tools
│        │    └── Tool.efi
│        ├── OpenCore.efi
│        ├── config.plist
│        ├── vault.plist
│        └── vault.sig
├── boot
├── nvram.plist
├── opencore-YYYY-MM-DD-HHMMSS.txt
├── panic-YYYY-MM-DD-HHMMSS.txt
└── SysReport

Figure 1: 目录结构

使用目录引导时,使用的目录结构应该遵循上述目录结构。可用的条目有:

: 受限于固件的实现行为,OpenCore 可能无法访问绝对路径长度大于 OC_STORAGE_SAFE_PATH_MAX(默认值为 128)的目录。

3.2 安装和升级

如果要安装 OpenCore,请在使用 GPT 格式的硬盘上、按照上一节的文件夹结构建立文件和文件夹。尽管本文档的相应部分的确提供了有关你所需的外部资源(如 ACPI 表、UEFI 驱动程序或 kexts)的某些信息,但是本文档不保证会提供关于这些外部资源的全部信息。关于 kext 的完整信息可以查看由 OpenCore 提供的 可选 kext 列表;而本文档也在安全属性的相关章节提供了 Vauting 的相关信息。

OpenCore 的配置文件可以使用任何常规的文本编辑器(如 nano、vim、VSCode)进行编辑,但是专用软件可以带来更好的体验。在 macOS 上我们推荐使用 Xcode。你也可以使用 ProperTree ,这是一个轻量级的跨平台的开源 plist 编辑器。

如果要通过 BIOS 进行开机,你必须使用第三方 UEFI 环境提供程序。OpenDuetPkg 是一个常用的为旧操作系统提供 Legacy 引导的 UEFI 环境提供程序。要在这样的旧操作系统上运行 OpenCore,你可以使用一个独立的工具 BootInstall 安装 OpenDuetPkg(目前已和 OpenCore 打包在一起发布)。

如果要升级 OpenCore,Differences.pdf 提供了 OpenCore 配置文件变更的相关信息,Changelog.md 提供了 OpenCore 的更新日志。

3.3 贡献代码

OpenCore 可以作为普通的 EDK II 进行编译。由于 TianoCore 放弃了对 UDK 的开发,因此 OpenCore 需要使用 EDK II Stable。目前支持的 EDK II 版本托管在 acidanthera/audk。软件包所需的补丁在 Patches 目录下。

XCODE5 是官方唯一支持的工具链。使用其他工具链虽然也有可能正常工作,但我们的态度是既不推荐、也不支持。也欢迎贡献一些干净、简洁的补丁,代码规范务必遵循 EDK II C Codestyle。

要使用 XCODE5 编译,除了 Xcode 之外,还需要安装 NASM 和 MTOC。建议使用最新的 Xcode 版本,不必因为工具链叫 XCODE5 而纠结于 Xcode 的版本号。命令行举例如下:

git clone --depth=1 https://github.com/acidanthera/audk UDK
cd UDK
git submodule update --init --recommend-shallow
git clone --depth=1 https://github.com/acidanthera/OpenCorePkg
source edksetup.sh
make -C BaseTools
build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc

Listing 1: 编译指令

对于 IDE 的用法,Xcode 项目可在资源库的根目录下使用。还有一种方法是使用 Sublime Text 并带有 EasyClangComplete 插件。在你的 UDK 根目录下添加类似内容的 .clang_complete 文件:

-I/UefiPackages/MdePkg
-I/UefiPackages/MdePkg/Include
-I/UefiPackages/MdePkg/Include/X64
-I/UefiPackages/OpenCorePkg/Include/AMI
-I/UefiPackages/OpenCorePkg/Include/Acidanthera
-I/UefiPackages/OpenCorePkg/Include/Apple
-I/UefiPackages/OpenCorePkg/Include/Apple/X64
-I/UefiPackages/OpenCorePkg/Include/Duet
-I/UefiPackages/OpenCorePkg/Include/Generic
-I/UefiPackages/OpenCorePkg/Include/Intel
-I/UefiPackages/OpenCorePkg/Include/Microsoft
-I/UefiPackages/OpenCorePkg/Include/VMware
-I/UefiPackages/OvmfPkg/Include
-I/UefiPackages/UefiCpuPkg/Include
-IInclude
-include
/UefiPackages/MdePkg/Include/Uefi.h
-fshort-wchar
-Wall
-Wextra
-Wno-unused-parameter
-Wno-missing-braces
-Wno-missing-field-initializers
-Wno-tautological-compare
-Wno-sign-compare
-Wno-varargs
-Wno-unused-const-variable
-DOC_TARGET_NOOPT=1
-DNO_MSABI_VA_FUNCS=1

Listing 2: ECC 配置</em></center><br>

警告:工具开发人员修改 config.plist 或其他任何 OpenCore 文件时,都务必检查 opencore-version NVRAM 变量(详见后面的 Debug Properties 章节),如果版本号不支持或尚未发布,则需警告用户。OpenCore 配置可能因版本不同而改变,因此工具开发应仔细遵循本文档,否则可能会当作恶意软件并阻止发布。

3.4 代码约定

和其他项目一样,我们在开发过程中也有一些约定。强烈建议所有第三方贡献者在提交补丁之前仔细阅读并遵循以下约定。另外,我们也建议在发送补丁之前先在 Acidanthera Bugtracker 里讨论一下,以免与其他人的工作重复,导致你的补丁被拒绝。

组织结构。代码库包含在 OpenCorePkg 仓库中,它是主要的 EDK II 软件包。

设计。代码库是使用独立的 C11 (C17) 子集编写的,能够被 EDK II 使用的大多数较新的工具链支持。如果下面没有讨论特殊情况,建议使用常见的软件开发操作,或者另附解释说明。

代码规范。代码库遵循 EDK II codestyle,并作了些许改动和解释。

排错。代码库中加入了 EDK II 调试和一些自定义功能,以改善体验。

当试图找到有问题的更改时,依靠 git-bisect 功能会很有帮助。另外还有一些非官方资源,提供了按照逐条 Commit 更新的 OpenCore 编译文件,如 Dortania。

ACPI

4.1 简介

ACPI(Advanced Configuration and Power Interface,高级配置和电源接口)是发现和配置计算机硬件的开放标准。 ACPI 规格 定义了实现用的标准表(如 DSDTSSDTFACSDMAR)和各种方法(如 _DSM_PRW)。现代硬件几乎不需要更改即可保持 ACPI 兼容性,但是 OpenCore 仍然提供了修改 ACPI 的方法。

要反汇编和编译 ACPI 表,可以使用由 ACPICA 开发的 iASL compiler。你可以从 Acidanthera/MaciASL 下载 iASL 的图形界面程序。

对 ACPI 的修补按照如下顺序执行:

为了解决操作系统检测的问题,所有对 ACPI 的更改会在所有操作系统上生效。但是在某些场景下(ACPI 编写不规范、操作系统链式引导启动、ACPI 调试)会出现问题。因此在修补 ACPI 时,需要使用 \_OSI 方法。

在系统引导前加载补丁使得编写「代理」补丁成为可能 —— 「代理」补丁即通过重命名的方法修补 DSDT 中的原始行为,然后通过 SSDT 注入同名的行为进行替代。

OpenCore、WhateverGreen、VirtualSmc、VoodooPS2 的 GitHub 仓库中都包含了部分 SSDT 和其他 ACPI 修补的方法。在 AppleLife 的 Laboratory 版块、DSDT 版块提供了不少教程和样例(如 笔记本电池修补教程)。Dortania 也编写了许多 ACPI 有关的教程。但是请注意,这些教程和 OpenCore 无关,他们提供的解决方法也不一定有用。

对于中国黑苹果玩家,强烈推荐 OC-little 项目,提供了众多 SSDT 范例和相关指导;笔记本用户电池修补请参考 这篇教程。

4.2 属性列表

1. Add

Type: plist array Failsafe: Empty Description: 从 OC/ACPI 目录加载指定的 ACPI 表。

设计为用 plist dict 值填充以描述每个块级项目。请参阅下面 4.3 Add 属性 章节。

2. Delete

Type: plist array Failsafe: Empty Description: 从 ACPI 栈中删除选定的表。

设计为用 plist dict 值填充以描述每个块级项目。请参阅下面 4.4 Delete 属性 章节。

3. Patch

Type: plist array Failsafe: Empty Description: 在添加或删除 ACPI 表之前执行的二进制修补。

设计为用 plist dictionary 值填充以描述每个块级项目。请参阅下面 4.5 Patch 属性 章节。

4. Quirks

Type: plist dict Description: 应用下文 4.6 Quirks 属性 章节中描述的 Quirks。

4.3 Add 属性

1. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

2. Enabled

Type: plist boolean Failsafe: false Description: 除非此值为 true,否则此 ACPI 表不会被添加。

3. Path

Type: plist string Failsafe: Empty string Description: 需要加载的 ACPI 表所在的路径。示例值如 DSDT.amlSubDir/SSDT-8.amlSSDT-USBX.aml

所有 ACPI 表都从 OC/ACPI 目录加载,加载顺序遵循数组中的项目顺序。

: 除具有 DSDT 表标识符(由解析得到的数据、而非由其文件名决定)的表外,所有表都将作为新表插入 ACPI 栈。而 DSDT 表与其余的表不同,将会执行 DSDT 表的替换。

4.4 Delete 属性

1. All

Type: plist boolean Failsafe: false Description: 如果设置为 true,则所有符合条件的 ACPI 表都会被舍弃。 否则,只舍弃第一个匹配到的。

2. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

3. Enabled

Type: plist boolean Failsafe: false Description: 除非此值为 true,否则此 ACPI 表不会被舍弃。

4. OemTableId

Type: plist data, 8 bytes Failsafe: All zero Description: 将表的 OEM ID 匹配为此处所填的值,全部为 0 时忽略。

5. TableLength

Type: plist integer Failsafe: 0 Description: 将表的大小匹配为此处所填的值,填 0 时忽略。

6. TableSignature

Type: plist data, 4 bytes Failsafe: All zero Description: 将表的签名匹配为此处的值,全部为 0 时忽略。

:当序列需要在多处替换的时候,务必注意不要指定表的签名,尤其是在进行不同类型的重命名操作的时候。

4.5 Patch 属性

1. Base

Type: plist string Failsafe: Empty string Description: 为重命名补丁指定一个 ACPI 路径,让 OC 通过取得该路径的偏移量来查找(或替换)重命名补丁。留空时忽略。

只有正确的绝对路径被支持(例如:\_SB.PCI0.LPCB.HPET)。目前支持的 Object 类型有:DeviceFieldMethod

:应谨慎使用,并非所有 OEM 的 ACPI 表都能被正确处理。如果遇到问题,可使用 Utilities 中的 ACPIe 工具来进行调错。使用 DEBUG=1 参数来编译 ACPIe 将会使该工具输出有助于调试的 ACPI 路径查找过程。

2. BaseSkip

Type: plist integer Failsafe: 0 Description: 在重命名补丁被应用之前跳过多少次 Base 指定的路径。如果将此值设置为 0,补丁将会被应用于指定 Base 中的所有匹配。

3. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

4. Count

Type: plist integer Failsafe: 0 Description: 补丁应用的次数。如果将此值设置为 0,补丁将会被应用于所有匹配。

5. Enabled

Type: plist boolean Failsafe: false Description: 除非设置为 true,否则此处的 ACPI 补丁不会生效。

6. Find

Type: plist data Failsafe: Empty data Description: 需要寻找的 Data,长度必须和 Replace 相等。

7. Limit

Type: plist integer Failsafe: 0 Description: 要搜索的最大字节数。当此值为 0 时会遍历整个 ACPI 表。

8. Mask

Type: plist data Failsafe: Empty data Description: 查找比较期间使用的数据按位掩码。 通过忽略未屏蔽(设置为零)位来进行模糊搜索。可以设置为空数据以忽略,否则此值的长度必须和 Replace 的长度相等。

9. OemTableId

Type: plist data, 8 bytes Failsafe: All zero Description: 将表的 OEM ID 匹配为此处所填的值,全部为 0 时忽略。

10. Replace

Type: plist data Failsafe: Empty data Description: 一个或多个字节的替换数据。

11. ReplaceMark

Type: plist data Failsafe: Empty data Description: 替换数据期间使用的数据按位掩码。 通过忽略未屏蔽(设置为零)位来进行模糊搜索。可以设置为空数据以忽略,否则此值的长度必须和 Replace 的长度相等。

12. Skip

Type: plist integer Failsafe: 0 Description: 完成替换之前要跳过的匹配数。

13. TableLength

Type: plist integer Failsafe: 0 Description: 将表的大小匹配为此处所填的值,填 0 时忽略。

14. TableSignature

Type: plist data, 4 bytes Failsafe: All zero Description: 将表的签名匹配为此处的值,全部为 0 时忽略。

大多数情况下,ACPI 补丁是有害而无益的:

在某些情况下,打补丁确实是有意义的:

TianoCore 源文件 AcpiAml.h 可能会对于理解 ACPI 操作码有所帮助。

FindReplace 的长度 必须完全一样,否则 ACPI 表可能会被破坏、导致系统不稳定。必要时请使用「代理」补丁的方法、或使用 NOP 填充剩余区域

4.6 Quirks 属性

1. FadtEnableReset

Type: plist boolean Failsafe: false Description: 在 FADT 表中提供寄存器复位标志,用于修复旧硬件的重启和关机。除非需要,否则不建议启用。

只有在传统硬件和少数笔记本上需要。这一 Quirk 也可以修复电源快捷键(译者注:<kbd>Command</kbd> + 电源键)。不建议启用,除非不启用就无法关机和重启。

2. NormalizeHeaders

Type: plist boolean Failsafe: false Description: 清理 ACPI 表头字段以解决 macOS ACPI 实现错误导致的引导崩溃。参考:由 Alex James(theracermaster)在调试 AppleACPIPlatform 时发现。从 macOS Mojave (10.14) 开始,这个错误已经被修复。

3. RebaseRegions

Type: plist boolean Failsafe: false Description: 尝试试探性地重定位 ACPI 内存区域。不建议启用这一选项,除非你需要自定义 DSDT。

ACPI 表通常由底层固件动态生成。在与位置无关的代码中,ACPI 表可能包含用于设备配置的 MMIO 区域的物理地址,通常按区域(例如 OperationRegion)分组。 更改固件设置或硬件配置,升级或修补固件不可避免地会导致动态生成的 ACPI 代码发生变化,这有时会导致上述 OperationRegion 结构中的地址发生变化。

因此,对 ACPI 表进行任何形式的修改都是非常危险的。最合理的方法是对 ACPI 进行尽可能少的更改,并尝试不替换任何表,尤其是 DSDT。

如果无法不得不替换 DSDT,则至少应尝试确保自定义 DSDT 基于最新的 DSDT 或避免对受影响区域的读写。如果没有其他帮助,可以尝试通过尝试修复 ACPI 地址来避免在 macOS 引导的 PCI Configuration Begin 阶段出现停顿的情况。

4. ResetHwSig

Type: plist boolean Failsafe: false Description: 将 FACS 表中 HardwareSignature 的值重置为 0

启用这一选项可以解决固件无法在重新启动过程中保持硬件签名导致的休眠唤醒问题。

5. ResetLogoStatus

Type: plist boolean Failsafe: false Description: 将 BGRT 表中 Displayed 状态字段重置为 false

这适用于提供 BGRT 表、但随后无法处理屏幕更新的固件。如果在开机时无法显示 OEM Windows 标志可以尝试开启。

Booter

5.1 简介

本部分允许在 Apple BootLoader(boot.efi)上应用不同种类的 UEFI 修改。目前,这些修改为不同的固件提供了各种补丁和环境更改。其中一些功能最初是作为 AptioMemoryFix.efi 的一部分,如今 AptioMemoryFix.efi 已经不再维护。如果你还在使用,请参考 技巧和窍门 章节提供的迁移步骤。

如果您是第一次在自定义固件上使用此功能,则首先需要执行一系列检查。开始之前,请确保您符合以下条件:

在调试睡眠问题时,可能需要(临时)禁用 Power Nap 和自动关闭电源,因为这二者似乎有时会导致旧的平台唤醒黑屏或循环启动。具体问题可能因人而异,但通常你应首先检查 ACPI 表,比如这是在 Z68 主板 上找到的一些 Bug。要关闭 Power Nap 和其他功能,请在终端中运行以下命令:

sudo pmset autopoweroff 0
sudo pmset powernap 0
sudo pmset standby 0

:这些设置可能会在硬件更改、操作系统更新和某些其他情况下重置。要查看它们的当前状态,请在终端中使用 pmset -g 命令。

5.2 属性列表

1. MmioWhitelist

Type: plist array Description: 设计为用 plist dict 值填充,用来描述在启用 DevirtualiseMmio 这个 Quirk 时特定固件能够运作的关键地址。详见下面的 MmioWhitelist 属性章节。

如果开机卡在 PCI... 可以尝试开启 Item 1 下的 Patch。

2. Patch

Type: plist array Failsafe: Empty Description: 在启动器中执行二进制补丁。

设计为用 plist dictionary 值填充,用来描述每个补丁。参加下面的 Patch 属性部分。

3. Quirks

Type: plist dict Description: 应用下面的 Quirks 属性部分中所述的各个引导 Quirk。

5.3 MmioWhitelist 属性

1. Address

Type: plist integer Failsafe: 0 Description: 指排除在外的 MMIO 地址,其内存描述符(Memory Descriptor)应被 DevirtualiseMmio 虚拟化(保持不变)。该值所在的区域会被分配一个虚拟地址,因此在操作系统运行期间,固件能够直接与该内存区域进行通信。

这里写入的地址必须是内存映射的一部分,具有 EfiMemoryMappedIO 类型和 EFI_MEMORY_RUNTIME 属性(最高 bit)。可以使用调试日志找到可能的地址。

2. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

3. Enabled

Type: plist boolean Failsafe: false Description: 设置为 true 时,所添加的地址将被虚拟化(保持不变)。

5.4 Patch 属性

1. Arch

Type: plist string Failsafe: Any Description: 启动器补丁架构(Any, i386, x86_64)。

2. Comment

Type: plist string Failsafe: Empty Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

3. Count

Type: plist integer Failsafe: 0 Description: 修补的次数,超过这一次数后便不再修补。0 表示修补所有查找到的地方。

4. Enabled

Type: plist boolean Failsafe: false Description: 除非设置为 true,否则将不会应用该补丁。

5. Find

Type: plist data Failsafe: Empty Description: 要查找的数据。必须与 Replace 的大小相等。

6. Identifier

Type: plist string Failsafe: Empty Description: Apple 代表 macOS 启动器(通常是 boot.efi);带有后缀的名称(如 bootmgfw.efi)代表特定的启动器;Any 或空字符串(默认)代表任何启动器。

7. Limit

Type: plist integer Failsafe: 0 Description: 搜索的最大字节数。可以设置为 0 来查找整个启动器。

8. Mask

Type: plist data Failsafe: Empty Description: 在查找比较的过程中使用数据位掩码。允许通过忽略未被屏蔽的 bit(设置为 0)进行模糊搜索。若留空则代表忽略,否则其大小必须等于 Find

9. Replace

Type: plist data Failsafe: Empty Description: 一个或多个字节的替换数据。

10. ReplaceMask

Type: plist data Failsafe: Empty Description: 替换时使用的数据位掩码。允许通过更新掩码(设置为非 0)来进行模糊替换。若留空则代表忽略,否则其大小必须等于 Replace

11. Skip

Type: plist integer Failsafe: 0 Description: 在替换前要跳过的发现事件数。

5.5 Quirks 属性

2. AllowRelocationBlock

Type: plist boolean Failsafe: false Description: 允许通过重定位块来启动 macOS。

重定位块(Relocation Block)是一个分配在低位 4GB 内存的缓冲区。EfiBoot 使用该这部分内存加载内核和相关结构,否则这部分区块会被「非运行时」数据(假定)所占用。在内核启动之前,重定位块的内容会被复制回位于低位的保留内存。同理,所有指向重定位块的其他内存地址也会作出相应调整。在下述情况中重定位块会被使用:

这个 Quirk 需要同时启用 ProvideCustomSlide(必需)和 AvoidRuntimeDefrag(通常情况下)。使用重定位块启动时不支持休眠(但启用这个 Quirk 并不意味着总是使用重定位块)。

:虽然某些低层内存被占用的平台需要这个 Quirk 来运行旧版 macOS 系统,但是这个 Quirk 并不兼容某些硬件及 macOS 11。这种情况下可能需要用 EnableSafeModeSlide 来替代。

2. AvoidRuntimeDefrag

Type: plist boolean Failsafe: false Description: 防止 boot.efi 运行时执行内存碎片整理。

这个选项通过提供对可变存储的支持,修复了包括日期、时间、NVRAM、电源控制等 UEFI Runtime 服务。

:除 Apple 和 VMware 固件外,都需要启用此选项。

3. DevirtualiseMmio

Type: plist boolean Failsafe: false Description: 从选定的 MMIO 区域中删除 Runtime 属性。

通过删除已知内存区域的 Runtime bit,此选项可减少内存映射中 Stolen Memory Footprint。 这个 Quirk 可能会使可用的 KASLR slide 增加,但如果没有其他措施,则不一定与目标主板兼容。 通常,这会释放 64 到 256 MB 的内存(具体数值会显示在调试日志中)。在某些平台上这是引导 macOS 的唯一方法,否则在引导加载程序阶段会出现内存分配错误。

该选项通常对所有固件都有用,除了一些非常古老的固件(例如 Sandy Bridge)。在某些固件上,可能需要一个例外映射列表。为了使 NVRAM 和休眠功能正常工作,获取其虚拟地址仍然是必要的。 请参考 MmioWhitelist 章节来实现。

对于某些 300 系列主板是必须的。

4. DisableSingleUser

Type: plist boolean Failsafe: false Description: 禁用 Apple 单用户模式。

这个选项可以禁用 CMD+S 热键和 -s 启动参数来限制单用户模式。启用这一 Quirk 后预期行为应和 T2 的机型行为类似。请参考 Apple 的 这篇文章(译者注:原文章已被关闭,此为网站时光机的存档副本)以了解如何在启用这一 Quirk 后继续使用单用户模式。

5. DisableVariableWrite

Type: plist boolean Failsafe: false Description: 防止 macOS 获取 NVRAM 的写入权限。

这个选项可以限制 macOS 对 NVRAM 的写入。这个 Quirk 需要 OpenRuntime.efi(原名 FwRuntimeServices.efi)提供了 OC_FIRMWARE_RUNTIME 协议的实现。

:这个 Quirk 也可以避免由于无法将变量写入 NVRAM 而导致的对操作系统的破坏。

在 Z390/HM370 等没有原生 macOS 支持 NVRAM 的主板上需要开启。

6. DiscardHibernateMap

Type: plist boolean Failsafe: false Description: 复用原始的休眠内存映射。

这一选项强制 XNU 内核忽略新提供的内存映射、认定设备从休眠状态唤醒后无需对其更改。如果你在使用 Windows,则 务必启用 这一选项,因为 Windows 要求 S4 唤醒后保留运行内存的大小和位置。

:这可能用于解决较旧硬件上的错误内存映射。如 Insyde 固件的 Ivy Bridge 笔记本电脑,比如 Acer V3-571G。除非您完全了解这一选项可能导致的后果,否则请勿使用此功能。

7. EnableSafeModeSlide

Type: plist boolean Failsafe: false Description: 修补引导加载程序以在安全模式下启用 KASLR。

这个选项与启动到安全模式(启动时按住 Shift 或用了 -x 启动参数)有关。默认情况下,安全模式会使用 slide=0,这个 Quirk 会试图通过修补 boot.efi 解除这一限制。只有当 ProvideCustomSlide 启用后才可以启用本 Quirks。

:除非启动到安全模式失败,否则不需要启用此选项。

8. EnableWriteUnprotector

Type: plist boolean Failsafe: false Description: 关闭 CR0 寄存器中的写入保护。

这个选项会在 UEFI Runtime Services 执行过程中,删除 CR0 寄存器中的写保护 WP bit,从而绕过其代码页的 RX 权限。这个 Quirk 需要配合 OpenRuntime.efi(原 FwRuntimeServices.efi)里的 OC_FIRMWARE_RUNTIME 协议来实现。

:这个 Quirk 可能会破坏你的固件的安全性。如果你的固件支持内存属性表 (MAT),请优先使用下文中的 RebuildAppleMemoryMap Quirk。是否支持 MAT,请参考 OCABC: MAT support is 1/0 日志条目来确定。

9. ForceExitBootServices

Type: plist boolean Failsafe: false Description: 在失败时用新的内存映射(Memory Map)重试 ExitBootServices

开启后会确保 ExitBootServices 即使在 MemoryMap 参数过期时也能调用成功,方法主要是获取当前的内存映射,并重试调用 ExitBootServices

:是否启用这个 Quirk 取决于你是否遇到了 Early Boot 故障。除非你详细了解这一选项可能导致的后果,否则请勿启用这一选项。

10. ProtectMemoryRegions

Type: plist boolean Failsafe: false Description: 保护内存区域免于不正确的读写。

有些固件会错误映射内存区域:

这一 Quirk 会尝试修复这些区域的类型,比如用 ACPI NVS 标记 CSM,MMIO 标记 MMIO。

:是否启用这一 Quirk 取决于你是否遇到了休眠、睡眠无法唤醒、启动失败或其他问题。一般来说,只有古董固件才需要启用。

11. ProtectSecureBoot

Type: plist boolean Failsafe: false Description: 保护 UEFI 安全启动变量不被写入。

尝试从操作系统写入 dbdbxPKKEK 时生成报告。

:这个 Quirk 主要试图避免碎片整理导致的 NVRAM 相关问题,如 Insyde 或 MacPro5,1

12. ProtectUefiServices

Type: plist boolean Failsafe: false Description: 保护 UEFI 服务不被固件覆盖。

某些现代固件(包括硬件和 VMware 之类的虚拟机)可能会在加载驱动及相关操作的过程中,更新 UEFI 服务的指针。这一行为会直接破坏其他影响内存管理的 Quirk,如 DevirtualiseMmioProtectMemoryRegions,或 RebuildAppleMemoryMap;也可能会破坏其他 Quirk,具体取决于 Quirk 的作用。

:在 VMware 上,是否需要开启这个 Quirk 取决于是否有 Your Mac OS guest might run unreliably with more than one virtual core. 这样的消息。

13. ProvideCustomSlide

Type: plist boolean Failsafe: false Description: 为低内存设备提供自定义 KASLR slide 值。

开启这个选项后,将会对固件进行内存映射分析,检查所有 slide(从 1255)中是否有可用的。由于 boot.efi 私用 rdrand 或伪随机 rdtsc 随机生成此值,因此有可能出现冲突的 slide 值被使用并导致引导失败。如果出现潜在的冲突,这个选项将会强制为 macOS 选择一个伪随机值。这同时确保了 slide= 参数不会被传递给操作系统。

:OpenCore 会自动检查是否需要启用这一选项。如果 OpenCore 的调试日志中出现 OCABC: Only N/256 slide values are usable! 则请启用这一选项。

14. ProvideMaxSlide

Type: plist integer Failsafe: 0 Description: 当更大的 KASLR slide 值不可用时,手动提供最大 KASLR slide 值。

ProvideCustomSlide 启用时,该选项通过用户指定的 1254(含)之间的值来覆盖上限为 255 的最大 slide 值。较新的固件会从上到下分配内存池中的内存,导致扫描 slide 时的空闲内存被当作内核加载时的临时内存来使用。如果这些内存不可用,启用这个选项则不会继续评估更高的 slide 值。

:当 ProvideCustomSlide 启用、并且随机化的 slide 落入不可用的范围时,如果出现随机的启动失败,则有必要开启这个 Quirk。开启 AppleDebug 时,调试日志通常会包含 AAPL: [EB|‘LD:LKC] } Err(0x9) 这样的信息。如果要找到最合适的值,请手动将 slide=X 追加到 boot-args 里,并用日志记录下不会导致启动失败的最大值。

15. RebuildAppleMemoryMap

Type: plist boolean Failsafe: false Description: 生成与 macOS 兼容的内存映射。

Apple 内核在解析 UEFI 内存映射时有几个限制:

为了解决这些限制,这个 Quirk 将内存属性表的权限应用到传递给 Apple 内核的内存映射中,如果生成的内存映射超过 4KiB,则可选择尝试统一类似类型的连续插槽。

注 1:由于许多固件自带的内存保护不正确,所以这个 Quirk 一般要和 SyncRuntimePermissions 一起启用。

注 2:根据是否遇到第一阶段启动失败再决定是否启用这一 Quirk。在支持内存属性表 (MAT) 的平台上,这一 Quirk 是 EnableWriteUnprotector 更好的替代。在使用 OpenDuetPkg 时一般是不需要启用这个 Quirk 的,但如果要启动 macOS 10.6 或更早的版本则可能需要启用,原因暂不明确。

16. SetupVirtualMap

Type: plist boolean Failsafe: false Description: 将 SetVirtualAddresses 调用修复为虚拟地址。

选择让固件在调用 SetVirtualAddresses 后通过虚拟地址访问内存,可能会导致 Early Boot 故障。这个 Quirk 可通过对分配的虚拟地址和物理内存进行 Early Boot 身份映射来解决这个问题。

:是否启用这个 Quirk 取决于你是否遇到了 Early Boot 故障。目前具有内存保护支持的新固件(例如 OVMF )由于一些原因不支持此 Quirk: acidanthera/bugtracker#719。

17. SignalAppleOS

Type: plist boolean Failsafe: false Description: 不论使用什么操作系统,总是向 OS Info 报告启动的是 macOS。

Mac 设备在不同的操作系统中具有不同的行为,因此如果你在使用 Mac 设备,这一功能会非常有用。例如,你可以通过启用这一选项为某些双 GPU 的 MacBook 型号中在 Windows 和 Linux 中启用 Intel GPU。

18. SyncRuntimePermissions

Type: plist boolean Failsafe: false Description: 更新运行时环境的内存权限。

某些固件无法正确处理运行时权限,表现为:

这个 Quirk 会通过更新内存映射和内存属性表来纠正这一问题。

:是否开启这一 Quirk 取决于是否遇到 Early Boot 故障。一般来说,只有 2017 年以后发布的固件才会受到影响。

DeviceProperties

6.1 简介

设备相关配置通过专用的缓存区(EfiDevicePathPropertyDatabase)提供给 macOS,这个缓冲区是设备路径到属性名称与值的键值对的序列化映射。

属性相关数据可以使用 gfxutil 进行调试。在 macOS 下获取当前属性数据请使用 ioreg

ioreg -lw0 -p IODeviceTree -n efi -r -x | grep device-properties |
  sed 's/.*<//;s/>.*//' > /tmp/device-properties.hex &&
  gfxutil /tmp/device-properties.hex /tmp/device-properties.plist &&
  cat /tmp/device-properties.plist

设备属性属于 macOS IO Registry 中的 IODeviceTree(gIODT) 层面,这个层面有很多与平台初始化相关的构建阶段(Construction Stage)。尽管早期的构建阶段是由 XNU 内核用 IODeviceTreeAlloc Method 来执行的,绝大部分仍然是由 Platform Expert 来构建、用 AppleACPIPlatformExpert.kext 来实现的。

AppleACPIPlatformExpert 包含了两个阶段的 IODeviceTree 构建,通过调用AppleACPIPlatformExpert::mergeDeviceProperties 来实现:

  1. 在 ACPI 表初始化过程中,通过调用 AppleACPIPlatformExpert::createDTNubs 递归扫描 ACPI 命名空间。
  2. 在 IOService 注册(IOServices::registerService)回调过程中,作为 AppleACPIPlatformExpert::platformAdjustService 函数和它私有的、针对 PCI 设备的 Worker Method AppleACPIPlatformExpert::platformAdjustPCIDevice 的一部分。

各阶段的应用取决于 ACPI 表中存在的设备。第一阶段适用于很早、但只适用于存在于 ACPI 表中的设备。第二阶段适用于所有晚于 PCI 配置的设备,如果设备没有出现在 ACPI 中,则会重复第一阶段。

所有的内核驱动可以在不探测设备的情况下检查 IODeviceTree 层面(例如 Lilu 和它的插件 WhateverGreen 等),因此确保 ACPI 表中的设备存在是尤其重要的。如果不这样做,则可能会因为注入的设备属性被忽略而导致各种不稳定的行为,原因是它们没有在第一阶段被构建出来。参见 SSDT-IMEI.dslSSDT-BRG0.dsl 的例子。

6.2 属性列表

1. Add

Type: plist dict Description: 将设备属性从设备路径的映射(plist dict)设置为变量名称和值的映射(plist dict),其中变量名称和值的格式为 plist metadata。设备路径必须以规范化字符串格式(Canonical String Format)提供,例如: PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)。添加的属性只有在不存在且未被屏蔽的情况下才会被设置。

:目前,属性只能通过原始驱动程序添加。因此除非安装了单独的驱动程序,否则没有理由 Delete 变量。

2. Delete

Type: plist dict Description: 从设备路径的映射(plist dict)到 plist string 格式的变量名数组(数据类型 plist array)中删除设备属性。

这里的设置等同于 Clover 里的 ACPI 重命名 _DSM → XDSM => TgtBridge

6.3 常见属性

一些常见的属性包括:

Kernel

7.1 简介

本章节介绍了如何在 Apple Kernel(XNU)上应用各种不同的内核空间修改,包括内核驱动程序(Kext)注入、修补以及屏蔽。

7.2 属性列表

1. Add

Type: plist array Failsafe: Empty Description: 从 OC/Kexts 目录加载选定的 Kext 驱动。

设计为使用 plist dict 数据填充以描述每个驱动程序。请参阅下述 Add 属性章节。Kext 驱动程序加载的顺序遵照数组中项目的顺序,因此如 Lilu 这种其他驱动程序的依赖驱动应该位于前面。

可以通过检查 Kext 驱动中 Info.plistOSBundleLibraries 值的方法来确定其依赖驱动的加载顺序。OSBundleLibraries 中的任何依赖驱动都必须在此 Kext 之前加载。

:Kext 驱动的内部可能也附带另外的 Kext (Plug-Ins),每个内部的 Kext 也都必须单独添加(参考下文 Add 属性章节)。

2. Block

Type: plist array Failsafe: Empty Description: 从 Prelinked Kernel 中移除选定的 Kext。

设计为使用 plist dict 数据填充以描述每个驱动程序。请参阅下述 Block 属性章节。Kext 驱动程序加载的顺序遵照数组中项目的顺序,因此如 Lilu 这种其他驱动程序的依赖驱动应该位于前面。

3. Emulate

Type: plist dict Description: 在内核空间中仿真选定的硬件。请参考下文 Emulate 属性。

4. Force

Type: plist array Failsafe: Empty Description: 如果内核驱动没有被缓存,则从系统卷宗强制加载内核驱动。

设计为使用 plist dict 值来填充,用于描述驱动程序。参见下面的 Force 属性部分。依赖其他驱动的驱动程序不能被缓存,该部分着重解决了这种驱动程序注入的难点。这个问题会映像到旧的操作系统,在旧的操作系统中存在各种依赖性的 Kext,比如 IOAudioFamilyIONetworkingFamily,可能默认不存在于内核缓存中。内核驱动的加载是有顺序的,因此依赖驱动应该排在前面。Force 发生在 Add

:「强制加载」的内核驱动不会被检查,因此,使用安全启动的同时使用这个功能是不可取的。另外,这个功能可能无法在较新的操作系统的加密分区上工作。

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 架构(Any, i386, x86_64)。

2. BundlePath

Type: plist string Failsafe: Empty string Description: Kext 相对于 EFI/OC/kexts/Other/ 的路径,如 Lilu.kextMyKext.kext/Contents/PlugIns/MySubKext.kext

VoodooPS2Controller.kext 这种包括其他 Kext 驱动的,需要分别单独添加,如 VoodooPS2Controller.kext/Contents/PlugIns/VoodooPS2Keyboard.kext

3. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

4. Enabled

Type: plist boolean Failsafe: false Description: 是否加载该驱动。

5. ExecutablePath

Type: plist string Failsafe: Empty string 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 对内核版本解释的实现方式如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-55s6AWeV-1655985958727)(/img/7-1.svg)]

内核版本比较的实现如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyUI563m-1655985958732)(/img/7-2.svg)]

将 Darwin 内核版本号字符串从左到右以 . 符号作为分隔符分割成三个整数,即为 ParseDarwinVersion 的三个参数。FindDarwinVersion 函数将会通过在内核镜像中查找形如 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Vg6OVVh-1655985958734)(/img/7-3.svg)] 的字符串来定位 Darwin 内核版本号。

7. MinKernel

Type: plist string Failsafe: Empty string Description: 在大于等于指定的 macOS 版本中添加该 Kext 驱动程序。

:匹配逻辑请参阅 Add MaxKernel 的描述。

以上两个属性定义了这个驱动将在什么版本范围的 macOS 中加载。留空表示在所有的 macOS 版本下都加载。

8. PlistPath

Type: plist string Failsafe: Empty string Description: Kext 中 Info.plist 文件的路径。一般为 Contents/Info.plist

7.4 Block 属性

1. Arch

Type: plist string Failsafe: Any Description: Kext block 架构(Any, i386, x86_64)。

2. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

3. Enabled

Type: plist boolean Failsafe: false Description: 除非设置为 true,否则这个内核驱动不会被加载。

4. Identifier

Type: plist string Failsafe: Empty string Description: Kext Bundle 标识符(比如 com.apple.driver.AppleTyMCEDriver)。

5. MaxKernel

Type: plist string Failsafe: Empty string Description: 在小于等于指定的 macOS 版本中阻止 Kext 驱动程序。

:匹配逻辑请参阅 Add MaxKernel 的描述。

6. MinKernel

Type: plist string Failsafe: Empty string Description: 在大于等于指定的 macOS 版本中阻止 Kext 驱动程序。

:匹配逻辑请参阅 Add MaxKernel 的描述。

7.5 Emulate 属性

1. Cpuid1Data

Type: plist data, 16 bytes Failsafe: All zero Description: EAXEBXECXEDX 值的序列,用来取代 XNU 内核中的 CPUID (1) 调用。

该属性主要应用于以下三种需求:

注 1:还有一种可能的情况,即 CPU 型号是支持的,但其电源管理不支持(比如虚拟机)。在这种情况下,可以通过设置 MinKernelMaxKernel 来限制特定 macOS 内核版本的 CPU 虚拟化和虚拟电源管理补丁。

注 2:通常来讲只需要处理 EAX 的值,因为它代表完整的 CPUID。剩余的字节要留为 0。字节顺序是小端字节序(Little Endian),比如 C3 06 03 00 代表 CPUID 0x0306C3 (Haswell)。

注 3:推荐使用下面的组合启用 XCPM 支持:

注 4:请记住,目前以下配置不被 XCPM 兼容(至少还没有人成功过):

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 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 架构(Any, i386, x86_64)。

2. BundlePath

Type: plist string Failsafe: Empty Description: Kext 路径,如 System/Library/Extensions/IONetworkingFamily.kext

3. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

4. Enabled

Type: plist boolean Failsafe: false Description: 是否加载该驱动。

5. ExecutablePath

Type: plist string Failsafe: Empty string Description: Kext 中实际可执行文件的路径,如 Contents/MacOS/IONetworkingFamily

6. Identifier

Type: plist string Failsafe: Empty string Description: Kext 标识符,以便在添加前检查是否存在,如 com.apple.iokit.IONetworkingFamily。只有在缓存中找不到标识符的驱动程序才会被添加。

7. MaxKernel

Type: plist string Failsafe: Empty string Description: 在小于等于指定的 macOS 版本中添加 Kext 驱动程序。

:匹配逻辑请参阅 Add MaxKernel 的描述。

8. MinKernel

Type: plist string Failsafe: Empty string Description: 在大于等于指定的 macOS 版本中添加 Kext 驱动程序。

:匹配逻辑请参阅 Add MaxKernel 的描述。

9. PlistPath

Type: plist string Failsafe: Empty string Description: Kext 中 Info.plist 文件的路径。一般为 Contents/Info.plist

7.7 Patch 属性

1. Arch

Type: plist string Failsafe: Any Description: Kext patch 架构(Any, i386, x86_64)。

2. Base

Type: plist string Failsafe: Empty string Description: 通过获取所提供的 Symbol 名称的地址,来选择 Symbol 匹配的 Base 进行补丁查找(或直接替换)。可以设置为空字符串以忽略。

3. Comment

Type: plist string Failsafe: Empty string 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 data Description: 需要查找的数据。可留空,在 Base 处直接替换。若不留空,其大小必须等于 Replace

7. Identifier

Type: plist string Failsafe: Empty string Description: Kext Bundle 标识符(如 com.apple.driver.AppleHDA)或内核补丁的 kernel

8. Limit

Type: plist integer Failsafe: 0 Description: 搜索的最大字节数。可以设置为 0 来查找整个 Kext 或内核。

9. Mask

Type: plist data Failsafe: Empty data 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。

某些固件会锁定 PKG_CST_CONFIG_CONTROL MSR 寄存器。可以使用附带的 VerifyMsrE2 工具检查其状态。

由于现代固件已经提供了 CFG Lock 相关设置、从而可以配置 PKG_CST_CONFIG_CONTROL 寄存器锁定,此选项应该尽可能避免。对于一些不显示 CFG Lock 配置的固件,可以按照下述配置进行修改:

  1. 下载 UEFITool 和 IFR-Extractor
  2. 使用 UEFITool 中打开固件镜像文件,找到 CFG Lock 的 Unicode 字符串。如果你没有找到,意味着你的固件可能不支持 CFG Lock 解锁,那么你现在可以停下来了。
  3. 从 UEFITool 菜单中的 Extract Body 选项提取 Setup.bin 中的 PE32 镜像部分。
  4. 对提取出来的文件执行 IFR-Extractor(./ifrextract Setup.bin Setup.txt)。
  5. 从 Setup.txt 中找到 CFG Lock, VarStoreInfo (VarOffset/VarName):,记住紧随其后的偏移量值(例如 0x123)。
  6. 下载并执行由 brainsucker 编译的 修改版 GRUB Shell。你也可以使用 datasone 制作的 新版 GRUB Shell。
  7. 在 GRUB Shell 中,使用 setup_var 0x123 0x00(其中 0x123 应该被替换为你在前几步找到的偏移值),然后重启电脑。

{% note danger 警告 %} 可变偏移量对于每个主板乃至每一个固件版本都是唯一的。永远不要尝试使用别人的偏移量! {% endnote %}

2. AppleXcpmCfgLock

Type: plist boolean Failsafe: false Requirement: 10.8 (not required for older) Description: 禁用 XNU 内核对 PKG_CST_CONFIG_CONTROL (0xE2) 修改,从而避免早期 Kernel Panic。

:这一选项应该避免被使用,请参考上文中关于 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. CustomSMBIOSGuid

Type: plist boolean Failsafe: false Requirement: 10.4 Description: 对 UpdateSMBIOSMode 自定义模式执行 GUID 修补,通常用于戴尔笔记本电脑。

6. DisableIoMapper

Type: plist boolean Failsafe: false Requirement: 10.8 (not required for older) Description: 禁用 XNU (VT-d) 中的 IOMapper 支持,这可能与固件的实现相冲突。

:相比直接在 ACPI 表中删除 DMAR,我们更推荐大家使用这一选项。这样不会破坏其他操作系统中的 VT-d 支持(总会有人需要用到的,对吧?)。

7. DisableLinkeditJettison

Type: plist boolean Failsafe: false Requirement: 11.0 Description: 禁止丢弃 __LINKEDIT

这个选项能让 Lilu.kext 和其他一些功能在 macOS Big Sur 中以最佳性能运行,而不需要 keepsyms=1 启动参数。

8. DisableRtcChecksum

Type: plist boolean Failsafe: false Requirement: 10.4 Description: 禁用 AppleRTC 初始校验和(0x58 - 0x59)写入。

注 1:这个选项不能确保其他区域不被覆盖,如有需要,请使用 RTCMemoryFixup。

注 2:这个选项不能确保区域在固件阶段不被覆盖(例如 macOS bootloader)。如有需要,请参阅 AppleRtcRam 协议描述。

9. ExtendBTFeatureFlags

Type: plist boolean Failsafe: false Requirement: 10.8 Description: 将 FeatureFlags 设置为 0x0F,以实现蓝牙的全部功能(包括连续互通功能)。

:由于原先的 BT4LEContinuityFixup.kext 的补丁过程较迟而不起作用,因此合并至 OpenCore 来替代 BT4LEContinuityFixup.kext

10. ExternalDiskIcons

Type: plist boolean Failsafe: false Requirement: 10.4 Description: 修补 AppleAHCIPort.kext 图标,使 macOS 将所有 AHCI 存储设备显示为内部硬盘。

:这一选项应尽量避免使用。现代固件通常情况下都是兼容的。

11. ForceSecureBootScheme

Type: plist boolean Failsafe: false Requirement: 11 Description: 强制采用 x86 方案进行 IMG4 核查。

:在虚拟机上使用 x86legacy 以外的 SecureBootModel 时需要开启此选项。

12. IncreasePciBarSize

Type: plist boolean Failsafe: false Requirement: 10.10 Description: 将 IOPCIFamily 中 32 位 PCI Bar 的大小从 1 GB 增加到 4 GB。

:你应该尽可能避免使用这一选项。通常这一选项只需要在配置错误或损坏的固件上开启。

如果你的 BIOS 中存在 Above4GDecoding 选项,请直接在 BIOS 中启用。

13. LapicKernelPanic

Type: plist boolean Failsafe: false Requirement: 10.6 (64-bit) Description: 禁用 LAPIC 中断导致的 Kernal Panic。

惠普电脑可能需要启用这一选项。

14. 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。

15. PanicNoKextDump

Type: plist boolean Failsafe: false Requirement: 10.13 (not required for older) Description: 在发生内核崩溃时阻止输出 Kext 列表,提供可供排错参考的崩溃日志。

16. PowerTimeoutKernelPanic

Type: plist boolean Failsafe: false Requirement: 10.15 (not required for older) Description: 修复 macOS Catalina 中由于设备电源状态变化超时而导致的内核崩溃。

macOS Catalina 新增了一项额外的安全措施,导致在电源切换超时的时候会出现 Kernel Panic。配置错误的硬件可能会因此出现问题(如数字音频设备)、有的时候会导致睡眠唤醒的问题。这一 Quirk 和引导参数 setpowerstate_panic=0 功能大部分一致,但是后者只应该用于调试用途。

17. 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。更多细节详见 这篇文章。

18. 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 变量。

19. XhciPortLimit

Type: plist boolean Failsafe: false Requirement: 10.11 (not required for older) Description: 修补 AppleUSBXHCI.kextAppleUSBXHCIPCI.kextIOUSBHostFamily.kext 以移除 15 端口限制。

:请尽可能避免使用这一选项。USB 端口数量限制是由 locationID 的 bit 决定的,想要移除限制就需要对操作系统进行大量修改。真正长期有效的解决方案是限制可用的 USB 端口个数在 15 以下(通过 USB 定制的方法)。

7.9 Scheme 属性

这些属性对于旧版 macOS 操作系统尤为重要。更多关于如何安装此类 macOS 及相关排错的详细信息,请参考 旧版 Apple 操作系统。

1. 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 在多个平台上的启动性能。

2. KernelArch

Type: plist string Failsafe: Auto Description: 如果可用,优先选择指定的内核架构(Auto, i386, i386-user32, x86_64)。

macOS 10.7 和更早的 XNU 内核可能不会使用 x86_64 架构来启动,具体选择取决于很多因素,包括启动参数、SMBIOS 以及操作系统类型。当 macOS 和配置支持时,该设置将使用指定的架构来启动 macOS:

下面是确定内核架构的计算过程:

  1. arch 参数位于映像参数(比如从 UEFI Shell 启动时)或 boot-args 变量中,覆盖兼容性检查,强制指定架构,并完成此计算过程。
  2. 对于 32 位 CPU Variant,OpenCore 会将架构兼容性限制在 i386i386-user32 模式。
  3. 确定 EfiBoot 版本所限制的架构:
    • 10.4-10.5 --- i386i386-user32(仅限用于 32 位固件)
    • 10.6 --- i386i386-user32x86_64
    • 10.7 --- i386x86_64
    • 10.8 及更新的版本 --- x86_64
  4. 如果 KernelArch 被设置为 Auto,并且 CPU 不支持 SSSE3 指令集, 则兼容性会被限制为 i386-user32(如果 EfiBoot 支持的话)。
  5. 主板标识符(来自 SMBIOS)基于 EfiBoot 版本,如果有任何 i386 的 CPU Variant 与之兼容,就会在不支持的机型上禁用 x86_64 架构。Auto 不参与这个过程,因为在 EfiBoot 中,该列表是不可覆盖的。
  6. 当没有设置为 Auto 时,KernelArch 会把系统支持限制在明确指定的架构(如果该架构兼容)。
  7. 按以下顺序选择参数可以获得最佳的架构支持:x86_64i386i386-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+26+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 在这些系统上不可用。

Misc

8.1 简介

本部分包含关于 OpenCore 行为的其他配置,以及不能被分类到其它章节的配置条目的说明。

OpenCore 尽可能地遵循 bless 模式,即 Apple Boot Policybless 模式的主要特点是允许在文件系统中嵌入启动选项(而且能通过专门的驱动程序访问),同时,相比于 UEFI 规范中的可移动媒体列表,它还支持更多的预定义启动路径。

只有当分区符合 Scan policy 时才能被启动(Scan policy 是一组限制条件,能够使其仅使用特定文件系统和特定设备类型的分区)。具体的扫描策略(Scan policy)将在下面的 ScanPolicy 属性中阐述。

扫描过程从获取 Scan policy 过滤过的分区开始。每个分区可能会产生多个主选项和备用选项。主选项描述的是安装在这个介质上的操作系统。备用选项描述的是介质上的操作系统的恢复项。备用选项可以在没有主选项的情况下存在,反之亦然。请注意,这些选项描述的操作系统不一定都在同一个分区上。每个主选项和备用选项都可以作为辅助选项(Auxiliary Option),也可以不作为辅助选项,具体细节参考下面的 HideAuxiliary 章节。用来确定启动选项的算法如下:

  1. 通过 Scan policy(和驱动可用性)过滤,获取所有可用的分区句柄。
  2. BootOrder UEFI 变量中,获取所有可用的启动选项。
  3. 对于每个找到的启动选项:
    • 检索该启动选项的设备路径。
    • 执行对设备路径的修复(如 NVMe 子类型修复)和扩展(如 Boot Camp)。
    • 通过定位到所产生的设备路径,来获取句柄(失败时忽略)。
    • 在分区句柄列表中找到设备句柄(缺失时忽略)。
    • 对磁盘设备路径(不指定引导程序)执行 bless(可能返回不止一个条目)。
    • 对文件设备路径直接检查其文件系统。
    • 在 OpenCore 启动分区中,通过 Header Check 排除所有 OpenCore Bootstrap 文件。
    • 如果有分区句柄列表,则在列表中将设备句柄标记为 used
    • 将生成的条目注册为主选项,并确定他们的类型。某些类型的选项作为辅助选项(如 Apple HFS Recovery)。
  4. 对于每个分区句柄:
    • 如果分区句柄被标记为 unused,则执行 bless 主选项列表检索。如果设置了 BlessOverride 列表,那么不仅能找到标准的 bless 路径,还能找到自定义的路径。
    • 在 OpenCore 启动分区中,通过 Header Check 排除所有 OpenCore Bootstrap 文件。
    • 将生成的条目注册为主选项,并确定他们的类型。某些类型的选项作为辅助选项(如 Apple HFS Recovery)。
    • 如果分区已经具有来 Apple Recovery 类型的主选项,则继续处理下一个句柄。
    • 通过 bless 恢复选项列表检索和预定义路径,来查找备用条目。
    • 将生成的条目注册为备用辅助选项,并确定它们的类型。
  5. 把自定义条目和工具添加为主选项,不做有关 Auxiliary 的任何检查。
  6. 把系统条目(如 Reset NVRAM)添加为主要的辅助选项。

启动选择器中的启动选项的显示顺序和启动过程,是通过扫描算法分别来确定的。显示顺序如下:

启动过程如下:

注 1:这个过程只有在启用了 RequestBootVarRouting 选项,或者固件不控制 UEFI 启动选项(如 OpenDuetPkg 或其他自定义 BDS)时,才会可靠地工作。如果不启用 LauncherOption,那么其他操作系统有可能会覆盖 OpenCore,如果你打算使用 OpenCore,请确保启用这个选项。

注 2:UEFI 变量引导选项的引导参数,如果存在的话则会被丢弃,因为它们包含的一些参数可能会对操作系统产生不利影响,一旦启用了安全引导,这种影响是我们不希望看到的。

注 3:某些操作系统(说的就是你,Windows)会在第一次启动时,或 NVRAM 重置后,创建他们的启动选项,并将其标记为最上面的选项。这种情况发生时,默认的启动条目选择将会更新,直到下一次重新手动配置。

8.2 属性列表

1. Boot

Type: plist dict Description: 应用本章节 Boot 属性中的引导相关设置。

2. BlessOverride

Type: plist array Description: 通过 Bless Model 添加自定义扫描路径。

设计为填充 plist string 条目,其中包含指向自定义引导程序的绝对 UEFI 路径,例如,用于 Debian 引导程序的 \EFI\debian\grubx64.efi。这允许引导选择器自动发现异常的引导路径。在设计上它们等效于预定义的 Bless 路径(如 \System\Library\CoreServices\boot.efi\EFI\Microsoft\Boot\bootmgfw.efi),但与预定义的 Bless 路径不同,它们具有最高优先级。

3. Debug

Type: plist dict Description: 应用本章节 Debug 属性中的调试相关设置。

4. Entries

Type: plist array Description: 在开机引导菜单中添加引导项。

应填入 plist dict 类型的值来描述相应的加载条目。详见 Entry 属性部分。

5. Security

Type: plist dict Description: 应用本章节 Security 属性中的安全相关设置。

6. Tools

Type: plist array Description: 将工具条目添加到开机引导菜单。

应填入 plist dict 类型的值来描述相应的加载条目。详见 Entry 属性部分。

:选择工具(比如 UEFI shell)是很危险的事情,利用这些工具可以轻易地绕过安全启动链,所以 千万不要 出现在生产环境配置中,尤其是设置了 Vault 和安全启动保护的设备(译者注:即,工具仅作调试用)。具体的工具示例参见本文档的 UEFI 章节。

8.3 Boot 属性

1. ConsoleAttributes

Type: plist integer Failsafe: 0 Description: 为控制台设置特定的属性。

根据 UEFI 规范,文本渲染器支持的颜色参数为前景色与背景色之和。黑色背景色和黑色前景色 (0) 的值是预留的。以下是颜色名称一览:

:这个选项可能和 TextRenderer 的 System 参数有冲突,设置一个非黑的背景可以用来测试 GOP 是否正常运行。

2. HibernateMode

Type: plist string Failsafe: None Description: 休眠检测模式。 支持以下模式:

:如果固件自身能处理休眠(大多数 Mac 的 EFI 固件都可以),你应该在此处设置为 None 来让固件处理休眠状态并传递给 OpenCore。

3. HideAuxiliary

Type: plist boolean Failsafe: false Description: 默认情况下,隐藏开机引导项菜单中的辅助条目。

满足任一以下条件的引导项条目即会被视为「辅助项目」

即使被隐藏,你仍然可以通过 空格 进入「扩展模式」查看所有条目(引导项菜单会被重新加载):

一般来说,隐藏辅助条目有助于加快启动速度。

4. LauncherOption

Type: plist string Failsafe: Disabled Description: 在固件偏好设置中注册启动器选项,以保证 bootloader 的持久与一致性。

有效值有:

在安装和升级第三方操作系统时 \EFI\BOOT\BOOTx64.efi 文件可能会被覆盖掉,该选项则保证了出现覆盖情况时 bootloader 的一致性。创建一个自定义启动项后,\EFI\BOOT\BOOTx64.efi 这个文件路径将不再用于引导 OpenCore。自定义的引导路径在 LauncherPath 选项中指定。

注 1:某些固件的 NVRAM 本身存在问题,可能会出现无启动项支持,或者其他各种不兼容的情况。虽然可能性不大,但使用此选项可能会导致启动失败。请在已知兼容的主板上使用,风险自行考虑。请查看 acidanthera/bugtracker#1222 来了解与 Haswell 及其他一些主板相关的已知问题。

注 2:虽然从 OpenCore 执行的 NVRAM 重置不会清除在 Bootstrap 模式中创建的启动选项,但在加载 OpenCore 之前重置 NVRAM 则会同时清除。在进行某些涉及重要实现的更新时(如 OpenCore 0.6.4),须确保在禁用 Bootstrap 的情况下执行一次 NVRAM 重置,然后再重新启用。

5. LauncherPath

Type: plist string Failsafe: Default Description: LauncherOption 的启动引导路径。

Default 用于引导 OpenCore.efi。其他的路径(如 \EFI\Launcher.efi)可用来提供自定义加载器,用于自行加载 OpenCore.efi

6. PickerAttributes

Type: plist integer Failsafe: 0 Description: 设置开机引导菜单的属性。

可以用属性掩码来设置引导菜单的不同属性,其中掩码包含 OpenCore 的预留值(BIT0 ~ BIT15)和 OEM 特定值(BIT16 ~ BIT31)。

目前 OpenCore 的预留值有:

7. PickerAudioAssist

Type: plist boolean Failsafe: false Description: 在开机引导菜单中启用 屏幕朗读。

macOS Bootloader 屏幕朗读 的偏好设置是存在 isVOEnabled.int32 文件的 preferences.efires 中、并受操作系统控制。这里仅提供一个等效的开关。切换 OpenCore 开机引导菜单和 macOS BootLoader FileVault 2 登录界面也可以使用快捷键 Command + F5

:屏幕朗读 依赖可以正常工作的音频设备。

8. PollAppleHotKeys

Type: plist boolean Failsafe: false Description: 在开机引导菜单中启用 Modifier Hotkey

除了 Action Hotkey(在 PickerMode 一节中有所描述,由 Apple BDS 处理),还有由操作系统 bootloader(即 boot.efi)处理的 Modifier Hotkey。这些键可以通过提供不同的启动模式来改变操作系统的行为。

在某些固件上,由于驱动程序不兼容,使用 Modifier Hotkey 可能会有问题。为了解决问题,这个选项允许你在启动选择器中以更宽松的方式注册选择的热键,比如:在按住 Shift 和其他按键的同时支持敲击按键,而不是只按 Shift,这在许多 PS/2 键盘上是无法识别的。已知的 Modifier Hotkey 包括:

9. ShowPicker

Type: plist boolean Failsafe: false Description: 是否显示开机引导菜单。

10. TakeoffDelay

Type: plist integer, 32 bit Failsafe: 0 Description: 在 处理引导项启动 和 处理 Action Hotkey 之前的延迟,以微秒为单位。

引入这一延迟有助于为你争取时间去完成按住 Action Hotkey 的操作,比如启动到恢复模式。在某些平台上,可能需要把此项设置为至少 5000-10000 来使 Action Hotkey 生效,具体取决于键盘驱动程序的性质。

11. Timeout

Type: plist integer, 32 bit Failsafe: 0 Description: 开机引导菜单中,启动默认启动项之前超时时间(以秒为单位)。 使用 0 禁用倒计时。

译者注:0 为关闭倒计时而非跳过倒计时,相当于 Clover 的 -1

12. PickerMode

Type: plist string Failsafe: Builtin Description: 选择启动管理器的界面。

这里描述的是具有可选用户界面的底层启动管理器,支持以下值:

External 模式一旦成功,就会完全禁用 OpenCore 中的除策略强制执行的所有其他启动管理器,而 Apple 模式下可以绕过策略的强制执行。请参阅 ueficanopy 插件以了解自定义用户界面的实例。

OpenCore 内置的启动选择器包含了一系列在启动过程中选择的操作。支持的操作与 Apple BDS 类似,一般来说能够通过在启动过程中按住 Action Hotkey 来实现,目前有以下几种:

注 1:需要激活 KeySupportOpenUsbKbDxe 或类似的驱动程序才能工作。无法获得全部按键功能的固件有很多。

注 2:当禁用 ShowPicker 时,除了 OPT 键之外,OpenCore 还支持 Escape 键来显示启动选项。这个键不仅适用于 Apple 启动选择器模式,也适用于 PS/2 键盘的固件,因为这种键盘无法提交按住 OPT 键的请求,需要连续点按 Escape 键来进入启动选择菜单。

注 3:有些 Mac 的 GOP 很棘手,可能很难进入 Apple 启动选择器。还有一些 Mac,BootKicker 不能从 OpenCore 运行。可以通过直接 bless BootKicker 实用工具来解决这个问题,不需要加载 OpenCore。

13. PickerVariant

Type: plist string Failsafe: Auto Description: 选择启动管理器所使用的图标集。

支持以下值:

8.4 Debug 属性

1. AppleDebug

Type: plist boolean Failsafe: false Description: 启用将 boot.efi 调试日志保存到 OpenCore 日志。

:此项仅适用于 10.15.4 和更新版本。

2. ApplePanic

Type: plist boolean Failsafe: false Description: 将 macOS Kernel Panic 保存到 OpenCore 根分区。

保存的文件为 panic-YYYY-MM-DD-HHMMSS.txt。强烈建议使用 keepsyms=1 引导参数来查看 Panic 日志中的调试符号。如果没有,可以用 kpdescribe.sh 实用工具(OpenCore 绑定)来部分恢复堆栈跟踪。

开发者内核和调试内核会产生更有用的 Kernel Panic。调试的时候,可以考虑从 developer.apple.com 下载并安装 KernelDebugKit。如果要激活开发者内核,需要添加一个 kcsuffix=development 引导参数。使用 uname -a 命令来确保你当前加载的内核是一个开发者(或调试)内核。

如果没有使用 OpenCore 的 Kernel Panic 保存机制,仍然可以在 /Library/Logs/DiagnosticReports 目录下找到 Panic 日志。从 macOS Catalina 开始,Kernel Panic 会以 JSON 格式储存,所以在传递给 kpdescribe.sh 之前需要预处理:

cat Kernel.panic | grep macOSProcessedStackshotData | python -c 'import json,sys;print(json.load(sys.stdin)["macOSPanicString"])'

3. DisableWatchDog

Type: plist boolean Failsafe: false Description: 某些固件启动操作系统的速度可能不够快(尤其是调试模式下),看门狗定时器会因此中止引导过程。此选项用来关闭看门狗定时器。

4. DisplayDelay

Type: plist integer Failsafe: 0 Description: 屏幕上打印每行输出之间的延迟。

5. DisplayLevel

Type: plist integer, 64 bit Failsafe: 0 Description: 与屏幕显示相关的 EDK II 调试级别的位掩码(总和)。除非 Target 启用了控制台在屏幕上输出日志,否则屏幕上的调试输出将不可见。支持以下级别(更多信息参见 DebugLib.h):

6. SerialInit

Type: plist boolean Failsafe: false Description: 执行串行端口初始化。

该选项会在任何调试日志启用之前,初始化 OpenCore 的串行端口设置。串行端口配置是在编译时,在 gEfiMdeModulePkgTokenSpaceGuid GUID 中通过 PCD 来定义的。MdeModulePkg.dec 中的默认值如下:

具体细节见 Debugging 部分。

7. SysReport

Type: plist boolean Failsafe: false Description: 在 EFI 分区中保存系统报告。

启用这一选项后,EFI 分区中将会新建一个 SysReport 目录。这一目录中将会保存 ACPI、SMBIOS 和音频编解码器的调试信息。保存音频编解码器信息需要加载音频后端驱动。

:基于安全的考虑,RELEASE 构建的 OpenCore 将不会内置这一功能。如果需要使用这一功能请使用 DEBUG 构建版。

8. Target

Type: plist integer Failsafe: 0 Description: 启用日志记录目标的位掩码(总和)。默认所有日志的输出都是隐藏的,所以当需要调试时,有必要设置这个选项。

支持以下日志记录目标:

控制台日志会比其他日志少,根据 build 类型(RELEASEDEBUGNOOPT)的不同,读取到的日志量也会不同(从最少到最多)。

Data Hub 日志中不包括 Kernel 和 Kext 的日志。要获取 Data Hub 日志,请使用 ioreg:

ioreg -lw0 -p IODeviceTree | grep boot-log | sort | sed 's/.*<\(.*\)>.*/\1/' | xxd -r -p

UEFI 变量日志中不包含某些信息,也没有性能数据。为了安全起见,日志大小被限制在 32 KB。有些固件可能会提前截断它,或者在它无内存时完全删除它。使用非易失性 flag 将会在每打印一行后把日志写入 NVRAM 闪存。如要获取 UEFI 变量日志,请在 macOS 中使用以下命令:

nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:boot-log | awk '{gsub(/%0d%0a%00/,"");gsub(/%0d%0a/,"\n")}1'

{% note danger 警告 %} 有些固件的 NVRAM 垃圾收集据说存在问题,它们可能无法做到在每次变量删除后都释放空间。在这类设备上,没有额外需要的话,请不要使用非易失性 NVRAM 日志。 {% endnote %}

虽然 OpenCore 的引导日志已经包含了基本的版本信息(包括 build 类型和日期),但即使在禁用引导日志的情况下,这些数据也可以在 NVRAM 中的 opencore-version 变量中找到。

文件记录会在 EFI 卷宗的根目录下创建一个名为 opencore-YYYY-MM-DD-HHMMSS.txt 的文件,其中包含了日志的内容(大写字母部分会被替换为固件中的日期和时间)请注意,固件中的一些文件系统驱动程序不可靠,并且可能会通过 UEFI 写入文件时损坏数据。因此,OpenCore 会尝试用最安全同时也是最慢的方式来写入日志。当你在使用慢速存储驱动器时,请确保已将 DisableWatchDog 设置为 true。如果你在使用 SSD,应该尽量避免使用这一选项,大量的 I/O 操作会很快耗尽 SSD 的寿命。

注意,每一行日志都包含有一个描述日志类型的前缀,从而确定该行日志的归属。以下是已知的前缀列表:

Drivers and tools:

Libraries:

8.5 Security 属性

1. AllowNvramReset

Type: plist boolean Failsafe: false Description: 启用这一选项后将允许使用 CMD+OPT+P+R 快捷键重置 NVRAM,同时 NVRAM Reset 条目也会出现在开机引导菜单中。

注 1:据说部分联想笔记本存在固件 bug,执行 NVRAM 重置后无法启动。更多细节请参见 acidanthera/bugtracker#995。

注 2:重置 NVRAM 后,未经过 bless 工具备份过的开机项(如 Linux)会被全部删除。

译者注:BootCamp Windows 因为符合 bless 模型而不受影响。

2. AllowSetDefault

Type: plist boolean Failsafe: false Description: 允许使用 CTRL+EnterCTRL+[数字] 设置默认启动项。

3. AllowToggleSip

Type: plist boolean Failsafe: false Description: 在 OC 的启动项中加入一个切换 SIP (System Integrity Protection) 的选项。

这会在 Apple 的 NVRAM 变量 csr-active-config 中,从 0 ,即启用 SIP,和一个禁用 SIP 的值,目前是 0x26F 之间切换。

注1:强烈不推荐将 macOS 运行在禁用 SIP 的状态下。使用这一个启动选项有助于在需要的情况下快速的禁用 SIP,当操作完成后应当将 SIP 再次启用。

注2:尽管在 Big Sur 中,csrutil disable 命令会将值设置为 0x7F,OC 依然使用 0x26F 这个值,因为:

注3:对于其他你可能用到的值,你可以将 CsrUtil.efi 配置为一个 TextMode Tools 启动项来指定不同的参数,例如,将参数设置为 0x6F 来将禁用 SIP 的值设置为 Big Sur 中 csrutil disable --no-internal 的默认值。

4. ApECID

Type: plist integer, 64 bit Failsafe: 0 Description: Apple Enclave 标识符。

将此值设置为任何非零的 64 位整数,将允许使用个性化的 Apple 安全启动标识符。如果你想使用此设置,请确保使用加密的随机数生成器生成一个 64 位的随机数。还有一种方法是将 SystemUUID 的前 8 个字节用于 ApECID,没有 T2 芯片的 Mac 的 macOS 11 就是这样做的。

如果这个值设置妥当,并且 SecureBootModel 值有效且不是 Disabled,那么就可以实现 Apple 安全启动的 完整安全性。

要使用个性化的 Apple 安全启动,必须重新安装操作系统,或对其进行个性化定制。在操作系统被个性化定制之前,只能加载 macOS DMG 恢复镜像。DMG 恢复镜像可以随时用 macrecovery 实用工具下载,然后放到 com.apple.recovery.boot 里,如 技巧和窍门 部分所述。请记住,DmgLoading 需要设置为 Signed 才能通过 Apple 安全启动来加载 DMG。

如果要对现有的操作系统进行个性化定制,请在加载 macOS DMG 恢复镜像之后使用 bless 命令。确保已挂载到系统卷分区,并执行以下命令:

bless bless --folder "/Volumes/Macintosh HD/System/Library/CoreServices" \
  --bootefi --personalize

macOS 11 为没有 T2 芯片的 Mac 引入了专用的 x86legacy 机型,对于 macOS 11.0 之前的版本,这个机型的 Apple 安全启动可能无法达到预期效果。如果要使用个性化的 Apple 安全启动重新安装操作系统,请记住,当前版本的 macOS 安装器(测试版本 10.15.6)通常会把 /var/tmp 分区的可用内存耗尽,因此在 macOS 安装器镜像下载后不久,就会出现 Unable to verify macOS 的错误信息。为了解决这个问题,需要在开始安装前,在 macOS Recovery 终端输入如下命令,为 macOS 个性化分配一个 2MB 的专用 RAM 磁盘:

disk=$(hdiutil attach -nomount ram://4096)
diskutil erasevolume HFS+ SecureBoot $disk
diskutil unmount $disk
mkdir /var/tmp/OSPersonalizationTemp
diskutil mount -mountpoint /var/tmp/OSPersonalizationTemp $disk

5. AuthRestart

Type: plist boolean Failsafe: false Description: 启用与 VirtualSMC 兼容的 authenticated restart。

authenticated restart 可以在重启 FileVault2 分区时不用再次输入密码。你可以使用下述指令执行一次 authenticated restartsudo fdesetup authrestart。macOS 在安装系统更新使用的也是 authenticated restart

VirtualSMC 通过将磁盘加密密钥拆分保存在 NVRAM 和 RTC 中来执行 authenticated restart。虽然 OpenCore 在启动系统后立刻删除密钥,但是这仍然可能被视为安全隐患。

6. BlacklistAppleUpdate

Type: plist boolean Failsafe: false Description: 忽略某些用于更新 Apple 外设固件的启动项(如 MultiUpdater.efi)。

:由于某些操作系统(如 macOS Big Sur)无法利用 NVRAM 变量 run-efi-updater 禁用固件更新,因此单独设立了此项。

7. DmgLoading

Type: plist string Failsafe: Signed Description: 定义用于 macOS Recovery 的磁盘映像(Disk Image, DMG)加载策略。

有效值如下:

8. EnablePassword

Type: plist boolean Failsafe: false Description: 为敏感操作启用密码保护。

启动非默认操作系统(如 macOS Recovery 或工具)、启动到非默认模式(如详细模式或安全模式)或重置 NVRAM 等,以上这些行为属于敏感操作,密码保护可以很好地保证这些操作都是由本人或授权人操作。目前,密码和盐(Salt)用 5000000 次 SHA-512 迭代来进行哈希运算。

:此功能尚在开发阶段,不推荐日常使用。

9. ExposeSensitiveData

Type: plist integer Failsafe: 0x6 Description: 用于向操作系统暴露敏感数据的位掩码(总和)。

根据加载顺序,暴露的启动器路径指向 OpenCore.efi 或其引导器。如要获得引导器路径,请在 macOS 中使用以下命令:

nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:boot-path

如要使用启动器路径加载启动器卷宗,请在 macOS 中使用以下命令:

u=$(nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:boot-path | sed 's/.*GPT,\([^,]*\),.*/\1/'); \
if [ "$u" != "" ]; then sudo diskutil mount $u ; fi

如要获取 OpenCore 版本信息,请在 macOS 中使用以下命令:

nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:opencore-version

如要获取 OEM 信息,请在 macOS 中使用以下命令:

nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-product # SMBIOS Type1 ProductName
nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-vendor # SMBIOS Type2 Manufacturer
nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-board # SMBIOS Type2 ProductName

10. HaltLevel

Type: plist integer, 64 bit Failsafe: 0x80000000 (DEBUG_ERROR) Description: EDK II 调试级别的位掩码(总和),使 CPU 在获得 HaltLevel 消息后中止(停止执行)。可能的值与 DisplayLevel 值相匹配。

11. PasswordHash

Type: plist data 64 bytes Failsafe: all zero Description: 密码使用的哈希值(Hash)。

12. PasswordSalt

Type: plist data Failsafe: empty Description: 密码使用的盐值(Salt)。

13. Vault

Type: plist string Failsafe: Secure Description: 启用 OpenCore 的 Vault 机制。

有效值:

vault.plist 文件应该包含 OpenCore 使用的所有文件的 SHA-256 哈希值。强烈建议使用这个文件,以确保无意中的文件修改(包括文件系统损坏)不会被忽视。要自动创建这个文件,请使用 create_vault.sh 脚本。无论底层的文件系统如何,路径名和大小写必须在 config.plistvault.plist 之间相匹配。

vault.sig 文件应该包含一个来自 vault.plist SHA-256 哈希值的原始的 256 字节 RSA-2048 签名。这个签名是根据嵌入到 OpenCore.efi 中的公钥来验证的。如要嵌入公钥,以下任一步骤均可:

RSA 公钥的 520 字节格式可参阅 Chromium OS 文档。如要从 X.509 证书或 PEM 文件中转换公钥,请使用 RsaTool。

以下操作的完整指令:

可以参照如下指令:

cd /Volumes/EFI/EFI/OC
/path/to/create_vault.sh .
/path/to/RsaTool -sign vault.plist vault.sig vault.pub
off=$(($(strings -a -t d OpenCore.efi | grep "=BEGIN OC VAULT=" | cut -f1 -d' ')+16))
dd of=OpenCore.efi if=vault.pub bs=1 seek=$off count=528 conv=notrunc
rm vault.pub

注 1:必须使用外部方法来验证 OpenCore.efiBOOTx64.efi 的安全启动路径,尽管它们看似显而易见。为此,建议你至少使用自定义证书来启用 UEFI 的 SecureBoot,并使用自定义的密钥来签名 OpenCore.efiBOOTx64.efi 。关于在现代固件上定制安全启动的更多细节,请参见 Taming UEFI SecureBoot(俄文)。

注 2:当 vault.plist 存在,或者当公钥嵌入到 OpenCore.efi 中的时候,无论这个选项是什么,vault.plistvault.sig 都会被使用。设置这个选项仅仅会确保配置的合理性,否则启动过程会中止。

14. ScanPolicy

Type: plist integer, 32 bit Failsafe: 0xF0103 Description: 定义操作系统检测策略。

通过设置该值来根据所选 flag 的位掩码(总和)防止从非信任源扫描(和启动)。由于不可能可靠地检测到每一个文件类型或设备类型,因此在开放环境中不能完全依赖此功能,需要采取额外的措施。

第三方驱动程序可能会根据提供的扫描策略引入额外的安全(和性能)措施。扫描策略暴露在 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102 GUID的 scan-policy 变量中,仅适用于 UEFI 启动服务。

:举例:根据以上描述,0xF0103 值允许扫描带有 APFS 文件系统的 SATA、SAS、SCSI 和 NVMe 设备,不扫描 USB、CD 和 FireWire 设备上的 APFS 文件系统,也不扫描任何带有 HFS 或 FAT32 文件系统的设备。该值表示如下组合:

15. SecureBootModel

Type: plist string Failsafe: Default Description: Apple 安全启动的机型。

定义 Apple 安全启动的机型和策略。指定此值能够定义哪些操作系统可以启动。早于指定机型发布时间的操作系统将无法启动。有效值如下:

Apple 安全启动最初出现于搭载 T2 芯片的机型上的 macOS 10.13。PlatformInfoSecureBootModel 是相互独立的,因此可以在任何 SMBIOS 上启用 Apple 安全启动。将 SecureBootModel 设置为除 Disabled 以外的任意有效值,相当于实现了 Apple 安全启动的 中等安全性。如要实现「完整安全性」,还需要指定 ApECID 值。

启用 Apple 安全启动的要求很多,任何不正确的配置、错误的 macOS 安装或者不支持的安装设置都可能会增加启用难度,记住以下几点:

有时,已安装的系统 Preboot 分区上的 Apple 安全启动清单是过时的,从而导致启动失败。如果你看到 OCB: Apple Secure Boot prohibits this boot entry, enforcing! 这样的信息,很可能就是出现了上述这种情况。想要解决这个问题,要么重新安装操作系统,要么把 /usr/standalone/i386 中的清单(扩展名为 .im4m 的文件,如 boot.efi.j137.im4m)复制到 /Volumes/Preboot/<UUID>/System/Library/CoreServices<UUID> 为系统卷的标识符)。HFS+ 文件系统则须复制到系统卷上的 /System/Library/CoreServices 目录。

关于如何结合 UEFI 安全启动来配置 Apple 安全启动的细节,请参考本文档 UEFI 安全启动 部分。

8.6 Entry 属性

1. Arguments

Type: plist string Failsafe: Empty string Description: 对该引导条目使用的引导参数。

2. Auxiliary

Type: plist boolean Failsafe: false Description: 当 HideAuxiliary 被启用时,这一值为 true 的引导条目将不会显示在开机引导菜单中。

3. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。

4. Enabled

Type: plist boolean Failsafe: false Description: 除非设置为 true,否则该引导条目不会显示在开机引导菜单中。

5. Flavour

Type: plist string Failsafe: Auto Description: 为该启动项指定 flavour,详见文档中的 OC_ATTR_USE_FLAVOUR_ICON 标识。

6. Name

Type: plist string Failsafe: Empty string Description: 引导条目在开机引导菜单中显示的名字。

7. Path

Type: plist string Failsafe: Empty string Description: 引导入口。

8. RealPath

Type: plist boolean Failsafe: false Description: 启动时将完整的路径传递给工具。

传递目录可能会使工具在没有检查文件完整性的情况下就意外地访问了文件,降低了安全性,因此通常应该禁用。需要启用该项的情况有:工具需要外部文件来正常工作;工具需要外部文件来更好地实现某些功能(如 memtest86 的记录和配置功能,Shell 自动执行脚本的功能)。

:此属性的开关仅对工具有效。对于 Entries 该属性始终为 true

9. TextMode

Type: plist boolean Failsafe: false Description: 以文本模式而非图形模式运行条目。

某些需要文本输出的旧工具需要用到此项。默认情况下所有工具都以图形模式启动。更多关于文本模式的内容,请参阅 Output 属性。

NVRAM

9.1 简介

设置易失性 UEFI 变量(通常被称作 NVRAM 变量),数据类型为 plist dict。使用 man nvram 获取详细信息。macOS 广泛使用 NVRAM 变量使 操作系统、BootLoader、固件 之间互通,因此需要提供多个 NVRAM 变量才能正常运行 macOS。

每个 NVRAM 变量均由其名称、值、属性(参考 UEFI 规范)以及 GUID 组成,表示 NVRAM 变量属于哪一区域。macOS 使用如下(包括但不限于)几种 GUID:

:某些变量可以通过 PlatformNVRAMPlatformInfo 节的 Generic 子节添加。请确保本节中的变量不会与它们发生冲突,否则可能导致未定义的行为。

为了使 macOS 正常运行,通常需要使用 OC_FIRMWARE_RUNTIME 协议。该协议的实现目前是 OpenRuntime(原名 FwRuntimeServices.efi)驱动程序的一部分。虽然可能带来一些好处,但根据用途不同也会存在某些限制。

9.2 属性列表

1. Add

Type: plist dict Description: 从一组 GUID 映射(plist dict)中读取格式为 plist metadata 的变量映射,并将其添加到 NVRAM 中。GUID 必须以 Canonical String 格式提供,大写或小写均可(如 8BE4DF61-93CA-11D2-AA0D-00E098032B8C)。

创建的变量会设置 EFI_VARIABLE_BOOTSERVICE_ACCESSEFI_VARIABLE_RUNTIME_ACCESS 的属性。变量只有在不存在且未被屏蔽的情况下才会被设置,也就是说,如果想要覆盖一个现有的变量值,请将该变量的名称添加到 Delete 部分,这种方法能够提供一个默认的值,直到操作系统接手为止。

:如果 plist key 不符合 GUID 格式,则可能出现一些未定义的行为。

2. Delete

Type: plist dict Description: 从一组 GUID 映射(plist dict)读取一组包含 plist string 的数组(plist array),这些将会被从 NVRAM 变量中被删除。

3. LegacyEnable

Type: plist boolean Failsafe: false Description: 允许从 ESP 分区的根目录中的 nvram.plist 文件读取 NVRAM 变量。

该文件必须以 plist dictionary 为文件根格式,并包含以下两个字段:

变量加载优先于 Delete(以及 Add)阶段。除非启用了 LegacyOverwrite,否则不会覆盖现有的任何变量。允许设置的变量必须指定于 LegacySchema 中。第三方脚本可以用来创建 nvram.plist 文件,脚本示例可参照 Utilities。使用第三方脚本可能要将 ExposeSensitiveData 设置为 0x3 来为 boot-path 变量提供 OpenCore EFI 分区的 UUID。

{% note danger 警告 %} 这一功能非常危险,因为会将不受保护的数据传递给固件中的变量服务。只有在你的硬件不提供硬件 NVRAM 或与之不兼容时才使用。 {% endnote %}

4. LegacyOverwrite

Type: plist boolean Failsafe: false Description: 允许用 nvram.plist 文件中的变量覆盖现有 NVRAM 中的变量。

:只有操作系统访问的到的变量会被覆盖。

5. LegacySchema

Type: plist dict Description: 允许从 GUID 映射(plist dict)中选择 NVRAM 变量设置到一个变量名称数组(plist array),格式为 plist string

可用 * 值来接受所有用来选择 GUID 的变量。

{% note danger 警告 %} 选择变量要非常慎重,因为 nvram.plist 不会被存储。比如,不要把 boot-argscsr-active-config 放进去,因为会绕过 SIP。 {% endnote %}

6. WriteFlash

Type: plist boolean Failsafe: false Description: 允许将所有添加的变量写入闪存。

:这个 Quirk 本应该在大多数固件上启用,但是由于可能存在 NVRAM 变量存储 GC 或类似的问题的固件,所以我们将这个 Quirk 设计为可配置的。

要从 macOS 中读取 NVRAM 变量的值,可以使用 nvram,并将变量 GUID 和名称用 : 符号隔开,形如 nvram 7C436110-AB2A-4BBB-A880-FE41995C9F82:boot-args

变量列表可参照相关文档(持续更新):NVRAM Variables。

9.3 必需变量

{% note danger 警告 %} 这些变量可通过 PlatformNVRAM 或 PlatformInfo 的 Generic 部分添加。推荐使用 PlatformInfo 来设置这些变量。 {% endnote %}

以下变量为 macOS 运行必需:

9.4 建议变量

建议使用以下变量来加快启动速度或改善其他表现:

9.5 其他变量

以下变量对于某些特定的配置或进行故障排除可能会很有用:

PlatformInfo

10.1 属性列表

1. Automatic

Type: plist boolean Failsafe: false Description: 基于 Generic 属性而不是 DataHubNVRAMSMBIOS 属性生成机型信息。

考虑到 Generic 部分的数据十分灵活,启用这个选项会很有用:

{% note danger 警告 %} 强烈不建议把此项设置为 false。只有在需要对 SMBIOS 进行小规模修正的情况下,才有理由不使用 Automatic,否则可能会导致 debug 困难。 {% endnote %}

2. CustomMemory

Type: plist boolean Failsafe: false Description: 使用在 Memory 部分所填写的自定义内存配置。该选项将完全取代 SMBIOS 中任何现有的内存配置,只有当 UpdateSMBIOS 设置为 true 时才生效。

3. UpdateDataHub

Type: plist boolean Failsafe: false Description: 更新 Data Hub 字段。根据 Automatic 的值,这些字段会从 GenericDataHub 中读取。

4. UpdateNVRAM

Type: plist boolean Failsafe: false Description: 是否更新 NVRAM 中关于机型信息的相关字段。

根据 Automatic 的值,这些字段会从 GenericPlatformNVRAM 中读取。所有其他字段都将在 NVRAM 部分中指定。

如果将此值设置为 false,则可以使用 nvram 部分更新上述变量;反之若将此值设置为 true,而同时 nvram 部分存在任何字段,会产生未定义行为。

5. UpdateSMBIOS

Type: plist boolean Failsafe: false Description: 更新 SMBIOS 字段。根据 Automatic 的值,这些字段会从 GenericSMBIOS 中读取。

6. UpdateSMBIOSMode

Type: plist string Failsafe: Create Description: 更新 SMBIOS 字段的方式有:

: 使用 Custom 有一个副作用(译者注:我怎么感觉是好事)使得 SMBIOS 设置只对 macOS 生效,避免了与现有的 Windows 激活和依赖机型的 OEM 设置的相关问题。不过,苹果在 Windows 下的特定工具(译者注:如 BootCamp for Windows)可能会受到影响。

7. UseRawUuidEncoding

Type: plist boolean Failsafe: false Description: 对 SMBIOS 的 UUID 使用原始编码。

基本上每个 UUID AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP 都是 16 字节的十六进制数字,编码方式有两种:

SMBIOS 规范没有明确规定 UUID 的编码格式,直到 SMBIOS 2.6 才说明应使用 Little Endian 编码,这就导致了固件实现和系统软件的双重混乱,因为在此之前不同的厂商使用不同的编码格式。

OpenCore 在生成修改过的 DMI 表时,总是设置最新的 SMBIOS 版本(目前是 3.2)。如果启用了 UseRawUuidEncoding,则使用 Big Endian 编码格式来存储 SystemUUID 数据,否则使用 Little Endian 编码格式。

:由于 DataHub 和 NVRAM 中使用的 UUID 是由 Apple 添加的,未经过标准化,所以这个选项并不会影响它们。与 SMBIOS 不同,它们总是以 Big Endian 编码格式存储。

7. Generic

Type: plist dictonary Description: 在 Automatic 模式下更新所有字段。

:当 Automaticfalse 时将自动忽略此部分,但不可将此部分整段删除。

8. DataHub

Type: plist dictonary Optional: Automatictrue 时可不填 Description: 在非 Automatic 模式下更新 Data Hub 字段。

:当 Automatictrue 时将自动忽略此部分,但不可将此部分整段删除。

9. Memory

Type: plist dictionary Optional: When CustomMemory is false Description: 用于设置自定义的内存配置。

:当 CustomMemoryfalse 时将自动忽略此部分,但不可将此部分整段删除。

10. PlatformNVRAM

Type: plist dictonary Optional: Automatictrue 时可不填 Description: 在非 Automatic 模式下更新 platform NVRAM 字段。

:当 Automatictrue 时将自动忽略此部分,但不可将此部分整段删除。

11. SMBIOS

Type: plist dictonary Optional: Automatictrue 时可不填 Description: 在非 Automatic 模式下更新 SMBIOS 字段。

:当 Automatictrue 时将自动忽略此部分,但不可将此部分整段删除。

10.2 Generic 属性

1. SpoofVendor

Type: plist boolean Failsafe: false Description: 将 SMBIOS 中的 Vendor 字段设置为 Acidanthera

由于在 SystemManufacturer 中阐述的原因,在 SMBIOS 的 Vendor 字段中使用 Apple 是危险的。但是,某些固件可能无法提供有效值,可能会导致某些软件的破坏。

2. AdviseWindows

Type: plist boolean Failsafe: false Description: 在 FirmwareFeatures 中强制提供 Windows 支持。

FirmwareFeatures 中添加如下 bit:

3. MaxBIOSVersion

Type: plist boolean Failsafe: false Description: 将 BIOSVersion 设置为 9999.999.999.999.999,建议使用 Automatic 选项的旧款 Mac 这样设置, 在运行非官方支持的 macOS 版本时可避免 BIOS 升级。

4. SystemMemoryStatus

Type: plist string Failsafe: Auto Description: 用来表示内存是否可以更换和升级,此值也控制着「关于本机」中「内存」选项卡的可见性。

有效值如下:

:在某些型号的 Mac 上,SPMemoryReporter.spreporter 会自动忽略 PT_FEATURE_HAS_SOLDERED_SYSTEM_MEMORY,并认为其内存是不可升级的,如 MacBookPro10,x 和所有的 MacBookAir

5. ProcessorType

Type: plist integer Failsafe: 0 (Automatic) Description: 请参考下文 SMBIOS 章节中的 ProcessorType

6. SystemProductName

Type: plist string Failsafe: OEM specified or not installed Description: 请参考下文 SMBIOS 章节中的 SystemProductName

7. SystemSerialNumber

Type: plist string Failsafe: OEM specified or not installed Description: 请参考下文 SMBIOS 章节中的 SystemSerialNumber

8. SystemUUID

Type: plist string, GUID Failsafe: OEM specified or not installed Description: 请参考下文 SMBIOS 章节中的 SystemUUID

9. MLB

Type: plist string Failsafe: OEM specified or not installed Description: 请参考下文 SMBIOS 章节中的 BoardSerialNumber

10. ROM

Type: plist data, 6 bytes Failsafe: OEM specified or not installed Description: 参考 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM

10.3 DataHub 属性

1. PlatformName

Type: plist string Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 name。在 Mac 上找到的值为 ASCII 码形式的 platform

2. SystemProductName

Type: plist string Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 Model。在 Mac 上找到的值等于 Unicode 形式的 SMBIOS SystemProductName

3. SystemSerialNumber

Type: plist string Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 SystemSerialNumber。在 Mac 上找到的值等于 Unicode 形式的 SMBIOS SystemSerialNumber

4. SystemUUID

Type: plist string, GUID Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 system-id。在 Mac 上找到的值等于 SMBIOS SystemUUID(字节顺序调换)。

5. BoardProduct

Type: plist string Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 board-id。在 Mac 上找到的值等于 ASCII 码形式的 SMBIOS BoardProduct

6. BoardRevision

Type: plist data, 1 byte Failsafe: 0 Description: 在 gEfiMiscSubClassGuid 中设置 board-rev。在 Mac 上找到的值似乎与 Internal Board Revision 相对应(如 01)。

7. StartupPowerEvents

Type: plist integer, 64-bit Failsafe: 0 Description: 在 gEfiMiscSubClassGuid Sets 中设置 StartupPowerEvents。在 Mac 上找到的值是 Power Management State 位掩码,通常为 0。X86PlatformPlugin.kext 能读取的已知 bit 有:

8. InitialTSC

Type: plist integer, 64-bit Failsafe: 0 Description: 在 gEfiProcessorSubClassGuid 中设置 InitialTSC。设置初始 TSC 值,通常为 0。

9. FSBFrequency

Type: plist integer, 64-bit Failsafe: 0 (Automatic) Description: 在 gEfiProcessorSubClassGuid 中设置 FSBFrequency

设置 CPU FSB 频率。此值等于 CPU 主频除以最高总线比率,以 Hz 为单位。请参考 MSR_NEHALEM_PLATFORM_INFO(CEh) MSR 值来确定 Intel CPU 的最高总线比率。

:此值虽然不是用于 Skylake 或更新的平台,但也可设置。

10. ARTFrequency

Type: plist integer, 64-bit Failsafe: 0 (Automatic) Description: 在 gEfiProcessorSubClassGuid 中设置 ARTFrequency

此值包含 CPU ART 频率,即晶体时钟频率。为 Skylake 或更新的平台独有,以 Hz 为单位。Client Intel segment 通常为 24 MHz,Server Intel segment 通常为 25 MHz,Intel Atom CPUs 通常为 19.2 MHz。macOS 10.15 及以下均默认为 24 MHz。

:由于 Intel Skylake X 平台特有 EMI-reduction 电路,其 ART 频率可能会比 24 或 25 MHz 有所损失(大约 0.25%)。参考 Acidanthera Bugtracker。

11. DevicePathsSupported

Type: plist integer, 32-bit Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 DevicePathsSupported。必须设置为 1 才能确保 AppleACPIPlatform.kext 将 SATA 设备路径添加到 Boot####efi-boot-device-data 变量。所有新款 Mac 都设置为 1

12. SmcRevision

Type: plist data, 6 bytes Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 REV。自定义属性由 VirtualSMCFakeSMC 读取,用于生成 SMC REV key。

13. SmcBranch

Type: plist data, 8 bytes Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 RBr。自定义属性由 VirtualSMCFakeSMC 读取,用于生成 SMC RBr key。

14. SmcPlatform

Type: plist data, 8 bytes Failsafe: Not installed Description: 在 gEfiMiscSubClassGuid 中设置 RPlt。自定义属性由 VirtualSMCFakeSMC 读取,用于生成 SMC RPlt key。

10.4 Memory 属性

1. DataWidth

Type: plist integer, 16-bit Failsafe: 0xFFFF (unknown) SMBIOS: Memory Device (Type 17) — Data Width Description: 指定内存的数据宽度,以位为单位。DataWidth0TotalWidth8 时,表示改设备仅用于提供 8 个纠错位。

2. Devices

Type: plist array Failsafe: Empty Description: 指定要添加的自定义内存设备。

plist dictionary 来描述每个内存设备,具体参见下面的 Memory Devices 属性部分。这里应该填写所有的内存插槽,包括没有插内存的插槽。

3. ErrorCorrection

Type: plist integer, 8-bit Failsafe: 0x03 SMBIOS: Physical Memory Array (Type 16) — Memory Error Correction Description: 指定内存支持的主要硬件纠错或检测方法。

4. FormFactor

Type: plist integer, 8-bit Failsafe: 0x02 SMBIOS: Memory Device (Type 17) — Form Factor Description: 指定内存的规格。在 Mac 上通常是 DIMM 或 SODIMM。下面列举的是一些常见的规格。

CustomMemory 设置为 false 时,该值会根据所设置的 Mac 机型自动设置。

5. MaxCapacity

Type: plist integer, 64-bit Failsafe: 0 SMBIOS: Physical Memory Array (Type 16) — Maximum Capacity Description: 指定系统支持的最大内存量,以字节为单位。

6. TotalWidth

Type: plist integer, 16-bit Failsafe: 0xFFFF (unknown) SMBIOS: Memory Device (Type 17) — Total Width Description: 指定内存的总宽度,以位为单位,包括任何检查或纠错位。如果没有纠错位,则这个值应该等于 DataWidth

7. Type

Type: plist integer, 8-bit Failsafe: 0x02 SMBIOS: Memory Device (Type 17) — Memory Type Description: 指定内存类型。常用的类型如下:

8. TypeDetail

Type: plist integer, 16-bit Failsafe: 0x4 SMBIOS: Memory Device (Type 17) — Type Detail Description: 指定附加的内存类型信息。

10.4.1 Memory Device 属性

1. AssetTag

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Asset Tag Description: 指定该内存的资产标签。

2. BankLocator

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Bank Locator Description: 指定内存设备所在的物理标签库。

3. DeviceLocator

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Device Locator Description: 指定内存设备所在的物理标签插槽或主板上的位置。

4. Manufacturer

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Manufacturer Description: 指定该内存设备的制造商。

5. PartNumber

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Part Number Description: 指定该内存设备的部件号。

6. SerialNumber

Type: plist string Failsafe: Unknown SMBIOS: Memory Device (Type 17) — Serial Number Description: 指定该内存设备的序列号。

7. Size

Type: plist integer, 32-bit Failsafe: 0 SMBIOS: Memory Device (Type 17) — Size Description: 指定内存设备的大小,以兆字节为单位。0 表示该插槽未插入内存。

8. Speed

Type: plist integer, 16-bit Failsafe: 0 SMBIOS: Memory Device (Type 17) — Speed Description: 指定设备的最大速度,单位为每秒百万传输量(MT/s)。0 表示未知速度。

10.5 PlatformNVRAM 属性

1. BID

Type: plist string Failsafe: Not installed Description: 指定 NVRAM 变量 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:HW_BID

2. ROM

Type: plist data, 6 bytes Failsafe: Not installed Description: 指定 NVRAM 变量 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:HW_ROM4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ROM

3. MLB

Type: plist string Failsafe: Not installed Description: 指定 NVRAM 变量 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:HW_MLB4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:MLB

4. FirmwareFeatures

Type: plist data, 8 bytes Failsafe: Not installed Description: 此变量与 FirmwareFeaturesMask 配对使用。指定 NVRAM 变量:

5. FirmwareFeaturesMask

Type: plist data, 8 bytes Failsafe: Not installed Description: 此变量与 FirmwareFeatures 配对使用。指定 NVRAM 变量:

6. SystemUUID

Type: plist string Failsafe: Not installed Description: 指定 NVRAM 变量 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:system-id 的值,仅用于启动服务。在 Mac 上找到的值等于 SMBIOS SystemUUID

10.6 SMBIOS 属性

1. BIOSVendor

Type: plist string Failsafe: OEM specified SMBIOS: BIOS Information (Type 0) --- Vendor Description: BIOS 供应商。SystemManufacturer 的所有规则都适用。

2. BIOSVersion

Type: plist string Failsafe: OEM specified SMBIOS: BIOS Information (Type 0) --- BIOS Version Description: 固件版本。此值更新时会同时影响更新推送配置文件以及 macOS 版本的兼容性。在较旧的固件中看起来类似于 MM71.88Z.0234.B00.1809171422,并且在 BiosId.h 中有所描述。在较新的固件中看起来类似于 236.0.0.0.0220.230.16.0.0 (iBridge: 16.16.2542.0.0,0)。 iBridge 版本是从 BridgeOSVersion 变量中读取的,并且只在具有 T2 芯片的 Mac 上有显示。

Apple ROM Version
 BIOS ID:      MBP151.88Z.F000.B00.1811142212
 Model:        MBP151
 EFI Version:  220.230.16.0.0
 Built by:     root@quinoa
 Date:         Wed Nov 14 22:12:53 2018
 Revision:     220.230.16 (B&I)
 ROM Version:  F000_B00
 Build Type:   Official Build, RELEASE
 Compiler:     Apple LLVM version 10.0.0 (clang-1000.2.42)
 UUID:         E5D1475B-29FF-32BA-8552-682622BA42E1
 UUID:         151B0907-10F9-3271-87CD-4BF5DBECACF5

3. BIOSReleaseDate

Type: plist string Failsafe: OEM specified SMBIOS: BIOS Information (Type 0) --- BIOS Release Date Description: 固件发布日期。与 BIOSVersion 类似,看起来像是 12/08/2017 这种格式。

4. SystemManufacturer

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- Manufacturer Description: 特定主板的 OEM 制造商。除非特别需要,否则最好不要设定,也不要包含 Apple Inc. 字样,这样做会混淆操作系统中的大量服务,例如固件更新、eficheck 以及 Acidanthera 开发的内核扩展(如 Lilu 及其插件)。此外还可能导致某些操作系统(如 Linux)无法引导。

5. SystemProductName

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- Product Name Description: 选择偏好的 Mac 机型来把设备标记为系统支持的机型。在任何配置中都应指定该值,以便之后自动生成 SMBIOS 表的相关值和相关配置参数。如果 SystemProductName 与目标操作系统不兼容,可用引导参数 -no_compat_check 来覆盖。

:如果 SystemProductName 未知,并且相关字段也未指定,则默认值会被设定为 MacPro6,1。目前已知产品的列表详见 MacInfoPkg

6. SystemVersion

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- Version Description: 产品迭代版本号。看起来类似于 1.1

7. SystemSerialNumber

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- Serial Number Description: 按照格式定义的产品序列号。已知的序列号的格式在 macserial 中可以找到。

8. SystemUUID

Type: plist string, GUID Failsafe: OEM specified SMBIOS: System Information (Type 1) --- UUID Description: UUID 被设计为在时间和空间上都是唯一的标识符,其生成是随机与去中心化的。

9. SystemSKUNumber

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- SKU Number Description: Mac 主板 ID (board-id)。在旧型号的机器中看起来类似于 Mac-7BA5B2D9E42DDD94Mac-F221BEC8。有时可以直接留空。

10. SystemFamily

Type: plist string Failsafe: OEM specified SMBIOS: System Information (Type 1) --- Family Description: 机型名称,看起来类似于 iMac Pro

11. BoardManufacturer

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Manufacturer Description: 主板制造商。SystemManufacturer 的所有规则都适用。

12. BoardProduct

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Product Description: Mac 主板 ID (board-id)。在旧型号机器中看起来类似于 Mac-7BA5B2D9E42DDD94Mac-F221BEC8

13. BoardVersion

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Version Description: 主板版本号。有各种各样,可能与 SystemProductNameSystemProductVersion 匹配。

14. BoardSerialNumber

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Serial Number Description: 主板序列号,有对应的格式,具体格式见 macserial 的描述。

15. BoardAssetTag

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Asset Tag Description: 资产标签号。有各种各样,可以留空或填 Type2 - Board Asset Tag

16. BoardType

Type: plist integer Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Board Type Description: 0xA (Motherboard (includes processor, memory, and I/O)) 或 0xB (Processor/Memory Module),详见 Table 15 --- Baseboard: Board Type。

译者注:此处提及的 Table 请参见 DMTF Specifications 中的相关文档。

17. BoardLocationInChassis

Type: plist string Failsafe: OEM specified SMBIOS: Baseboard (or Module) Information (Type 2) --- Location in Chassis Description: 各种各样,可以留空或填 Part Component

18. ChassisManufacturer

Type: plist string Failsafe: OEM specified SMBIOS: System Enclosure or Chassis (Type 3) --- Manufacturer Description: 主板制造商。SystemManufacturer 的所有规则都适用。

19. ChassisType

Type: plist integer Failsafe: OEM specified SMBIOS: System Enclosure or Chassis (Type 3) --- Type Description: 机箱类型,详见 Table 17 --- System Enclosure or Chassis Types。

译者注:此处所提及的 Table 请参见 DMTF Specifications 中的相关文档。

20. ChassisVersion

Type: plist string Failsafe: OEM specified SMBIOS: System Enclosure or Chassis (Type 3) --- Version Description: 应和 BoardProduct 符合。

21. ChassisSerialNumber

Type: plist string Failsafe: OEM specified SMBIOS: System Enclosure or Chassis (Type 3) --- Version Description: 应和 SystemSerialNumber 符合。

22. ChassisAssetTag

Type: plist string Failsafe: OEM specified SMBIOS: System Enclosure or Chassis (Type 3) --- Asset Tag Number Description: 机箱类型名称。有各种各样,可以留空或填 MacBook-Aluminum

23. PlatformFeature

Type: plist integer, 32-bit Failsafe: 0xFFFFFFFF SMBIOS: APPLE_SMBIOS_TABLE_TYPE133 - PlatformFeature Description: 平台功能位掩码,详见 AppleFeatures.h。填写 0xFFFFFFFF 值时不提供此表。

24. SmcVersion

Type: plist data, 16 bytes Failsafe: All zero SMBIOS: APPLE_SMBIOS_TABLE_TYPE134 - Version Description: ASCII 字符串,包含 SMC 版本号(大写)。配备 Apple T2 安全芯片的 Mac 没有这一字段。当此值设置为零时,这一选项会被忽略。

25. FirmwareFeatures

Type: plist data, 8 bytes Failsafe: 0 SMBIOS: APPLE_SMBIOS_TABLE_TYPE128 - FirmwareFeatures and ExtendedFirmwareFeatures Description: 64 位固件功能位掩码。详见 AppleFeatures.h。低 32 位与 FirmwareFeatures 匹配,高 64 位与 ExtendedFirmwareFeatures 匹配。

26.FirmwareFeaturesMask

Type: plist data, 8 bytes Failsafe: 0 SMBIOS: APPLE_SMBIOS_TABLE_TYPE128 - FirmwareFeaturesMask and ExtendedFirmwareFeaturesMask Description: 扩展固件功能位掩码。详见 AppleFeatures.h。低 32 位与 FirmwareFeatures 匹配,高 64 位与 ExtendedFirmwareFeatures 匹配。

27. ProcessorType

Type: plist integer, 16-bit Failsafe: 0 (Automatic) SMBIOS: APPLE_SMBIOS_TABLE_TYPE131 - ProcessorType Description: 由处理器的主要和次要类型组成。

自动生成的值(Automatic)是根据当前的 CPU 规格提供的最准确的值,一般不会有问题,如果有问题请务必到 bugtracker 创建一个 Issue,并附上 sysctl machdep.cpudmidecode 的输出结果。所有可用值及其限制条件(指该值只有在核心数匹配的情况下才适用)都可以在 Apple SMBIOS 定义 头文件 里找到。

UEFI

11.1 简介

UEFI(统一可扩展固件接口)是一种规范,用于定义操作系统和平台固件之间的软件接口。本部分允许加载其他 UEFI 模块 和/或 对板载固件进行调整。要检查固件内容,应用修改并执行升级,可以使用 UEFITool 和其他实用程序。

11.2 驱动列表

根据固件不同、可能需要不同的驱动程序。加载不兼容的驱动程序可能会导致无法启动系统,甚至导致固件永久性损坏。OpenCore 目前对以下 UEFI 驱动提供支持。OpenCore 可能兼容其他 UEFI 驱动,但不能确定。

标有 * 的驱动程序是 OpenCore 附带的。如果要从 UDK(EDK II)编译驱动程序,请使用编译 OpenCore 的相同命令,但要注意选择相应的软件包:

git clone https://github.com/acidanthera/audk UDK
cd UDK
source edksetup.sh
make -C BaseTools
build -a X64 -b RELEASE -t XCODE5 -p FatPkg/FatPkg.dsc
build -a X64 -b RELEASE -t XCODE5 -p MdeModulePkg/MdeModulePkg.dsc

11.3 工具与应用程序

一些不依赖 OpenCore 的工具可以帮助调试固件和硬件。下面列出了一些已知的工具。虽然有些工具可以从 OpenCore 启动,但大部分工具都应该直接或从 OpenCoreShell 中单独运行。

要启动到 OpenShell 或任何其他工具,直接将 OpenShell.efi 保存在 FAT32 分区中的 EFI/BOOT/BOOTX64.EFI 下。此时分区方案是 GPT 还是 MBR 并不重要。

这种方法在 Mac 和其他计算机上都可以使用。还有一种只能在 Mac 上的 HFS+ 或 APFS 分区上使用的方法:

sudo bless --verbose --file /Volumes/VOLNAME/DIR/OpenShell.efi --folder /Volumes/VOLNAME/DIR/ --setBoot

<center><em><strong>Listing 3</strong>: Bless 工具</em></center><br>

注 1:你可能需要将 /System/Library/CoreServices/BridgeVersion.bin 拷贝到 /Volumes/VOLNAME/DIR

注 2:为了能够使用 bless,你可能需要 禁用系统完整性保护。

注 3:为了能够正常启动,你可能需要 禁用 Apple 安全启动(如果有的话)。

一些已知的 UEFI 工具(内置工具已用 * 标出):

11.4 OpenCanopy

OpenCanopy 是一个 OpenCore 的图形化界面接口,基于 OpenCorePkg OcBootManagementLib 实现,提供与现有的文字模式类似的功能。当 PickerMode 设置为 External 时启用。

OpenCanopy 所需的图象资源位于 Resources 目录下,一些简单的资源(字体和图标)可以在 OcBinaryData 仓库 中获取。可以在网络上找到自定义图标(比如 这里 和 这里)。

OpenCanopy 为 PickerAttributes 提供了全面的支持,并提供了一套可配置的内置图标集。默认选择的图标由 DefaultBackgroundColor 变量决定,当该变量的值定义为浅灰时,则使用 Old 前缀的图标,定义为其他颜色时则使用没有前缀名的图标。

预定义的图标放在 \EFI\OC\Resources\Image 目录下。下面提供了所支持的图标的完整列表(.icns 格式)。可选图标如未提供,将使用最接近的可用的图标。外置设备的条目将使用 Ext 前缀的图标(如 OldExtHardDrive.icns)。

:以下标注的所有尺寸均为 1x 缩放级别的标准尺寸,其他缩放级别的尺寸须作相应调整。

预定义的标签放在 \EFI\OC\Resources\Label 目录下。每个标签都有 .lbl.l2x 的后缀,以代表缩放级别。完整的标签列表如下所示。所有标签都是必需的。

:所有标签的高度必须为 12px,宽度不限。

可以通过附带的实用程序来生成标签和图标:disklabelicnspack。字体为 12pt 的 Helvetica,比例缩放。

字体格式对应于 AngelCode binary BMF。虽然有很多工具可以生成字体文件,但目前还是建议使用 dpFontBaker 来生成位图字体(用 CoreText 达到最佳效果),并使用 fonverter 将其导出为二进制格式。

11.5 OpenRuntime

OpenRuntime 是一个 OpenCore 的插件,提供了对 OC_FIRMWARE_RUNTIME 协议的实现。该协议对 OpenCore 的部分功能提供了支持,而这部分功能由于需要 Runtime(如操作系统)中运行、因此无法内置在 OpenCore 中。该协议提供了包括但不限于如下功能:

11.6 属性列表

1. APFS

Type: plist dict Failsafe: None Description: 配置 APFS 分区驱动,具体配置内容参见下文 APFS 属性部分。

2. Audio

Type: plist dict Failsafe: None Description: 配置音频后端支持,具体配置如下文所述。

音频支持为上游协议提供了一种与所选硬件和音频资源交互的方式。所有音频资源应该保存在 \EFI\OC\Resources\Audio 目录。目前支持的音频文件格式为 MP3 和 WAVE PCM。虽然支持哪种音频流格式取决于驱动程序,但大多数常见的音频卡都支持 44100 或 48000Hz 的 16 位立体声。

音频文件的路径是由音频的类型、本地化语言和路径决定的。每个文件名看起来都类似于:[audio type]_[audio localisation]_[audio path].[audio ext]。对于没有本地化的文件,其文件名不包含语言代码,看起来类似于:[audio type]_[audio path].[audio ext]。其中音频扩展名为 mp3wav

macOS 引导程序和 OpenCore 的音频本地化是分开的。macOS 引导程序是在 systemLanguage.utf8 文件中的 preferences.efires 归档中设置,并由操作系统控制。OpenCore 则是使用 prev-lang:kbd 变量的值来控制。当某一特定文件的音频本地化缺失时,将会使用英语(en)来代替。示例音频文件可以在 OcBinaryData 仓库 中找到。

3. ConnectDrivers

Type: plist boolean Failsafe: false Description: 驱动程序加载后执行 UEFI 控制器连接操作。

此选项对于加载某些遵循 UEFI 驱动模型的 驱动程序(如文件系统驱动、音频输出驱动)很有用,因为这些驱动可能无法自行启动。此选项对会自动连接的驱动程序来说是不必要的,并且可能会稍微减慢启动速度。

:某些固件(特别是 Apple 的)仅连接包含操作系统的驱动器以加快启动过程。启用此选项可以在拥有多个驱动器时查看所有引导选项。

4. Drivers

Type: plist array Failsafe: None Description: 从 OC/Drivers 目录下加载选择的驱动。设计为填充 UEFI 驱动程序加载的文件名。

5. Input

Type: plist dict Failsafe: None Description: 从下面的 Input 属性部分,应用为输入(键盘和鼠标)而设计的个性化设置。

6. Output

Type: plist dict Failsafe: None Description: 从下面的 Output 属性部分,应用为输出(文本和图形)而设计的个性化设置。

7. ProtocolOverrides

Type: plist dict Failsafe: None Description: 强制执行从下面的 ProtocolOverrides 属性部分所选协议的内置版本。

:所有协议实例的安装都优先于驱动程序的加载。

8. Quirks

Type: plist dict Failsafe: None Description: 从下面的 Quirks 属性部分,应用个性化的固件 Quirks。

9. ReservedMemory

Type: plist array Description: 设计为用 plist dict 值填充,用于描述对特定固件和硬件功能要求很高的内存区域,这些区域不应该被操作系统使用。比如被 Intel HD 3000 破坏的第二个 256MB 区域,或是一个有错误的 RAM 的区域。

11.7 APFS 属性

1. EnableJumpstart

Type: plist boolean Failsafe: False Description: 从一个 APFS 容器中加载 APFS 驱动。

APFS 的 EFI 驱动内置在所有可以作为系统启动盘的 APFS 容器之中。这一选项将会根据基于 ScanPolicy 找到的 APFS 容器,从中加载 APFS 驱动。更多详情请查看 苹果 APFS 文件系统参考手册 中的 EFI Jummpstart 章节。

2. GlobalConnect

Type: plist boolean Failsafe: false Description: 在 APFS 加载期间执行完整的设备连接。

代替通常情况下用于 APFS 驱动程序加载的分区句柄连接,每一个句柄都是递归连接的。这可能会比平时花费更多的时间,但是是某些固件访问 APFS 分区的唯一方法,比如在旧的惠普笔记本电脑上发现的那样。

3. HideVerbose

Type: plist boolean Failsafe: False Description: 是否隐藏 APFS 驱动的 verbose 信息。

APFS 驱动的 verbose 信息有助于 debug。

4. JumpstartHotPlug

Type: plist boolean Failsafe: False Description: 允许从进入 OpenCore 引导菜单后插入的可移除硬盘上的 APFS 容器中加载 APFS 驱动。

这一选项不仅提供了进入 OpenCore 以后再插入 U 盘的支持,而且还允许了在 OpenCore 引导菜单下 APFS U 盘的热插拔。

5. MinDate

Type: plist integer Failsafe: 0 Description: 允许加载的最老 APFS 驱动的发布日期。

APFS 驱动的版本号基于其发布日期。较旧版本的 APFS 驱动可能与较新的系统不兼容、或者有未修补的漏洞。通过这一选项可以避免 OpenCore 加载过旧版本的 APFS 驱动。

6. MinVersion

Type: plist integer Failsafe: 0 Description: 允许加载的最老 APFS 驱动的版本号。

APFS 驱动的版本号和 macOS 版本相关。较旧版本的 APFS 驱动可能与较新的系统不兼容、或者有未修补的漏洞。通过这一选项可以避免 OpenCore 加载过旧版本的 APFS 驱动。

11.8 Audio 属性

1. AudioCodec

Type: plist integer Failsafe: 0 Description: 特定音频控制器上的编解码器地址,用于音频支持。

一般来说,这里包含了内置模拟音频控制器(HDEF)上的第一个音频编解码器地址。音频编解码器地址(比如 2)可以在调试日志中找到(已用粗斜体标出):

<code>OCAU: 1/3 PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x1)/VenMsg(<redacted>,<strong><em>00000000</em></strong>) (4 outputs)</code> <code>OCAU: 2/3 PciRoot(0x0)/Pci(0x3,0x0)/VenMsg(<redacted>,<strong><em>00000000</em></strong>) (1 outputs)</code> <code>OCAU: 3/3 PciRoot(0x0)/Pci(0x1B,0x0)/VenMsg(<redacted>,<strong><em>02000000</em></strong>) (7 outputs)</code>

除此之外,该值还可以在 I/O 注册表的 IOHDACodecDevice class 中获得,包含在 IOHDACodecAddress 字段中。

2. AudioDevice

Type: plist string Failsafe: empty string Description: 特定音频控制器的设备路径,用于音频支持。

一般来说,这里包含了内置模拟音频控制器(HDEF)的设备路径,比如 PciRoot(0x0)/Pci(0x1b,0x0)。认可的音频控制器列表可以在调试日志中找到(已用粗斜体标出):

<code>OCAU: 1/3 <strong><em>PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x1)</em></strong>/VenMsg(<redacted>,00000000) (4 outputs)</code> <code>OCAU: 2/3 <strong><em>PciRoot(0x0)/Pci(0x3,0x0)</em></strong>/VenMsg(<redacted>,00000000) (1 outputs)</code> <code>OCAU: 3/3 <strong><em>PciRoot(0x0)/Pci(0x1B,0x0)</em></strong>/VenMsg(<redacted>,02000000) (7 outputs)</code>

除此之外,该值还可以在 macOS 中通过 gfxutil -f HDEF 命令来获取。如果指定了空的设备路径,则会使用第一个可用的音频控制器。

3. AudioOut

Type: plist integer Failsafe: 0 Description: 特定编解码器的输出端口的索引,从 0 开始。

一般来说,这里包含了内置模拟音频控制器(HDEF)的绿色输出的索引。调试日志中输出节点的数量如下(已用粗斜体标出):

<code>OCAU: 1/3 PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x1)/VenMsg(<redacted>,00000000) (<strong><em>4 outputs</em></strong>)</code> <code>OCAU: 2/3 PciRoot(0x0)/Pci(0x3,0x0)/VenMsg(<redacted>,00000000) (<strong><em>1 outputs</em></strong>)</code> <code>OCAU: 3/3 PciRoot(0x0)/Pci(0x1B,0x0)/VenMsg(<redacted>,02000000) (<strong><em>7 outputs</em></strong>)</code>

找到正确端口的最快办法就是暴力地尝试 0N - 1 的值。

4. AudioSupport

Type: plist boolean Failsafe: false Description: 通过连接到固件音频驱动程序以激活音频支持。

启用此设置可将音频播放从内置协议路由到音频控制器(AudioDevice)上指定编解码器(AudioCodec)的专用音频端口(AudioOut)。

5. MinimumVolume

Type: plist integer Failsafe: 0 Description: 听到的最小音量水平,从 0100

当计算出的音量小于 MinimumVolume 时,屏幕阅读器将使用这个音量。当计算出的音量小于 MinimumVolume,则不播放 Mac 特有的开机启动声音。

6. PlayChime

Type: plist string Failsafe: Auto Description: 开机时播放 Mac 特有的风铃的声音。

启用此设置可通过内置的音频支持来播放开机时播放的声音。音量大小由 MinimumVolumeVolumeAmplifier 的设置,以及 SystemAudioVolume NVRAM 变量来决定。可用的值有:

Enable 是可以与 StartupMute NVRAM 变量分开使用的,以此来避免在固件能够播放启动铃声时发生冲突。

7. SetupDelay

Type: plist integer Failsafe: 0 Description: 音频编解码器重新配置的延迟,单位为微秒。

某些编解码器在重新配置后需要特定延迟(由供应商提供,例如音量设置),此选项可对其进行配置。一般来说,必要的延迟时间可能长达 0.5 秒。

8. VolumeAmplifier

Type: plist integer Failsafe: 0 Description: 系统音量到原始音量的线性换算的乘法系数,从 01000

SystemAudioVolume 读取的音量范围会因编解码器的不同而不同。为了将 [0, 127] 范围内的值转换为原始音量范围 [0, 100] 内的值,所读取的值按比例调整为 VolumeAmplifier 的百分数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nq60L2Zd-1655987034338)(/img/11-1.svg)]

:macOS 中使用的转换并不是线性的,但非常接近,因此我们忽略了这种细微差别。

11.9 Input 属性

1. KeyFiltering

Type: plist boolean Failsafe: false Description: 启用键盘输入的合理性检查。

显然,有些主板,如 GA Z77P-D3,可能会在 EFI_INPUT_KEY 中返回所有输入协议的未初始化数据。这个选项会舍弃那些既不是 ASCII 码,也不是 UEFI 规范中定义的键(见版本 2.8 的表 107 和 108)。

2. KeyForgetThreshold

Type: plist integer Failsafe: 0 Description: 两次按键之间的间隔时间,单位为毫秒。

AppleKeyMapAggregator 协议应该包含当前按下的键的固定长度的缓冲。但是大部分驱动程序仅将按键按下报告为中断、并且按住按键会导致在一定的时间间隔后再提交按下行为。一旦超时到期,我们就是用超时从缓冲区中删除一次按下的键,并且没有新提交。

此选项允许根据你的平台设置此超时。在大多数平台上有效的推荐值为 5 毫秒。作为参考,在 VMWare 上按住一个键大约每 2 毫秒就会重复一次,而在 APTIO V 上是 3 - 4 毫秒。因此,可以在较快的平台上设置稍低的值、在较慢的平台设置稍高的值,以提高响应速度。

:某些平台可能需要更高或者更低的值。例如,当 OpenCanopy 检测到按键丢失的时候,尝试稍高的值(比如增加到 10),当检测到按键停滞时,尝试稍低的值。由于每个平台各不相同,因此检查从 125 的每个值可能会比较合理。

3. KeyMergeThreshold

Type: plist integer Failsafe: 0 Description: 按住按键被重置的间隔时间,单位为毫秒。

KeyForgetThreshold 类似,这一选项适用于按键提交的顺序。为了能够识别同时按下的按键,我们需要设置一个超时时间,在这个时间内可以假定这两个按键是同时按下的。

对于 VMWare,同时按下多个键的间隔是 2 毫秒。对于 APTIO V 平台为 1 毫秒。一个接一个地按下按键会导致 6 毫秒和 10 毫秒的延迟。此选项的建议值为 2 毫秒,但对于较快的平台可以选取较小的值,反之亦然。

4. KeySupport

Type: plist boolean Failsafe: false Description: 启用这一选项后将会开启内置键盘支持。

这一选项基于 AppleGenericInputAptioInputFix),激活内部键盘拦截器驱动程序以填充 AppleKeyMapAggregator 数据库以实现输入功能。如果使用了单独的驱动程序(如 AppleUsbKbDxe),则永远不要开启这一选项。

5. KeySupportMode

Type: plist string Failsafe: Auto Description: 将内部键盘的输入转换设置为 AppleKeyMapAggregator 协议模式。

:目前 V1V2AMI 区别于 Auto,只对特定的协议进行过滤。这种情况在未来的版本中可能会改变。

6. KeySwap

Type: plist boolean Failsafe: false Description: 启用后将交换 CommandOption

此选项对于 Option 键位于 Command 右侧的键盘来说会很有用。

7. PointerSupport

Type: plist boolean Failsafe: false Description: 启用后将试图修复 UEFI 选择器协议。

该选项通过选择 OEM 协议实现标准 UEFI 指针协议 EFI_SIMPLE_POINTER_PROTOCOL。该选项在 Z87 华硕主板可能有用(该主板的 EFI_SIMPLE_POINTER_PROTOCOL 存在问题)。

8. PointerSupportMode

Type: plist string Failsafe: empty string Description: 设置用于内部指针驱动程序的 OEM 协议。

目前只支持 ASUS 值,使用的是 Z87 和 Z97 主板上的特殊协议。更多详情请参考 LongSoft/UefiTool#116。如果启用了 PointerSupport,此处值不能为空。

9. TimerResolution

Type: plist integer Failsafe: 0 Description: 固件始终刷新的频率(单位 100 纳秒)

设置较低的值可以提高界面和输入处理性能的响应能力。建议值为 50000(即 5 毫秒)或稍高一些。选择 ASUS Z87 主板时,请使用 60000,苹果主板请使用 100000。你也可以将此值保留为 0,由 OpenCore 自动计算。

11.10 Output 属性

1. TextRenderer

Type: plist string Failsafe: BuiltinGraphics Description: 选择通过标准控制台输出的渲染器。

目前支持两种渲染器:BuiltinSystemSystem 渲染器使用固件服务进行文本渲染。Builtin 渲染器则绕过固件服务,自行渲染文本。不同的渲染器支持的选项也不同。建议使用 Builtin 渲染器,因为它支持 HiDPI 模式,并能够使用全屏分辨率。

UEFI 固件一般用两种渲染模式来支持 ConsoleControlGraphicsText。有些固件不支持 ConsoleControl 和渲染模式。OpenCore 和 macOS 希望文本只在 Graphics 模式下显示,而图形可以在任何模式下绘制。由于 UEFI 规范并不要求这样做,因此具体的行为各不相同。

有效值为文本渲染器和渲染模式的组合:

BuiltinGraphics 的用法通常是比较直接的。对于大多数平台,需要启用 ProvideConsoleGop,将 Resolution 设置为 Max。某些非常老旧且问题很多的笔记本只能在 Text 模式下绘图,对它们来说,BuiltinTextBuiltinGraphics 的替代选择。

System 协议的用法比较复杂。一般来说,首选设置 SystemGraphicsSystemText。启用 ProvideConsoleGop,将 Resolution 设置为 Max,启用 ReplaceTabWithSpace 几乎在所有平台上都很有用。SanitiseClearScreenIgnoreTextInGraphicsClearScreenOnModeSwitch 比较特殊,它们的用法取决于固件。

:某些 Mac,比如 MacPro5,1,在使用较新的 GPU 时,可能会出现控制台输出中断的情况,因此可能只有 BuiltinGraphics 对它们有效。

2. ConsoleMode

Type: plist string Failsafe: Empty string Description: 按照 WxH(例如 80x24)格式的字符串所指定的方式设置控制台的输出模式。

设置为空字符串则不会改变控制台模式。设置为 Max 则会尝试最大的可用控制台模式。目前 Builtin 文本渲染器只支持一种控制台模式,所以该选项可以忽略。

:在大多数固件上,这个字段最好留空。

3. Resolution

Type: plist string Failsafe: Empty string Description: 设置控制台的屏幕分辨率。

在 HiDPI 屏幕上,APPLE_VENDOR_VARIABLE_GUID UIScale NVRAM 变量可能需要设置为 02,以便在 Builtin 文本渲染器、FileVault 2 UEFI 密码界面和启动界面 logo 启用 HiDPI 缩放。更多细节请参考 建议变量 部分。

:当控制台句柄没有 GOP 协议时,这些设置会失败。当固件不再提供时,可以将 ProvideConsoleGop 设置为 true 并添加。

4. ForceResolution

Type: plist boolean Failsafe: false Description: 当默认情况下无法获得所需分辨率时,强制设置 Resolution 中所填写的分辨率,多用于老的 Intel GMA 和第一代 Intel HD Graphics (Ironlake/Arrandale)。将 Resolution 设置为 Max 时,将尝试从所连接的显示器的 EDID 中提取最大的可用分辨率。

:该选项依赖 OC_FORCE_RESOLUTION_PROTOCOL 协议。目前只有 OpenDuetPkg 支持该协议,而 OpenDuetPkg 的实现目前仅支持 Intel iGPU。

4. ClearScreenOnModeSwitch

Type: plist boolean Failsafe: false Description: 有些固件在从图形模式切换到文本模式时,只会清除部分屏幕、而会留下一部分之前绘制的图像。启用这一选项后,在切换到文本模式之前会用黑色填充整个图形屏幕。

:这一选项只会在 System 渲染器上生效。

5. DirectGopRendering

Type: plist boolean Failsafe: false Description: 为控制台使用内置的图形输出协议渲染器。

在某些固件上,这样做可能会提供更优的性能,甚至修复渲染问题,比如 MacPro5,1。但是,除非有明显的好处,否则还是建议不要使用这个选项,因为可能会导致滚动速度变慢。

6. IgnoreTextInGraphics

Type: plist boolean Failsafe: false Description: 选择固件同时在图形和文本两种模式下在屏幕上输出文本。通常不会这样做,因为随机的文本可能会出现在图形图像上,并导致用户界面出错。将此选项设置为 true 时,会在控制台处于与 Text 不同的模式时,舍弃所有文本输出。

:这一选项只会在 System 渲染器上生效。

7. ReplaceTabWithSpace

Type: plist boolean Failsafe: false Description: 有些固件不会打印 tab 符号,甚至不打印 tab 后面的所有内容,导致很难或根本无法用 UEFI Shell 内置的文本编辑器来编辑属性列表和其他文档。这个选项会使控制台输出空格来替代 tab。

:这一选项只会在 System 渲染器上生效。

8. ProvideConsoleGop

Type: plist boolean Failsafe: false Description: 确保控制台句柄上有 GOP (Graphics Output Protocol)。

macOS bootloader 要求控制台句柄上必须有 GOP 或 UGA(适用于 10.4 EfiBoot),但 UEFI 规范并未涵盖图形协议的确切位置。此选项会确保 GOP 和 UGA(如果存在)在控制台句柄上可用。

:这个选项也会替换掉控制台句柄上损坏的 GOP 协议,在使用较新的 GPU 的 MacPro5,1 时可能会出现这种情况。

9. ReconnectOnResChange

Type: plist boolean Failsafe: false Description: 改变屏幕分辨率后重新连接控制台控制器。

当通过 GOP 改变屏幕分辨率时,某些固件需要重新连接产生控制台协议(简单的文本输出)的控制器,否则它们不会根据新的分辨率生成文本。

:当 OpenCore 从 Shell 启动时,这个逻辑可能会导致某些主板黑屏,因此这个选项是非必须的。在 0.5.2 之前的版本中,这个选项是强制性的,不可配置。除非需要,否则请不要使用该选项。

10. SanitiseClearScreen

Type: plist boolean Failsafe: false Description: 有些固件在使用较大的显示器(如 2K 或 4K)时,清除屏幕内容会导致屏幕分辨率重置为 failsafe 值(如 1024x768)。这个选项为这种情况提供了一个变通方法。

:这一选项只会在 System 渲染器上生效。在所有已知的受影响的系统中,ConsoleMode 必须设置为空字符串才能正常工作。

11. UgaPassThrough

Type: plist boolean Failsafe: false Description: 在 GOP 协议的顶部提供 UGA 协议实例。

有些固件不会去实现老旧的 UGA 协议,但是有些更老的 EFI 应用程序(如 10.4 的 EfiBoot)可能需要用它来进行屏幕输出。

11.11 ProtocolOverrides 属性

1. AppleAudio

Type: plist boolean Failsafe: false Description: 重新安装内置版本的 Apple 音频协议。

Apple 音频协议允许 macOS bootloader 和 OpenCore 播放声音和信号,用于屏幕阅读或可闻及的错误报告。支持的协议有生成「哔」声和 VoiceOver。VoiceOver 协议是带有 T2 芯片的机器特有的,不支持 macOS High Sierra (10.13) 之前的版本。旧版 macOS 版本使用的是 AppleHDA 协议,目前还没有实现。

每次只能有一组音频协议可用,所以如果为了在 Mac 系统上的 OpenCore 用户界面实现其中一些协议的音频播放,这一设置应该启用。

:后端音频驱动需要在 UEFI Audio 部分进行配置,以便这些协议能够流式传输音频。

2. AppleBootPolicy

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple Boot Policy 协议,可用于确保 VM 或旧版 Mac 设备上的 APFS 兼容性。

:某些 Mac 设备(如 MacPro5,1)虽然兼容 APFS,但是其 Apple Boot Policy 协议包含了恢复分区检测问题,因此也建议启用这一选项。

3. AppleDebugLog

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple 调试日志输出协议。

4. AppleEvent

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple Event 协议,可以确保在 VM 或旧版 Mac 设备上的 FileVault 2 兼容性。

5. AppleFramebufferInfo

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple Framebuffer Info 协议。这样可以覆盖虚拟机或者旧款 Mac 上的缓冲帧信息,从而提高与旧版 EfiBoot(如 macOS 10.4 中的 EfiBoot)的兼容性。

6. AppleImageConversion

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple Image Conservation 协议。

7. AppleImg4Verification

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple IMG4 验证协议。该协议用于验证 Apple 安全启动所使用的 im4m 清单文件。

8. AppleKeyMap

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple Key Map 协议。

9. AppleRtcRam

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple RTC RAM 协议。

:内置的 Apple RTC RAM 协议可能会过滤掉 RTC 内存地址的潜在 I/O。地址列表可以在 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:rtc-blacklist 中以数组的方式指定。

10. AppleSecureBoot

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple 安全启动协议。

11. AppleSmcIo

Type: plist boolean Failsafe: false Description: 重新安装内置的 SMC I/O 协议。

这一协议代替了传统的 VirtualSmc.efi,并与所有 SMC Kext 驱动兼容。如果你在用 FakeSMC,可能需要手动往 NVRAM 中添加键值对。

12. AppleUserInterfaceTheme

Type: plist boolean Failsafe: false Description: 重新安装内置的 Apple User Interface Theme 协议。

13. DataHub

Type: plist boolean Failsafe: false Description: 重新安装具有内置版本的 Data Hub 协议。如果已经安装了协议,这将删除所有先前的属性。

14. DeviceProperties

Type: plist boolean Failsafe: false Description: 重新安装内置版本的 Device Property 协议。 如果已经安装,它将删除所有以前的属性。这一选项可用于确保在 VM 或旧版 Mac 设备上的兼容性。

15. FirmwareVolume

Type: plist boolean Failsafe: false Description: 强制包装固件卷协议或安装新版本以支持 FileVault 2 的自定义光标图像。建议启用这一选项以确保 FileVault 2 在除 VM 和传统 Mac 设备之外的兼容性。

:包括 VMWare 在内的多个虚拟机在 HiDPI 模式下光标会损坏,因此建议为所有虚拟机启用这一选项。

16. HashServices

Type: plist boolean Failsafe: false Description: 强制重新安装内置版本的 Hash Services 协议。为了在 SHA-1 哈希协议不完整的固件上确保 FileVault 2 的兼容性,这一 Quirk 应设置为 true。对于大多数固件来说,你可以通过将 UIScale 设置为 02 查看是否会出现禁行图标,来诊断你的固件是否需要这一 Quirk。一般来说,APTIO V(Haswell 和更早的平台)之前的平台都会受到影响。

17. OSInfo

Type: plist boolean Failsafe: false Description: 强制使用内置版本重新安装 OS Info 协议。该协议通常用于通过固件或其他应用程序从 macOS 引导加载程序接收通知。

18. UnicodeCollation

Type: plist boolean Failsafe: false Description: 强制重新安装内置版本的 Unicode Collation 服务。建议启用这一选项以确保 UEFI Shell 的兼容性。一些较旧的固件破坏了 Unicode 排序规则,启用后可以修复这些系统上 UEFI Shell 的兼容性 (通常为用于 IvyBridge 或更旧的设备)

11.12 Quirks 属性

1. DisableSecurityPolicy

Type: plist boolean Failsafe: false Description: 禁用平台安全策略。

:此设置可禁用固件的各种安全功能,因此也会同时破坏安全启动策略。如果打算使用 UEFI 安全启动,请勿启用此项。

1. ExitBootServicesDelay

Type: plist integer Failsafe: 0 Description: 在 EXIT_BOOT_SERVICES 事件后添加延迟,单位为毫秒。

这是一个非常丑陋的 Quirk,用于修复 Still waiting for root device 提示信息。在使用 FileVault 2 时,特别是华硕 Z87-Pro 等 APTIO IV 固件这种错误经常发生。似乎因为某种原因,FileVault 与 EXIT_BOOT_SERVICES 同时执行、导致 macOS 无法访问 SATA 控制器。未来应该会找到一个更好的方法。如果需要启用这一选项,设置 3-5 秒的延时就可以了。

2. IgnoreInvalidFlexRatio

Type: plist boolean Failsafe: false Description: 某些固件,即 APTIO IV,可能在 MSR_FLEX_RATIO (0x194) MSR 寄存器中含有无效值。这些值可能会导致 macOS 在 Intel 平台上启动失败。

:虽然该选项不会对不受影响的固件造成损害,但在不需要的情况下不建议启用。

3. ReleaseUsbOwnership

Type: plist boolean Failsafe: false Description: 尝试从固件驱动程序中分离 USB 控制器所有权。尽管大多数固件都设法正确执行了该操作或者提供有一个选项,但某些固件没有,从而导致操作系统可能会在启动时冻结。除非需要,否则不建议启用这一选项。

4. RequestBootVarRouting

Type: plist boolean Failsafe: false Description: 请求将所有带有 Boot 前缀的变量从 EFI_GLOBAL_VARIABLE_GUID 重定向到 OC_VENDOR_VARIABLE_GUID

启用这个 Quirk 需要用到在 OpenRuntime.efi 中实现的 OC_FIRMWARE_RUNTIME 协议。当固件删除不兼容的启动条目时,这一 Quirk 可以让默认的启动条目保存在引导菜单中。简单地说就是,如果你想使用「系统偏好设置」中的「启动磁盘」,就必须启用这一 Quirk。

借助 RequestBootVarRoutingBoot 前缀变量重定向至单独的 GUID 命名空间,可实现以下效果:

5. TscSyncTimeout

Type: plist integer Failsafe: 0 Description: 尝试用指定的 Timeout 执行 TSC 同步。

这个 Quirk 的主要目的是在运行 XNU 调试内核时,在一些服务器和笔记本型号上实现早期引导 TSC 同步。对于调试内核,在任何 Kext 可能导致其他解决方案出现问题之前,TSC 需要在各个内核之间保持同步。Timeout 以微秒为单位,取决于平台上存在的核心数量,推荐的起始值是 500000

这是一个实验性的 Quirk,只能被用于上述问题。在其他情况下,这个 Quirk 可能会导致操作系统不稳定,所以并不推荐使用。在其他情况下,推荐的解决办法是安装一个内核驱动,如 VoodooTSCSync、TSCAdjustReset 或 CpuTscSync(是 VoodooTSCSync 的一个更有针对性的变种,适用于较新的笔记本电脑)。

:这个 Quirk 不能取代内核驱动的原因是它不能在 ACPI S3 模式(睡眠唤醒)下运行,而且 UEFI 固件提供的多核心支持非常有限,无法精确地更新 MSR 寄存器。

6. UnblockFsConnect

Type: plist boolean Failsafe: false Description: 某些固件通过「按驱动程序」模式下来阻止引导项加载,导致文件系统协议无法安装。

:如果惠普笔记本在 OpenCore 界面没有看到引导项,启用这一选项。

11.13 ReservedMemory 属性

1. Address

Type: plist integer Failsafe: 0 Description: 保留内存区域的起始地址,该区域应被分配为保留区,有效地将此类型的内存标记标记为操作系统不可访问。

这里写的地址必须是内存映射的一部分,具有 EfiConventionalMemory 类型,并且按页对齐(4KB)。

:禁用 CSM 后,某些固件可能不会为 S3(睡眠)和 S4(休眠)分配内存区域,因此导致唤醒失败。你可以分别比较禁用和启用 CSM 的内存映射,从低层内存中找到这些区域,并保留该区域来修复这个问题。详见 Sample.plist

2. Comment

Type: plist string Failsafe: Empty string Description: 用于为条目提供人类可读参考的任意 ASCII 字符串(译者注:即注释)。该值取决于具体的实现定义。

3. Size

Type: plist integer Failsafe: 0 Description: 保留的内存区域的大小,必须按页对齐(4KB)。

4. Type

Type: plist string Failsafe: Reserved Description: 内存区域类型,与 UEFI 规范的内存描述符类型的匹配映射如下:

5. Enabled

Type: plist boolean Failsafe: false Description: 除非设置为 true,否则该区域不会被保留。

排错

12.1 旧版 Apple 操作系统

旧版操作系统的安装可能比较复杂,但有时出于各种原因还是需要用到。主板标识符和 CPUID 的兼容性是旧版操作系统正常运行的基础,除此之外还有一些细枝末节的事情需要注意。本章节将尽量阐述与旧版 macOS 操作系统相关的一系列常见问题。

尽管较新的操作系统可以通过互联网下载,但旧版操作系统并不是每个次要版本都有安装介质的,因此要想获得兼容的发行版,可能需要下载特定设备的镜像,并在必要时进行修改。Mac 电脑随附的 macOS 旧版本和旧版号列表,可以从这篇 Apple 支持的 存档文章 中找到,但由于它并不一定准确,下面列出了一些旧版 Apple 操作系统最后发布的版本。

1. macOS 10.8 和 10.9

2. macOS 10.7

3. macOS 10.6

机型检查可以被手动去除,大体思路是用 Flat Package Editor 之类的工具编辑 OSInstall.mpkg,让 Distribution 脚本在 hwbeModelCheck 函数中总是返回 true。仅更新映像中某一的文件而不影响到其他文件是相当困难的,而且还有可能因为内核缓存日期的改变而导致启动速度变慢,因此建议按照如下命令重建映像:

#!/bin/bash
# Original.dmg is original image, OSInstall.mpkg is patched package
mkdir RO
hdiutil mount Original.dmg -noverify -noautoopen -noautoopenrw -noautofsck -mountpoint RO cp RO/.DS_Store DS_STORE
hdiutil detach RO -force
rm -rf RO
hdiutil convert Original.dmg -format UDRW -o ReadWrite.dmg
mkdir RW
xattr -c OSInstall.mpkg
hdiutil mount ReadWrite.dmg -noverify -noautoopen -noautoopenrw -noautofsck -mountpoint RW cp OSInstall.mpkg RW/System/Installation/Packages/OSInstall.mpkg
killall Finder fseventsd
rm -rf RW/.fseventsd
cp DS_STORE RW/.DS_Store
hdiutil detach RW -force
rm -rf DS_STORE RW

4. macOS 10.5

5. macOS 10.4

12.2 UEFI 安全启动

OpenCore 的设计初衷是在 固件 和 操作系统 之间提供一个安全的启动链。在大多数 x86 平台上,可信加载(Trusted Loading)是通过 UEFI 安全启动 模式实现的。OpenCore 不仅完全支持这种模式,还扩展了它的功能,以确保通过 Vault 进行配置的加密存储,并使用自定义的验证过程向操作系统提供可信加载,例如 Apple 安全启动。正确的安全启动链需要通过以下步骤来仔细配置:

  1. 如果要启动的系统是 macOS,则需要通过设置 SecureBootModel 来启用 Apple 安全启动。请注意,并不是每个 macOS 版本都能使用 Apple 安全启动,具体限制详见 Apple 安全启动 章节。
  2. 旧的 DMG 恢复镜像往往很脆弱、易受攻击,如果担心因为加载它而突破防线,可以通过设置 DmgLoadingDisabled 来禁用 DMG 加载。非必需,但建议使用。参阅 DMG 加载 部分来权衡利弊。
  3. MinDateMinVersion 设置为 0,以确保 APFS JumpStart 功能限制旧的驱动程序加载。更多细节参见 APFS JumpStart 部分。除此之外,手动安装 apfs.efi 驱动也可以达到相同效果。
  4. 确保你想要运行的操作系统不加载 Force 驱动也能正常启动。
  5. 确保使用 ScanPolicy 限制加载不受信任的设备。要想做到足够安全,最好的办法是禁止加载 所有可移动设备 和 未知的文件系统。
  6. 使用私钥给所有已安装的驱动程序和工具签名。不要对提供管理员权限的工具(如 UEFI Shell)签名。
  7. 加密存储你的配置,详见 Vault 部分。
  8. 使用同一私钥签名该系统使用的所有 OpenCore 二进制文件(BOOTX64.efi, BOOTIa32.efi, OpenCore.efi, 自定义启动器)。
  9. 如果需要用到第三方操作系统(非微软或 Apple 制造)的 bootloader,也同样为它们签名。对于 Linux,可以选择安装微软签名的 Shim bootloader,具体解释见 Debian Wiki。
  10. 在 BIOS 中开启 UEFI 安全启动,并用自己的私钥安装证书。很多文章都介绍了生成证书的具体方法,比如 这篇文章,本文档不再赘述。如果需要启动 Windows,还需要添加 Microsoft Windows Production CA 2011 证书。如果需要启动 Option ROM,或决定使用已签名的 Linux 驱动程序,还需要添加 Microsoft UEFI Driver Signing CA。
  11. 设置密码保护防止固件设置被篡改,避免 UEFI 安全启动在你不知情的情况下被禁用。

12.3 Windows 支持

1. 我能安装 Windows 系统吗?

虽然 OpenCore 并没有提供官方的 Windows 支持,但是使用 Boot Camp 安装 64 位 UEFI Windows(即 Windows 8 及更高版本)应该是可以正常工作的。安装第三方 UEFI、或者仅部分支持 UEFI 引导的系统(如 Windows 7)可能需要额外注意。不论如何,记住以下几点:

2. 我需要安装其他什么软件吗?

在大多数情况下,要启用多操作系统切换、安装相关驱动程序,你将需要 Boot Camp 提供的 Windows 支持软件。为了简化下载过程、或者配置硬盘中已经安装好的 Windows,可以使用 Brigadier 这个实用软件。请注意在使用 Brigadier 之前,你可能需要先下载并安装 7-Zip。

译者注:7-zip 官方中文网站

记住,一定要使用最新版本的 Boot Camp 的 Windows 支持软件。6.1 之前的版本不支持 APFS 文件系统、因此无法运行。要下载最新的软件,请将最新 Mac 的型号作为参数传递给 Brigadier,如 ./brigadier.exe -m iMac19,1。之后,在不受支持的 Mac 型号上安装 Boot Camp,请以管理员身份运行 PowerShell,输入 msiexec /i BootCamp.msi 即可。如果你之前不小心已经安装了旧版本的 Boot Camp,则必须先通过运行 msiexec /x BootCamp.msi 将其卸载。BootCamp.msi 文件位于 BootCamp/Drivers/Apple 目录中、可以通过资源管理器访问。

译者注:在资源管理器下,按住 <kbd>Shift</kbd> 同时右击窗口中空白处,此时菜单中会显示「在此处运行 PowerShell」,即在当前目录下运行 PowerShell。但是这种方式启动的 PowerShell 不具备管理员权限。

尽管 Boot Camp 提供的 Windows 支持软件解决了大多数兼容性问题,但是有时候您还是需要手动解决一些问题:

3. 为什么我会在 Boot Camp 启动硬盘 控制面板 中看到 Basic data partition

Boot Camp 使用 GPT 分区表获取每个引导选项的名称。独立安装 Windows 后,你必须手动重新标记分区。这可以通过许多工具完成,比如开源的 gdisk,使用方法如下:

PS C:\gdisk> .\gdisk64.exe \\.\physicaldrive0
GPT fdisk (gdisk) version 1.0.4

Command (? for help): p
Disk \\.\physicaldrive0: 419430400 sectors, 200.0 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): DEC57EB1-B3B5-49B2-95F5-3B8C4D3E4E12
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 419430366
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1023999   499.0 MiB   2700  Basic data partition
   2         1024000         1226751   99.0 MiB    EF00  EFI system partition
   3         1226752         1259519   16.0 MiB    0C01  Microsoft reserved ...
   4         1259520       419428351   199.4 GiB   0700  Basic data partition

Command (? for help): c
Partition number (1-4): 4
Enter name: BOOTCAMP

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to \\.\physicaldrive0.
Disk synchronization succeeded! The computer should now use the new partition table.
The operation has completed successfully.

<center><em><strong>Listing 4</strong>: 重新标记 Windows 卷宗</em></center>

4. 如何选择 NTFS 驱动程序

提供 NTFS 读写支持的第三方驱动程序,如 NTFS-3G、Paragon NTFS、Tuxera NTFS 或 希捷移动硬盘 Paragon 驱动程序 会破坏 macOS 的功能,比如 系统偏好设置 中的 启动磁盘 选项。 虽然我们仍然不建议使用这些经常破坏文件系统的驱动程序(我们推荐使用 macOS 内建的 NTFS 读写支持,可以通过 终端 或 GUI 启用),但是这些驱动程序的厂商也提供了他们各自的解决方案,在这里我们仅列举两个:

译者注:虽然 acidanthera 团队推荐使用 macOS 内置的 NTFS 支持,但是译者强烈反对这种方法(不论是直接方法还是使用类似 Mounty 的第三方工具)。修改 fstab 的风险是极高的。在你清楚你在做什么之前,不要轻举妄动!!

12.4 调试

与其他硬件相关的项目类似,OpenCore 也支持审计与调试。使用 NOOPTDEBUG 构建版本(而非 RELEASE 构建版本)可以产生更多的调试输出。对于 NOOPT 构建版本,你还可以使用 GDB 或 IDA Pro 进行调试。对于 GDB 请查看 OpenCore Debug 相关页面;对于 IDA Pro,你需要 7.3 或更高版本,更多详细信息请参考 IDA Pro 提供的页面:Debugging the XNU Kernel with IDA Pro。

可以使用串口调试来获取启动过程中的日志。串口调试是在 Target 中开启的,例如 0xB 代表在屏幕上显示并输出串行。可使用 SerialInit 配置选项来初始化串行。对于 macOS 来说,最好是选择基于 CP2102 的 UART 设备。将主板 TX 连接到 USB UART RX,主板 GND 连接到 USB UART GND。使用 screen 实用工具,或者下载 GUI 软件获取输出,如 CoolTerm。

:在一些主板(可能还有一些 USB UART 转换器)上,PIN 的命名可能是不正确的。GNDRX 互换是很常见的,因此你需要将主板 "TX" 连接到 USB UART GND,主板 "GND" 连接到 USB UART RX

务必记得在固件设置中启用 COM 口,一定不要使用超过 1 米的 USB 线缆,以免输出数据损坏。如果要额外启用 XNU 内核串行输出,则需要添加 debug=0x8 启动参数。

12.5 技巧和窍门

1. 啊呀呀呀我系统没法启动了我该怎么看日志啊?

通常情况下,获取实际的错误信息就足够了。为此,请确保:

如果你在日志中看不出明显的错误,请逐一检查 Quirks 部分中可用的 hacks。例如,对于 Early Boot 出现的问题(如 OpenCore 启动菜单无法显示),通过 UEFI Shell(随 OpenCore 打包在一起)可以查看相关调试信息。

2. macOS 启动失败我该怎么调试?

3. 如何自定义启动项?

OpenCore 遵循 Apple Bless 标准模型、从引导目录中的 .contentDetails.disk_label.contentDetails 文件中提取条目名称。这些文件包含带有输入标题的 ASCII 字符串,你可以修改它们。

4. 如何选择默认启动的系统?

OpenCore 使用 UEFI 首选启动项 来选择默认的启动项。设置的方式随 BIOS 不同而不同,具体请参考 macOS 启动磁盘 或 Windows 启动转换 控制面板。

由于使用 OpenCore 提供的 BOOTx64.efi 作为首选启动项会限制这项功能(可能还会导致一些固件删除不兼容的引导选项),我们强烈建议你启用 RequestBootVarRouting Quirk,这会将你所做的选择保留在 OpenCore 变量空间中。请注意,RequestBootVarRouting 需要单独的 .efi 驱动文件(译者注:即 OpenRuntime.efi)。

5. 安装 macOS 最简单的方法是什么?

在线安装。将 Recovery 镜像(*.dmg*.chunklist 文件)和 OpenCore 一起复制到一个 FAT32 分区中。加载 OpenCore 的启动菜单并选择后缀为 .dmg 的条目。如果你有强迫症,你可以修改 .contentDetails 文件改变条目显示的文字。

你可能会用到 AppleModels 内置的 macrecovery.py 来下载 Recovery 镜像。

如果你需要进行离线安装,请参考 如何创建可引导的 macOS 安装器。除了通过 App Store 或 系统更新,你还可以使用 第三方工具 下载 macOS 镜像文件。

6. 为什么无法加载 Recovery 恢复镜像 进行在线安装?

可能是因为你没带 HFS+ 驱动。目前我们所知道的 Recovery 分区全都是 HFS+ 文件系统。

7. 我可以在 Apple 的硬件、或虚拟机中使用 OpenCore 吗?

可以,没有必要,但请加大力度

OpenCore 支持包括 MacPro 5,1 和虚拟机在内的大部分较新的 Mac 型号。不过,OpenCore 有关在 Mac 硬件上使用的具体细节微乎其微。你可以在 MacRumors.com 查看相关讨论。

8. 为什么 Find 和 Replace 的补丁的长度必须相等?

对于 x86 机器码来说,相对寻址 无法进行大小不同的替换。对于 ACPI 代码来说这是有风险的,而且在技术上这与替换 ACPI 表等价,所以 OpenCore 没有实现。更多详细的解答可以在 AppleLife.ru 上和本文档的 ACPI 章节找到。

9. 我应该如何决定哪些 Booter Quirk 需要被启用?

这些 Quirk 源自 AptioMemoryFix 驱动,为更多的固件提供了广泛支持。如果你正在使用 OpenRuntime,并且想要获得和 AptioMemoryFix 类似的行为,请启用下述 Quirk:

但是,对于大部分现代的设备来说,上述 Quirk 不一定是必需的。比如 DevirtualiseMmioProtectUefiServices 通常是需要启用的,但是 DiscardHibernateMapForceExitBootServices 一般不建议启用。

不幸的是,对于某些 Quirk 来说(RebuildAppleMemoryMap, EnableWriteUnprotector, ProtectMemoryRegions, SetupVirtualMapSyncRuntimePermissions)由于没有明确的参考,因此需要自行尝试最佳组合。详细内容请参考本文档中对这些 Quirk 的描述。

结束语

到此,OpenCore 安装教程已经结束了,感谢大家一路看到这里,也希望本文能为大家提供帮助。