从 Clover 到 OpenCore —— Clover 迁移 OpenCore 指南

随着 OpenCore 日渐成熟、acidanthera 团队宣布放弃旗下绝大部分内核驱动(包括 Lilu、VirtualSMC、WhateverGreen、AppleALC 等)对 Clover 的兼容性支持,与其届时被迫更换,不如主动从 Clover 迁移 OpenCore。

当然面对迁移,有的人会选择直接抛弃之前 Clover 的全部成果,直接从零开始配置 OpenCore。但是我相信对于大部分人来说更希望通过简简单单的修补,在现有的 EFI 的基础上迁移到 OpenCore,因此我开始撰写这篇文章。

然而不幸的是从 Clover 切换到 OpenCore 并不是一个简单的任务,因此这种迁移应该是渐进式的,不可能一蹴而就。那什么是「渐进式」呢?意思就是,如果你按照本文的步骤一步一步按顺序进行,那么大部分迁移步骤产生的修改,在 Clover 下一样可用,你不需要一下子就扔掉 Clover。

序言以外应该写在最前面的话

  1. OpenCore 丢掉了不少 Clover 的历史包袱。毫无疑问依然有不少 Clover 设置在 OpenCore 是没有可以直接替代的。因此 Clover 完全照搬到 OpenCore 是肯定行不通的。
  2. 在迁移到 OpenCore 之前,Clover 的大部分设置都要精简:用 SSDT 代替、改为注入设备属性(Device Properties)。这篇教程就是在教你这些。
  3. 如果你一开始在组织 Clover 的 EFI 时就有洁癖的话,你会发现迁移到 OpenCore 出人意料地简单。
  4. 只有完美的 Clover 的 EFI,在按照本文档的步骤精简后能获得完美的 OpenCore 的 EFI。如果你的 EFI 是不完美的,那么迁移到 OpenCore 也一定是不完美的。因此,如果你是为了解决不完美、才想迁移到 OpenCore,那么我建议先在 Clover 下完善。
  5. 独木难成林。这篇教程初次发布以后,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 快捷键」。

根据同样的思路,我们先在 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 函数、也就是现在已经被重命名为 XQ14XQ15 的函数。当然,别忘了在文件头部添加对 XQ14XQ15 的函数的外部引用(函数的外部引用类型为 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 EH01EHC2 to EH02 :六代(Skylake)及以上的机器已经没有 EHC 控制器了,建议用 OpenCore 官方的 SSDT-EHCx_OFF 关闭 EHC 控制器、并把重命名删除。六代以下机器保留该重命名。
  • SAT0 to SATASAT1 to SATA :实质上完全没用。
  • HECI to IMEIHEC1 to IMEIMEI to IMEIIDER to MEIDWhateverGreen 能够处理这个问题。
  • GFX0 to IGPUPEG0 to GFX0PEGP to GFX0SL01 to PEGP:WhateverGreen 能够处理这个问题。除非你没有使用 WhateverGreen,否则没必要保留这些重命名。
  • EC0 to ECH_EC to ECECDV to ECPGEC to EC :虽然 macOS 的 USB 电源管理需要名称为 EC 的控制器,但是你完全可以使用 OC-little 中的「仿冒 EC」补丁。随意重命名 EC 控制器可能会对硬件造成伤害。
  • HDAS to HDEFCAVS to HDEFAZAL to HDEFAppleALC 能够处理这个问题。除非你在用 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 ANS1PXSX to ANS2 :建议用 NVMeFix.kext 修复 NVMe SSD 的电源管理。
  • LPC0 to LPCB :如果你要添加 SMBUS 支持,OC-little 中分别有 SBUS 的 SSDT 注入补丁和 MCHC 设备补丁。

顺便提醒一下,使用 OC-little 的补丁的时候,需要注意设备的原始 DSDT 中的 LPC 总线名称,并且必要时要自己修改 SSDT 以使 LPC 总线名称匹配。

  • PC00 to PCIOFPU to MATHTMR to TIMRGBE1 to ETH0PIC to IPIC :这些重命名实质上也是完全没用的。
  • _OSI to XOSIOSID 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 补丁、目录结构
  • AppleSupportPkg - 包括三个 EFI 驱动,ApfsDriverLoaderVBoxHfsAudioDxe
  • OcBinaryData - 包含两个闭源驱动 HfsPlus.efiExFatDxe.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(不过之后更新时都修复了),比如之前有一个版本,在应对 VoodooPS2ControllerVooooI2C 这种嵌套 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.efiExFatDxeLegacy.efi:除非你的 EFI 分区或者某个系统分区是 ExFAT 分区格式的,否则不需要保留。在四代以前机型上应该用 ExFatDxeLegacy.efi 而不是 ExFatDxe.efi
  • HfsPlus.efiHfsPlusLegacy.efiVBoxHfs.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 参考手册的简体中文翻译。这份翻译由我和一些黑苹果爱好者们共同在维护。

上面两份参考资料适合你在配置时不知道某个选项的 具体作用和副作用 时作为参考,但是新手并不适合直接对照它们配置 config.plist
如果想要快速上手 OpenCore 配置,应该参考下面的教程:

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

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

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)相关

  • KernelPmAppleIntelCPUPM:对应 OpenCore 中 Kernel -> Quirks -> AppleXcpmCfgLock -> YESKernel -> Quirks -> AppleCpuPmCfgLock -> YES
  • DellSMBIOSPatch :在 OpenCore 中对应了两个 Quirk:
    • Kernel -> Quirks -> CustomSMBIOSGuid -> YES
    • PlatformInfo -> UpdateSMBIOSMode -> Custom
  • Kernel LAPICKernelXCPM:分别对应 OpenCore 中的 Kernel -> Quirks -> LapicKernelPanic -> YESKernel -> 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 NamePlatformInfo -> Generic -> SystemProductName
  • Serial NumberPlatformInfo --> Generic -> SystemSerialNumber
  • Board Serial NumberPlatformInfo -> Generic -> MLB
  • SmUUIDPlatformInfo -> 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 中删除了。

本文作者 : Sukka
本文采用 CC BY-NC-SA 4.0 许可协议。转载和引用时请注意遵守协议、注明出处!
本文链接 : https://blog.skk.moe/post/from-clover-to-opencore/

喜欢这篇文章?为什么不考虑打赏一下作者呢?

评论加载中 ...