随着 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 上提供了许多意见,正是在他们的帮助下,这篇教程得以不断完善。
修改 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 快捷键」。https://www.mfpud.com/topics/1070/

根据同样的思路,我们先在 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})

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 的方式了。

新的声卡 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 补丁、目录结构

https://github.com/acidanthera/OpenCorePkg/releases

AppleSupportPkg - 包括三个 EFI 驱动,ApfsDriverLoader、VBoxHfs、AudioDxe

https://github.com/acidanthera/AppleSupportPkg/releases

OcBinaryData - 包含两个闭源驱动 HfsPlus.efi 和 ExFatDxe.efi,以及 OpenCore 官方主题的图标文件。

https://github.com/acidanthera/OcBinaryData

非常推荐安装 OpenCore 官方做的主题,和真 Mac 的 BootPicker 一模一样(除了没有网络图标)。不过那可能是另一篇文章的内容了。

 

决定你使用的配置文件编辑器

ProperTree:一个 Python 编写的 plist 编辑器,专门优化了 OpenCore 和 Clover 配置文件编写。
据说在处理大整数方面存在问题,但我在 GitHub Issue 中并没有看到。如果有人遇到了建议前往 GitHub Issue 提交反馈。

https://github.com/corpnewt/ProperTree

 

Xcode:非常不推荐,Xcode 11 不仅花里胡哨、而且处理 plist data 和大整数方面存在问题。
简单来说,Apple 没有再开放旧版的 Xcode 10 下载、而且 Apple 的 CDN 还有防盗链。因此如果我要写一篇从 Apple 官方下载 Xcode 10 的教程,那么会比你现在看的这篇的「从 Clover 到 OpenCore」要长得多。

如果你和我一样成功下载了 Xcode 10 或者就没有升级到 Xcode 11:我刚才什么都没写,你什么都没看见。

 

OpenCore Configurator:Clover Configurator 开发者的新作品。很适合新手使用。

https://mackie100projects.altervista.org/opencore-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 机型设置部分更加完整以外,没有其它差别。而一般情况下,并不需要完整的 SMBIOS 机型配置。
如果你下载的是 OpenCore 0.5.7 版本,还需要额外将 Reources 目录复制到 EFI/OC 目录之中。这是由于 OpenCore 编译脚本错误导致的,OpenCore 0.5.8 已经修复了这一问题。

解压下载的 AppleSupportPkg,将其中的 Drivers 目录和 Tools 目录中的文件复制到 EFI/OC/Drivers 目录和 EFI/OC/Tools 目录中。

解压下载的 OcBinaryData,将其中 Drivers 目录复制到 EFI/OC/Drivers 目录中。

 

删除不需要的文件

删除 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 界面字体渲染支持的,现代的机器已经不需要了。

删除 Tools 目录中的这些文件:

BootKicker.efi:调用 Mac 内置的引导界面(即 BootPicker),是用于在白苹果上安装 OpenCore 时用的。黑苹果由于无法使用 Mac 的 BootPicker,所以需要删除。
删除上述不需要的文件以后,你的 OpenCore EFI 目录的结构应该是这样的:

EFI
├── BOOT
│   └── BOOTx64.efi
└── OC
    ├── ACPI
    ├── config.plist
    ├── Drivers
    │   ├── ApfsDriverLoader.efi // OpenCore 0.5.8 内置了 ApfsDriverLoader
    │   ├── 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 参考手册的简体中文翻译。这份翻译由我和一些黑苹果爱好者们共同在维护。

https://oc.skk.moe/

 

上面两份参考资料适合你在配置时不知道某个选项的 具体作用和副作用 时作为参考,但是新手并不适合直接对照它们配置 config.plist。

 

Clover 中的部分配置,如 DSDT 重命名,由于之前已经经过精简,因此可以直接将 Find 和 Replace 逐对复制到 OpenCore 的配置文件中。

需要注意的是,Clover 的 DSDT 重命名中提供了 TgtBridge,但是这一实现充满 Bug,连 Clover 官方都不推荐使用。OpenCore 为 DSDT 属性添加了 Count、Limit、Mask 等属性以实现精确重命名。

 

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 补丁。

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.kext

MSR 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 中删除了。

转载自:https://blog.skk.moe/post/from-clover-to-opencore/