从 Clover 到 OpenCore —— Clover 迁移 OpenCore 指南
随着 OpenCore 日渐成熟、acidanthera 团队宣布放弃旗下绝大部分内核驱动(包括 Lilu、VirtualSMC、WhateverGreen、AppleALC 等)对 Clover 的兼容性支持,与其届时被迫更换,不如主动从 Clover 迁移 OpenCore。
当然面对迁移,有的人会选择直接抛弃之前 Clover 的全部成果,直接从零开始配置 OpenCore。但是我相信对于大部分人来说更希望通过简简单单的修补,在现有的 EFI 的基础上迁移到 OpenCore,因此我开始撰写这篇文章。
然而不幸的是从 Clover 切换到 OpenCore 并不是一个简单的任务,因此这种迁移应该是渐进式的,不可能一蹴而就。那什么是「渐进式」呢?意思就是,如果你按照本文的步骤一步一步按顺序进行,那么大部分迁移步骤产生的修改,在 Clover 下一样可用,你不需要一下子就扔掉 Clover。
序言以外应该写在最前面的话
- OpenCore 丢掉了不少 Clover 的历史包袱。毫无疑问依然有不少 Clover 设置在 OpenCore 是没有可以直接替代的。因此 Clover 完全照搬到 OpenCore 是肯定行不通的。
- 在迁移到 OpenCore 之前,Clover 的大部分设置都要精简:用 SSDT 代替、改为注入设备属性(Device Properties)。这篇教程就是在教你这些。
- 如果你一开始在组织 Clover 的 EFI 时就有洁癖的话,你会发现迁移到 OpenCore 出人意料地简单。
- 只有完美的 Clover 的 EFI,在按照本文档的步骤精简后能获得完美的 OpenCore 的 EFI。如果你的 EFI 是不完美的,那么迁移到 OpenCore 也一定是不完美的。因此,如果你是为了解决不完美、才想迁移到 OpenCore,那么我建议先在 Clover 下完善。
- 独木难成林。这篇教程初次发布以后,Bat.bat 等许多大佬在 远景论坛、Telegram 上提供了许多意见,正是在他们的帮助下,这篇教程得以不断完善。
更新日志
- 2020-06-01:更新关于 OpenCore 0.5.8 和 OpenCore 0.5.9 的内容。
- 2020-04-21:补充关于 macOS、Windows 的时钟设备的说明;补充了可以被删除的 XCPM KextsToPatch 列表。
- 2020-04-13:在 SSDT 修改教程中为 SSDT 样例代码补充了注释,便于新手理解。
修改 SSDT / DSDT 以兼容 OpenCore
OpenCore 和 Clover 最大的不同之一是,acidanthera 决定在 OpenCore 中设置的 SMBIOS 机型信息、DSDT 和 SSDT,都将一视同仁地对所有操作系统生效。这样做的目的是让黑苹果更像白苹果,但是却有可能导致在 macOS 上正常可用的 ACPI 表到了 Windows 上反而会出问题。
因此,我个人推荐迁移到 OpenCore 从修改现有的 SSDT 和 DSDT 开始。虽然修改 SSDT、DSDT 并不简单,但是却是每一个黑苹果玩家必须掌握的知识。而且在 OpenCore 下能用的 SSDT、DSDT 在 Clover 下一定也是可用的,所以当你完成对 SSDT、DSDT 的修改后,你可以继续使用 Clover 而不受影响。
这里主要介绍对 ACPI 中 Method
函数的修改方法。以 GPRW(6D0D)「睡了即醒」补丁为例,在 Clover 上我们的补丁一般长这样:
//
// In config ACPI, GPRW to XPRW
// Find: 47505257 02
// Replace: 58505257 02
//
DefinitionBlock ("", "SSDT", 2, "SUKA", "GPRW", 0)
{
External(XPRW, MethodObj)
Method (GPRW, 2, NotSerialized)
{
If ((0x6D == Arg0))
{
Return (Package ()
{
0x6D,
Zero
})
}
If ((0x0D == Arg0))
{
Return (Package ()
{
0x0D,
Zero
})
}
Return (XPRW (Arg0, Arg1))
}
}
这个 SSDT 的原理是,通过 DSDT 重命名将原始的 GPRW,2
函数重命名为 XPRW,2
,然后通过 SSDT 新增一个 GPRW
函数;ACPI 调用 GPRW
函数时其实是调用的 SSDT 里添加的 GPRW
函数。
在 Clover 下,所有 ACPI 相关设置(SSDT、DSDT 以及 DSDT 重命名)只会对 macOS 生效;但是现在,OpenCore 一视同仁,所有 SSDT、DSDT 重命名会对包括 Windows 在内的所有操作系统生效,那么现有 SSDT 中的 GPRW
函数也会在 Windows 生效,可能就会导致未知的后果。所以,我们需要通过 OSI
操作系统判断函数,确保 SSDT 中的 GPRW 函数的行为只对 macOS 操作系统生效:
//
// In config ACPI, GPRW to XPRW
// Find: 47505257 02
// Replace: 58505257 02
//
// 需要注意的是,ACPI 里不支持非 ASCII 字符注释,这里仅做示例,不可直接用于编译
DefinitionBlock ("", "SSDT", 2, "OCLT", "GPRW", 0)
{
External(XPRW, MethodObj) // 对 XPRW 函数的外部引用
Method (GPRW, 2, NotSerialized)
{
If (_OSI ("Darwin")) // 如果当前的操作系统是 macOS,生效以下行为
{
If ((0x6D == Arg0)) // 如果第一个参数是 0x6D
{
Return (Package () // 返回 06D,0x00 函数结束
{
0x6D,
Zero
})
}
If ((0x0D == Arg0)) // 如果第一个参数是 0x0D
{
Return (Package () // 返回 0x0D,0x00 函数结束
{
0x0D,
Zero
})
}
}
// 否则,直接返回 XPRW 函数。由于这个函数是以 Return 结束,所以 If 后面可以不带 Else。
// 只有三种情况下会走到这一步:第一个参数不是 0x6D;第一个参数不是 0x0D;当前操作系统不是 macOS
// XPRW 是 DSDT 中原始的 GPRW 函数重命名而来,实际上是调用了原始 DSDT 中原始的 GPRW 函数
Return (XPRW (Arg0, Arg1))
}
}
上面以 GPRW(6D0D)「睡了即醒」补丁为例介绍了 OpenCore 下编写 SSDT 的相关思路,接下来我们以亮度快捷键补丁为例,讲解如何逐步修改 Clover 下可用的 SSDT、使其兼容 OpenCore。
大部分亮度快捷键都是通过 EC Query 触发的,因此在 Clover 中我们的亮度快捷键 SSDT 可能是这样的:
// In config ACPI, _Q14 renamed XQ14
// Find: 5F 51 31 34
// Replace: 58 51 31 34
// In config ACPI, _Q15 renamed XQ15
// Find: 5F 51 31 35
// Replace: 58 51 31 35
DefinitionBlock("", "SSDT", 2, "SUKA", "BrightFN", 0)
{
External(_SB.PCI0.LPCB.KBD, DeviceObj)
External(_SB.PCI0.LPCB.EC, DeviceObj)
Scope (_SB.PCI0.LPCB.EC)
{
Method (_Q14, 0, NotSerialized)//up
{
Notify(\_SB.PCI0.LPCB.KBD, 0x0406)
}
Method (_Q15, 0, NotSerialized)//down
{
Notify(\_SB.PCI0.LPCB.KBD, 0x0405)
}
}
}
亮度快捷键补丁的具体工作原理,请参看我的另一篇文章「黑苹果自定义键盘 Fn 快捷键」。
根据同样的思路,我们先在 Method 定义中添加 OSI
函数判断操作系统:
DefinitionBlock("", "SSDT", 2, "SUKA", "BrightFN", 0)
{
External(_SB.PCI0.LPCB.KBD, DeviceObj)
External(_SB.PCI0.LPCB.EC, DeviceObj)
Scope (_SB.PCI0.LPCB.EC)
{
Method (_Q14, 0, NotSerialized)//up
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0406)
+ }
}
Method (_Q15, 0, NotSerialized)//down
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0405)
+ }
}
}
}
由于这里的函数不是以 Return 结束的,所以我们要为 If
加上 Else
:
DefinitionBlock("", "SSDT", 2, "SUKA", "BrightFN", 0)
{
External(_SB.PCI0.LPCB.KBD, DeviceObj)
External(_SB.PCI0.LPCB.EC, DeviceObj)
Scope (_SB.PCI0.LPCB.EC)
{
Method (_Q14, 0, NotSerialized)//up
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0406)
+ } Else {
+
+ }
}
Method (_Q15, 0, NotSerialized)//down
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0405)
+ } Else {
+
+ }
}
}
}
在 Else
区域中,调用原始 DSDT 中原始的 _Q14
、_Q15
函数、也就是现在已经被重命名为 XQ14
和 XQ15
的函数。当然,别忘了在文件头部添加对 XQ14
和 XQ15
的函数的外部引用(函数的外部引用类型为 MethodObj
):
DefinitionBlock("", "SSDT", 2, "SUKA", "BrightFN", 0)
{
External(_SB.PCI0.LPCB.KBD, DeviceObj)
External(_SB.PCI0.LPCB.EC, DeviceObj)
+ External(_SB.PCI0.LPCB.EC.XQ14, MethodObj)
+ External(_SB.PCI0.LPCB.EC.XQ15, MethodObj)
Scope (_SB.PCI0.LPCB.EC)
{
Method (_Q14, 0, NotSerialized)//up
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0406)
+ } Else {
+ \_SB.PCI0.LPCB.EC.XQ14()
+ }
}
Method (_Q15, 0, NotSerialized)//down
{
+ If (_OSI ("Darwin"))
+ {
Notify(\_SB.PCI0.LPCB.KBD, 0x0405)
+ } Else {
+ \_SB.PCI0.LPCB.EC.XQ15()
+ }
}
}
}
这样就大功告成了。
是不是有些头昏脑涨?实际上,和 Clover 现成的 SSDT 补丁库一样,OpenCore 也有现成的 SSDT 补丁库 OC-little,由资深黑苹果爱好者们维护。我也在其中贡献了一些补丁(如 PTWSAK 关机变重启修复)。 你在 Clover 中使用的 SSDT 补丁,大部分都有对应的 OpenCore 下可用的 SSDT 替代,免去了你手动修改的痛苦。而且,你还可能通过 OC-little 库里的其他补丁修复了一些你之前没有解决的问题。
当然,对于一些 OC-little 中没有等价替代的补丁,你仍然需要手动修改、添加操作系统判断;对于直接修补的 DSDT,你也只能自己在 Method
中添加对应的判断。
如果你完成了对 SSDT、DSDT 的修改,现在备份你的 EFI、然后修改后的 SSDT、DSDT 放到 EFI/Clover/ACPI/patched
之中,然后以 -v
重启,看看能不能正常开机。如果可以正常开机,登录以后打开终端执行以下命令、查看日志中是否包括 ACPI Error
:
$ log show --last boot | grep -Ei "ACPI"
如果正常开机,日志中没有 ACPI Error
,那么恭喜你,你已经迈出了向 OpenCore 迁移的第一步。此时你依然可以继续使用 Clover,你的黑苹果没有受到任何影响。
减少不必要的 DSDT 重命名
acidanthera 团队认为,不恰当的 DSDT 重命名可能会对设备硬件造成伤害;而且,OpenCore 下的 DSDT 重命名会对包括 Windows 在内的所有操作系统生效。
因此,迁移到 OpenCore 时很重要的一步是减少不必要的 DSDT 重命名:既降低伤害硬件的概率、又尽可能避免 Windows 等其它操作系统受到影响。
以下是一些不再需要的 DSDT 重命名,可以参考这个表进行精简、使用 SSDT 代替:
EHC1 to EH01
和EHC2 to EH02
:六代(Skylake)及以上的机器已经没有 EHC 控制器了,建议用 OpenCore 官方的SSDT-EHCx_OFF
关闭 EHC 控制器、并把重命名删除。六代以下机器保留该重命名。SAT0 to SATA
和SAT1 to SATA
:实质上完全没用。HECI to IMEI
、HEC1 to IMEI
、MEI to IMEI
和IDER to MEID
:WhateverGreen 能够处理这个问题。GFX0 to IGPU
、PEG0 to GFX0
、PEGP to GFX0
和SL01 to PEGP
:WhateverGreen 能够处理这个问题。除非你没有使用 WhateverGreen,否则没必要保留这些重命名。EC0 to EC
、H_EC to EC
、ECDV to EC
和PGEC to EC
:虽然 macOS 的 USB 电源管理需要名称为EC
的控制器,但是你完全可以使用 OC-little 中的「仿冒 EC」补丁。随意重命名 EC 控制器可能会对硬件造成伤害!。HDAS to HDEF
、CAVS to HDEF
和AZAL to HDEF
:AppleALC 能够处理这个问题。除非你在用 VoodooHDA 万能声卡驱动,否则没必要保留这些重命名。STAS to Noop
:建议由 OC-little 中的SSDT-AWAC
相关补丁替代。
虽然新的时钟设备 AWAC 逐渐普及,但是 macOS 尚不支持 AWAC,因此在 macOS 下需要使用传统的 RTC。
在 DSDT 中有一个STAS
变量使 AWAC 和 RTC 互锁、避免两个时钟设备同时启用。
由于部分机器无法在 BIOS 中禁用 AWAC 启用 RTC,传统的解决方法是将STAS
重命名为Noop
,从而同时启用两个时钟设备,而在 macOS 下只有一个 RTC 能正常工作。
但是如果这一重命名在 Windows 下也生效,意味着在 Windows 下将会暴露两个时间设备,这无疑对系统有害。同时,这也严重违反 ACPI 规范。
因此,在 OpenCore 下应该通过SSDT-AWAC
修改STAS
变量的值,实现在 macOS 下禁用 AWAC、启用 RTC。
感谢 Bat.bat 大佬指出。
PXSX to ANS1
和PXSX to ANS2
:建议用 NVMeFix.kext 修复 NVMe SSD 的电源管理。LPC0 to LPCB
:如果你要添加 SMBUS 支持,OC-little 中分别有 SBUS 的 SSDT 注入补丁和 MCHC 设备补丁。
顺便提醒一下,使用 OC-little 的补丁的时候,需要注意设备的原始 DSDT 中的 LPC 总线名称,并且必要时要自己修改 SSDT 以使 LPC 总线名称匹配。
PC00 to PCIO
、FPU to MATH
、TMR to TIMR
、GBE1 to ETH0
和PIC to IPIC
:这些重命名实质上也是完全没用的。_OSI to XOSI
和OSID to XSID
:除非你的某些硬件设备只能在 Windows 下工作(比如 I2C 触摸板只能在 Windows 下使用,再比如 ThinkPad 对 FreeBSD 的特殊优化),否则完全没有必要使用SSDT-XOSI
补丁来伪装操作系统。而且大部分情况下,直接定制 SSDT 也可以解除某些硬件的操作系统限制。
关于「定制 SSDT 以解除限制」,一种方法是通过「预置变量法」(详见 OC-little 的「总述」章节)禁用原始设备的函数如
_STA
,另一种方法是通过延长 Find 和 Replace 的上下文实现对相关_STA
的函数的精确重命名,然后通过 SSDT 添加新的_STA
函数。
感谢 Bat.bat 大佬补充说明。
_DSM to XDSM
:首先遍历一下你的 SSDT 补丁中没有依赖_DSM
的,如果没有,这个重命名也应该删除,因为这个重命名涉及的范围实在太大了、太过于危险。
我的建议是,尽可能只添加和 Method
名称有关的重命名(如 GPRW to XPRW
、_Q14 to XQ14
),而且随后要通过 SSDT 确保在非 macOS 操作系统下要调用并返回原始函数,确保在非 macOS 操作系统下的原始 DSDT 行为不会被改变。如果万不得已要添加其它重命名(如通过重命名禁用某些设备),那么就要权衡这一重命名的后果。
如果你完成了精简 DSDT 重命名并保存了 config,接下来的操作还是一样的,备份原始 EFI、然后以 -v
重启,看看能不能正常开机。如果可以正常开机,登录以后打开终端执行以下命令、查看日志中是否包括 ACPI Error
:
$ log show --last boot | grep -Ei "ACPI"
上述修改和 Clover 依然是兼容的,完成精简 DSDT 重命名后依然可以继续使用 Clover。
摆脱对 Clover ACPI Quirks 的依赖
Clover 的 ACPI Quirks 的确是非常方便。一个开关,关机变重启就修复了;三个开关,声卡 HPET、IRQ、TIMR 就修复了;等等等等。但是在 OpenCore 是没有内置这些 ACPI 修复的,所以在 Clover 下的 ACPI Quirk 现在都必须用 SSDT 实现。所幸的是,我们依然可以从 OC-little 里找到绝大部分我们需要的补丁。
- FixIPIC:使用 OC-little 的「声卡 IRQ 补丁」章节中的
SSDT-IPIC
- FixSBUS:参考 OC-little 的「注入设备」章节中的「SBUS_SMBU 补丁」
- FixShutdown:参考 OC-little 的「PTSWAK 综合补丁章节」,需要添加其中的 EXT1 插件补丁(该补丁由我贡献)
- FixDisplay:使用 WhateverGreen 和在缓冲帧补丁中定制显示接口解决
- AddMCHC:使用 OC-little 的「添加缺失的设备」章节中的
SSDT-MCHC
- FixHDA:该修复已包含在 AppleALC 中,使用 AppleALC 即可。
- FixHPET、FixRTC 和 FixTIMR:使用 OC-little 的「声卡 IRQ 补丁」章节中的
SSDT-HPET_RTC_TIMR-fix
注意根据原始 DSDT 查看
_STA
内变量是HPAE
还是HPTE
,并自行修改 SSDT。
- FixSATA:这个先不管它,OpenCore 中有对应的
ExternalDiskIcons
的 Quirk,也可以使用innie.kext
解决 - AddPNLF:参考 OC-little 的「注入设备」章节中的「PNLF 注入方法」
- AddIMEI:使用 WhateverGreen 即可
- FixIntelGfx:使用 WhateverGreen 即可
- AddHDMI:使用 WhateverGreen 即可
- FixADP1:有两种修复方法
- 直接 DSDT 重命名
AC0_ to ADP1
,根据原始 DSDT 中对AC0_
设备的定义,可能还需要用 SSDT 为ADP1
设备注入Name (_PRW, Package (0x02) {0x1C,0x03})
。 - 使用 SSDT 的方法,禁用原始
AC0_
设备,并新增ADP1
设备。根据原始 DSDT,可能还要为新增的ADP1
设备添加Name (_PRW, Package (0x02) {0x1C,0x03})
- 直接 DSDT 重命名
DefinitionBlock ("", "SSDT", 2, "SUKA", "FixADP1", 0x00001000)
{
External (_SB_.ADP1, DeviceObj)
External (_SB_.AC0_, DeviceObj)
If (_OSI ("Darwin"))
{
Scope (\_SB)
{
Scope (AC0_)
{
Method (_STA, 0, NotSerialized)
{
Return (Zero)
}
}
Device (ADP1)
{
Name (_ADR, Zero)
Name (_PRW, Package (0x02) {
0x1C,
0x03
})
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
}
}
}
}
除了这些开关以外,Clover 还有一些其它的 ACPI 设定,也有与之对应的替代。
- DisableASPM:没有很好的代替方法,可以在设备属性(Device Properties)中分别添加相关设备的 PCI 总线位置、并注入属性
pci-aspm-default | DATA | <00>
。 - PluginType:参考 OC-little 的「注入 X86」章节添加
SSDT-PLUG
补丁。 - Generate P States 和 Generate C States:这些是六代以前 CPU 才需要的设置,可以用 ssdtPRGen.sh 生成对应的 SSDT。
- 降压和超频功能:Clover 的实现相当简陋,即使 Clover 官方也不建议使用;降压推荐使用 VoltageShift。
完成上述配置项的精简后,还是以 -v
重启,正常开机后在终端查看日志中是否包括 ACPI Error
:
$ log show --last boot | grep -Ei "ACPI"
当你把所有 Clover 的开关都用 SSDT 代替以后,你离迁移到 OpenCore 就越来越近了。
更新设备属性
注入设备属性以驱动 Intel 核显
如果你还在用 Clover 的 InjectIntel
的方式来驱动 Intel 核显的话,是时候更换到通过设备属性(Device Properties)中注入缓冲帧补丁、搭配WhateverGreen 的方式了。
建议参考以下文章:
- 使用 WhateverGreen 驱动 Intel 核显 | 醉渔小站
- Hackintool(原Intel FB-Patcher)使用教程及插入姿势 | 黑果小兵的部落阁
- Intel 核显驱动常见问题 | WhateverGreen (务必看英文版,中文翻译严重过时)
新的声卡 layout-id 注入方式
大部分 AppleALC 驱动声卡的教程都已经推荐 Clover 中将此处留空、直接在设备属性(Device Properties)中注入 layout-id
了,不过我还是再冗笔一下。
下载 acidanthera 开发的工具 gfxutils,使用下述命令找出声卡的 PCI 总线位置:
$ path/to/gfxutils -f HDEF
$ path/to/gfxutils -f HDAS
$ path/to/gfxutils -f HDAU
然后在设备属性中添加声卡的 PCI 总线位置、注入 layout-id
属性。
Clover 中还有两个声卡相关的 Quirk,但是在 OpenCore 中并没有等效替代的配置:
AFGLowPowerState
,需要手动在设备属性中为声卡设备注入AFGLowPowerState
属性,类型和值为DATA | <01000000>
。ResetHDA
,推荐安装 JackFix 以及配套的守护进程,除了支持 ResetHDA、还支持 3.5mm 耳机接口的类型切换。
开始迁移到 OpenCore
终于,所有的准备工作都完成了!你可以抽出一天(最好占卜一下是否是吉日),沐浴更衣,然后开始将你的 EFI 迁移 OpenCore。
下载 OpenCore 所需文件
- OpenCorePkg - OpenCore 本体、一些 SSDT 补丁、目录结构
AppleSupportPkg - 包括三个 EFI 驱动,ApfsDriverLoader、VBoxHfs、AudioDxe
从 OpenCore 0.5.8 开始,ApfsDriverLoader 已经合并为 OpenCore 的一部分;VBoxHfs 和 AudioDxe 已和 OpenCorePkg 打包在一起。因此已经无需再额外下载 AppleSupportPkg(同时该项目已经存档),只需下载一个 OpenCorePkg 即可。
- OcBinaryData - 包含两个闭源驱动
HfsPlus.efi
和ExFatDxe.efi
,以及 OpenCore 官方主题的图标文件。- 非常推荐安装 OpenCore 官方做的主题,和真 Mac 的 BootPicker 一模一样(除了没有网络图标)。不过那可能是另一篇文章的内容了。
决定你使用的配置文件编辑器
- ProperTree:一个 Python 编写的 plist 编辑器,专门优化了 OpenCore 和 Clover 配置文件编写。
- 据说在处理大整数方面存在问题,但我在 GitHub Issue 中并没有看到。如果有人遇到了建议前往 GitHub Issue 提交反馈。
- Xcode:非常不推荐,Xcode 11 不仅花里胡哨、而且处理 plist data 和大整数方面存在问题。
- 简单来说,Apple 没有再开放旧版的 Xcode 10 下载、而且 Apple 的 CDN 还有防盗链。因此如果我要写一篇从 Apple 官方下载 Xcode 10 的教程,那么会比你现在看的这篇的「从 Clover 到 OpenCore」要长得多。
- 如果你和我一样成功下载了 Xcode 10 或者就没有升级到 Xcode 11:我刚才什么都没写,你什么都没看见。
- OpenCore Configurator:Clover Configurator 开发者的新作品。很适合新手使用。
- OpenCore 的配置文件变更非常频繁,因此只应该用 最新版的 OpenCore Configurator 搭配 最新的正式版的 OpenCore,否则配置文件格式错误将会导致无法引导。
- OpenCore Configurator 有不少低级 Bug(不过之后更新时都修复了),比如之前有一个版本,在应对
VoodooPS2Controller
和VooooI2C
这种嵌套 kext 时,会只添加内部 kext 的dsYM
签名文件、却不添加内部 kext 本体。 - 反正就是,使用后果自负。
组织 OpenCore 的目录
解压前一步下载的 OpenCorePkg,将其中的 EFI
目录 复制到别处。
直到配置好以后,再将这个目录合并进 硬盘/U 盘 上的 EFI 分区。
将 Docs
目录下的 Sample.list
复制到 EFI/OC
目录下、并重命名为 config.plist
。
SampleFull.plist
相比Sample.plist
,除 SMBIOS 机型设置部分更加完整以外,没有其它差别。除非你在模拟 2011 年以前的 Mac 机型,否则请不要使用SampleFull.plist
。
如果你下载的是 OpenCore 0.5.7 版本,还需要额外将Reources
目录复制到EFI/OC
目录之中。这是由于 OpenCore 编译脚本错误导致的,OpenCore 0.5.8 已经修复了这一问题。
解压下载的 AppleSupportPkg,将其中的 Drivers 目录和 Tools 目录中的文件复制到 EFI/OC/Drivers
目录和 EFI/OC/Tools
目录中。
如上文所述,AppleSupportPks 已经存档,其中的 UEFI 驱动和 UEFI Tools 已经全部合并进 OpenCorePkg。从 OpenCorePkg 中解压得到的
EFI
目录已经包含了全部的驱动。
解压下载的 OcBinaryData,将其中 Drivers
目录复制到 EFI/OC/Drivers
目录中。
删除不需要的文件
根据你的实际情况(机型、Intel CPU 世代、安装的 macOS 版本),选择性的删除 Drivers
目录中的这些文件:
ExFatDxe.efi
和ExFatDxeLegacy.efi
:除非你的 EFI 分区或者某个系统分区是 ExFAT 分区格式的,否则不需要保留。在四代以前机型上应该用ExFatDxeLegacy.efi
而不是ExFatDxe.efi
。HfsPlus.efi
、HfsPlusLegacy.efi
和VBoxHfs.efi
:三者只要留其中一个即可。一般推荐用HfsPlus.efi
,比VBoxHfs.efi
速度快三倍。在四代以前机型上应该用HfsPlusLegcay.efi
而不是HfsPlus.efi
。OpenUsbKbDxe.efi
(原名为AppleUsbKbDxe.efi
):为三代以前主板在引导时的键盘驱动,现代的机器应该直接使用 OpenCore 中的KeySupport
这个 Quirk。在 三代以后的机器上使用这一驱动会破坏硬件!。NvmExpressDxe.efi
:供四代以前主板在引导时的 NVMe 硬盘驱动,现代的机器已经不需要了。XhciDxe.efi
:为二代以前主板提供 XHCI 支持的,现代的机器已经不需要了。HiiDatabase.efi
:为四代以前主板提供 UEFI 界面字体渲染支持的,现代的机器已经不需要了。ExFatDxe.efi
:除非你有某些系统安装在 ExFAT 分区中、或者你的 EFI 分区时 ExFAT 格式的,否则可以删除。EnhancedFatDxe.efi
:除非你的 EFI 分区格式为 FAT16、而且在开机过程中可能会往 EFI 分区写入文件(如引导日志、截图等),否则可以删除。Ps2KeyboardDxe.efi
、Ps2MouseDxe.efi
和UsbMouseDxe.efi
:为三代以前机型准备的 PS/2 键盘鼠标、USB 鼠标的驱动。PartitionDxe.efi
:这是一个用于加载旧版 macOS(早于 macOS 10.9)分区映像文件(DMG)的驱动。在四代以前机型上应该用PartitionDxeLegacy
而不是PartitionDxe
。
删除 Tools
目录中的这些文件:
BootKicker.efi
:调用 Mac 内置的引导界面(即 BootPicker),是用于在白苹果上使用 OpenCore 时、通过 OpenCore 引导苹果官方引导菜单的。黑苹果无法使用苹果的引导菜单,可以直接删除。
删除上述不需要的文件以后,你的 OpenCore EFI 目录的结构应该是这样的:
EFI
├── BOOT
│ └── BOOTx64.efi
└── OC
├── ACPI
├── config.plist
├── Drivers
│ ├── ApfsDriverLoader.efi // OpenCore 0.5.8 不再包含这一文件
│ ├── AudioDxe.efi
│ ├── HfsPlus.efi
│ ├── OpenCanopy.efi
│ └── OpenRuntime.efi
├── Kexts
├── OpenCore.efi
├── Resources
└── Tools
├── ChipTune.efi
├── ......
└── VerifyMsrE2.efi
现在,你可以把你在之前步骤中修改过的 SSDT、DSDT 从 Clover/ACPI/Patched
中复制到 EFI/OC/ACPI
目录中;将 Kext 从 Clover/Kexts/*/
中复制到 EFI/OC/Kexts
目录中。
配置 OpenCore
由于已经有许多 OpenCore 配置的教程了,因此这里我就不再赘述。这里推荐几个写的不错的教程和足够有用的参考资料。
- OpenCore 参考手册。当你解压下载的 OpenCorePkg 时,
Docs/Configuration.pdf
文件就是 OpenCore 的官方文档。这是 最权威的 OpenCore 参考资料、没有之一。 - OpenCore 简体中文参考手册。OpenCore 参考手册的非官方简体中文翻译。这份翻译目前由我和一些黑苹果爱好者们共同在维护。
上面两份资料适合你在配置时不知道某个选项的 具体作用和副作用 时作为参考,但是新手不适合直接对照它们配置
config.plist
。
如果想要快速上手 OpenCore 配置,应该参考下面的教程:
- Dortania Guide。这是 acidanthera 团队认可的写得较好的新手教程。由于这篇教程的受众是第一次接触黑苹果就想用 OpenCore 进行引导的人,因此内容写得非常浅显。
- 精解 OpenCore | 黑果小兵的部落阁。国内最早介绍 OpenCore 的文章之一,提供了不少 OpenCore 配置的思路和 Quirks 的推荐配置。
- 使用 OpenCore 引导黑苹果 | XJN's Blog。比较详细的 OpenCore 配置介绍,主要面向台式机(不过这篇文章的排版我实在是欣赏不来)。
- OpenCore 引导迁移折腾记录 | 宇宙よりも遠い場所。内容详细的 OpenCore 配置介绍,提供了不少 Quirks 的推荐配置。
Clover 中的部分配置,如 DSDT 重命名,由于之前已经经过精简,因此可以直接将 Find 和 Replace 逐对复制到 OpenCore 的配置文件中。
需要注意的是,Clover 的 DSDT 重命名中提供了
TgtBridge
,但是这一实现充满 Bug,连 Clover 官方都不推荐使用。OpenCore 为 DSDT 属性添加了Count
、Limit
、Mask
等属性以实现精确重命名。如果你在 Clover 中部分 DSDT 重命名依赖TgtBridge
、建议舍弃或使用其它方法代替。
Clover 配置项在 OpenCore 中的等效配置
现在你开始跟着我推荐的教程和参考资料开始配置 OpenCore 了。本文接下来的内容包括 Clover 中的一些选项在 OpenCore 的对应等效配置,在配置 OpenCore 时别忘了跟着看看。
ACPI 相关设置
- HaltEnabler:在 OpenCore 中有一个等效的 Quirk
ACPI -> Quirks -> FadtEnableReset -> YES
。
Boot 相关设置
- 引导参数:OpenCore 中
NVRAM -> Add -> 7C436110-AB2A-4BBB-A880-FE41995C9F82 -> boot-args
- NeverHibernate:
Misc -> Boot -> HibernateMode -> None
- 其实不再建议禁用休眠,由于 OpenCore 的行为和白苹果更加接近,已经可以实现 macOS 的完美休眠。
- Default Boot Volume:OpenCore 中
Misc - Security - AllowSetDefaults - true
- 然后在 OpenCore 的引导菜单处使用 Ctrl + Enter 按键进行选择
- 你也可以直接使用 macOS「系统偏好设置」中的「启动磁盘」设置
- OpenCore 不支持 Clover 的
LastBootedVolume
- DefaultBackgroundColor:需要注入到 NVRAM 中
NVRAM -> Add -> 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14-> DefaultBackgroundColor
,需要自行将 RGB 转换为 HEX 然后填入。
- EFILoginHiDPI:需要注入到 NVRAM 中
NVRAM -> Add -> 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14 -> EFILoginHiDPI | Data | <>
- Clover:
0
-> NVRAM:<00000000>
- Clover:
1
-> NVRAM:<01000000>
- flagstate:需要注入到 NVRAM 中
NVRAM -> Add -> 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14 -> flagstate | Data | <>
- Clover:
0
-> NVRAM:<00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000>
- 注意自行判断 NVRAM 键值对位置
- UIScale:需要注入到 NVRAM 中
NVRAM -> Add -> 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14 -> UIScale | Data | <>
- Clover:
1
-> NVRAM:<01>
- Clover:
2
-> NVRAM:<02>
CPU 相关设置
- Type:在 OpenCore 中有对应的
Platforminfo -> SMBIOS -> ProcessorType
可以设置处理器类型- 在 EfiPkg 查看可以选用的值
- HWPEnable:如果你真的要依赖
MSR 0x770
(注意这里说的不是原生电源管理MSR 0xe2
)的 HWP 电源管理,建议安装 headkaze 开发的HWPEnable.kext
。HackinTool 也是他开发的。 - QEMU:OpenCore 已经完整支持各种虚拟机,因此 OpenCore 中不包含对应选项。
- TurboDisable:建议用 CPUFriend 或者 ssdtPRGen.sh 来修复变频和电源管理。
设备属性相关设置
USB
- FixOwnership:OpenCore 中
UEFI -> Quirk -> ReleaseUsbOwnership
- ClockID:需要自己注入对应的设备属性(Device Properties),属性为
AAPL,clock-id
- HighCurrent:需要自己注入对应的设备属性(Device Properties),属性为
AAPL,HighCurrent
- 对于 macOS 10.11 来说 HighCurrent 已经没啥用了。对于更新版的 macOS,推荐用 OC-little 中的
SSDT-USBX
补丁。
- 对于 macOS 10.11 来说 HighCurrent 已经没啥用了。对于更新版的 macOS,推荐用 OC-little 中的
FakeID
同样使用 gfxutils 工具找到 PCI 总线位置,然后分别注入相关属性:
- USB
device-id
device_type
device_type
- IMEI
device-id
vendor-id
- WIFI
name
compatible
- LAN
device-id
compatible
vendor-id
- XHCI
device-id
device_type: UHCI
device_type: OHCI
device_type: EHCI
device-id
AAPL,current-available
AAPL,current-extra
AAPL,current-available
AAPL,current-extra
AAPL,current-in-sleep
built-in
device_type: XHCI
device-id
AAPL,current-available
AAPL,current-extra
AAPL,current-available
AAPL,current-in-sleep
built-in
图形属性相关设置
和前文一样,这些在 Clover 中设置的属性都需要改为注入对应的设备属性(Device Properties)即可。
- InjectAti:
DeviceProperties -> Add -> PCIRoot... -> deviceID
DeviceProperties -> Add -> PCIRoot... -> Connectors
- InjectNvidia:
DeviceProperties -> Add -> PCIRoot... -> DeviceID
DeviceProperties -> Add -> PCIRoot... -> Family
- FakeAti:
DeviceProperties -> Add -> PCIRoot... -> device-id
DeviceProperties -> Add -> PCIRoot... -> ATY,DeviceID
DeviceProperties -> Add -> PCIRoot... -> @0,compatible
DeviceProperties -> Add -> PCIRoot... -> vendor-id
DeviceProperties -> Add -> PCIRoot... -> ATY,VendorID
- BootDisplay:
DeviceProperties -> Add -> PCIRoot... -> @0,AAPL,boot-display
Intel 核显依然推荐使用 WhateverGreen 和缓冲帧补丁驱动。
一般的,在注入仿造显卡或仿造 VBIOS 的时候,更推荐使用 SSDT 搭配 WhateverGreen 的方式(成功率较高)。至于 EDID 注入,WhateverGreen 的文档中有 详细介绍。
内核扩展驱动(Kext)相关
- KernelPm 和 AppleIntelCPUPM:对应 OpenCore 中
Kernel -> Quirks -> AppleXcpmCfgLock -> YES
和Kernel -> Quirks -> AppleCpuPmCfgLock -> YES
。 - DellSMBIOSPatch :在 OpenCore 中对应了两个 Quirk:
Kernel -> Quirks -> CustomSMBIOSGuid -> YES
PlatformInfo -> UpdateSMBIOSMode -> Custom
- Kernel LAPIC 和 KernelXCPM:分别对应 OpenCore 中的
Kernel -> Quirks -> LapicKernelPanic -> YES
和Kernel -> Quirks -> AppleXcpmExtraMsrs -> YES
- AppleRTC:
- Comment:Disable RTC checksum update on poweroff
- Enabled:YES
- Count:1
- Base:
__ZN8AppleRTC14updateChecksumEv
- Identifier:
com.apple.driver.AppleRTC
- Limit:0
- Find:
- Replace:c3
- FakeCPUID:OpenCore 提供了专门的 Emulate 功能。
除此以外,一些常用的 Kext Patch 在 OpenCore 中也有对应的 Quirks。
- 解除 USB 15 端口限制,以前根据不同的系统需要打不同的 Kext Patch,现在只需要 OpenCore 一个 Quirk:
Kernel -> Quirks -> XhciPortLimit -> YES
- 内置硬盘变外置硬盘,也只需要一个 Quirk:
kernel -> Quirks -> ExternalDiskIcons -> YES
- 和之前提到的 FixSATA 不同,FixSATA 顾名思义只修复 SATA 硬盘,而 OpenCore 这个 Quirks 会修复所有的硬盘。
- 为不支持的 SATA SSD 提供 TRIM 现在也只需要启用一个 Quirk:
Kernel -> Quirks -> ThirdPartyDrive
- 除非使用
sudo trimforce enable
后,「系统报告」中仍然提示 SATA 控制器下的硬盘没有启用 TRIM,否则不需要打开这个 Quirk。
- 除非使用
IOPCIFamily Patch
对应 OpenCore 中Kernel -> Quirks -> IncreasePciBarSize
。Disable board-ID check
可以用 WhateverGreen 代替。AppleHDA Patch
已经包含在 AppleALC 中。IONVMe Patches
在 macOS 10.13 及其之后的版本上已经没有必要了。如果要修复 macOS 10.14 及其之后版本的 NVMe 电源管理,请使用 NVMeFix.kextMSR 0xE2 _xcpm_idle instant reboot (c) Pike R. Alpha
(避免写入 MSR 0xE2)对应的是 OpenCore 中这个 Quirk:Kernel -> Quirks -> AppleXcpmCfgLock
- 除此以外,Pike R. Alpha 提供的下述 Kext Patch 也都已经包含在
Kernel -> Quirk -> AppleXcpmExtraMsrs
中:- _xcpm_bootstrap
- _xcpm_pkg_scope_msrs
- _xcpm_SMT_scope_msrs #1
- _xcpm_SMT_scope_msrs #2
- _xcpm_core_scope_msrs
- _xcpm_performance_patch
- xcpm MSR Patch 1 and 2
- /0x82D390/MSR_PP0_POLICY 0x63a xcpm support patch 1 and 2
SMBIOS 机型信息和系统参数
- Product Name:
PlatformInfo -> Generic -> SystemProductName
- Serial Number:
PlatformInfo --> Generic -> SystemSerialNumber
- Board Serial Number:
PlatformInfo -> Generic -> MLB
- SmUUID:
PlatformInfo -> Generic -> SystemUUID
- Slots AAPL Injection:需要注入到设备属性中
DeviceProperties -> Add -> PCIRoot... -> APPL,slot-name | string | Add slot
- CustomUUID:就连 Clover 都不推荐配置这一项,OpenCore 直接就不提供硬件 UUID 配置功能
- InjectSystemID:兼容变色龙的历史遗留配置,Clover 不推荐配置这一项,OpenCore 也不再提供该项配置
- BacklightLevel:需要注入到 NVRAM 中
NVRAM -> Add -> 7C436110-AB2A-4BBB-A880-FE41995C9F82 -> backlight-level | Data | <Insert value>
- NvidiaWeb:需要注入到 NVRAM 中
NVRAM -> Add -> 7C436110-AB2A-4BBB-A880-FE41995C9F82 -> nvda_drv: <31>
配置好 OpenCore 以后,可以将 OpenCore 复制到 U 盘或者硬盘中。需要注意的是,EFI/BOOT/BOOTx64.efi
需要直接替换。在添加引导项时,OpenCore 必须 从 EFI/BOOT/BOOTx64.efi
启动而不是从 EFI/OC/OpenCore.efi
启动。如果启动项中添加的不是 EFI/BOOT/BOOTx64.efi
,那么有很大的概率你会遇到各种奇怪的、无法引导的问题。
清理 Clover 残余
重启到 OpenCore 引导之前,务必清理掉 Clover 的残留文件:
# 删除 Clover 位于系统偏好设置中的面板
sudo rm -rf "/Library/PreferencePanes/Clover.prefPane"
# 删除 Clover 的自动脚本
rm -rf "/etc/rc.clover.lib"
rm -rf "/etc/rc.boot.d/10.save_and_rotate_boot_log.local"
rm -rf "/etc/rc.boot.d/20.mount_ESP.local"
rm -rf "/etc/rc.boot.d/70.disable_sleep_proxy_client.local.disabled"
rm -rf "/etc/rc.boot.d/80.save_nvram_plist.local"
rm -rf "/etc/rc.shutdown.local"
rm -rf "/etc/rc.boot.d"
rm -rf "/etc/rc.shutdown.d"
# 删除 Clover 的守护进程
launchctl unload '/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist'
rm -rf '/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist'
rm -rf '/Library/Application Support/Clover/CloverDaemonNew'
rm -rf '/Library/Application Support/Clover/CloverLogOut'
rm -rf '/Library/Application Support/Clover/CloverWrapper.sh'
除此以外,在使用 OpenCore 引导 macOS 之前需要重置 NVRAM。如果你之前使用的是模拟 NVRAM,那么还需要删除 EFI 分区中的 nvram.plist
文件。
- 如果在 OpenCore 中启用了
AllowNvramReset
这个 Quirk,那么可以在 OpenCore 引导菜单中,按下空格键显示隐藏条目,最后一个条目就是 OpenCore 内置的重置 NVRAM 功能。 - 也可以在 Clover 中重置 NVRAM:删除模拟 NVRAM 驱动和
nvram.plist
以后,在 Clover 引导菜单中按下 F11 来清除 NVRAM。
当 OpenCore 已经可以正常引导 macOS 后,你就可以将 EFI 分区中删除 EFI/Clover
目录、将 Clover 启动项从 BIOS 中删除了。