0%

Asus z370-p_8700k_Vega56 安装苹果系统攻略

Asus z370-p_8700k _Vega56 ,在2017年算是很流行的黑苹果主机配置。Vega56显卡属于iMacpro1,1的选择,而8700k与Asus z370的搭配,又属于iMac机型的配置。所以这套主机配置经常纠结于iMacPro和iMac的选择中。
总体而言,这套配置比较适合iMacPro,这是经过对主板问题的研究以及核显驱动在z370主板上的缺陷得到的认知。

一、基本功课

  1. 主板Bios重点项目设置

Bios项目 设置 备注
VT-d disabled 对FCPX有帮助
Secure boot state disabled
Primary Display Auto
iGPU Multi-Monitor Disable iMac机型设置成enable
CFG Lock Disable 一个超级重要的设置
  • 关于Primary Display 此项为主显示器设置,比较普遍的设置是PCIE。但是在黑果的过程中,可能会出现意外情况会导致屏幕无法点亮,连Bios都看不见的情况。这时候你可能做的只有重置BIOS了,或者连重置都没机会,只能编程器刷BIOS了。所以为了保险还是设置成自动比较好。
  • CFG Lock 就是CFG锁,主板默认设置为Disable,为CFG开启状态,也就是系统可以些入NVRAM信息。设置成enable反而是上锁了。这个项目的设置对于黑苹果特别重要,比如你在引导里换了机型设置,如果CFG Lock上锁了,结果就是死机,严重的就要刷BIOS。
  1. 核显与机型

    使用iMac19,1/19,2机型,需要开启核显,但必须使用WhateverGreen.kext。使用iMacPro机型最好关闭核显,否则你还是需要WhateverGreen.kext驱动。
    这是由于z370主板Bios的缺陷造成的。引起这个缺陷的是Bios里的IntelGuc(核显中负责媒体编解码的固件)。对于Asus Z370主板,最新的Bios停留在2019/07/18的2401版,虽然升级了ME(CPU微码),但是guc的问题依然如故。WhateverGreen.kext驱动实际上等于禁用Guc。我在WhateverGreen-1.3.8.kext上强制开启guc功能,结果还是IGPU通不过。
    从返回的错误报告看,主要是AppleIntelKBLGraphics.kext驱动发生了错误。
    1
    2
    3
    4
    Kernel Extensions in backtrace:
    com.apple.driver.AppleIntelKBLGraphics(14.0.4)[820679F0-1A2F-3F76-AEBD-24E3393CDFCD]@0xffffff7f96868000->0xffffff7f9695afff
    dependency: com.apple.iokit.IOPCIFamily(2.9)[ADD485B5-3EF8-37C4-B3C5-F86326E497A4]@0xffffff7f91514000
    ...
    所以,如果用iMac机型,需要使用WhateverGreen.kext驱动,结果就是核显大多数情况不会满载,GFX的频率会处于一个较低的水平,比如不超过0.35GHz。这样一来,开启核显形同鸡肋。
    对于使用Vega这样可以双解的显卡,直接选择iMacPro机型,免得麻烦。
  2. 补充

    使用最新的WhateverGreen1.3.8版,情况得到改善,特别是FCPX上编码导出HEVC有绝对的用处。参见:http://zuoyoulz.top/2020/4-9/ 第四部分。

二、调教ACPI

完善黑苹果的主要部分应该是调教ACPI,涉及ACPI补丁,包括电源管理、RTC、显卡位置等一系列问题。

  1. XCPM

    Asus z370主板需要对CPU部分的PR00打SSDT补丁,以加载原生电源管理,以下为宪武制作的SSDT-XCPM补丁。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    DefinitionBlock ("", "SSDT", 2, "CpuRef", "CpuPlug", 0x00003000)
    {
    External (_PR_.PR00, ProcessorObj)

    Scope (_PR.PR00)
    {
    Method (DTGP, 5, NotSerialized)
    {
    If ((Arg0 == ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
    {
    If ((Arg1 == One))
    {
    If ((Arg2 == Zero))
    {
    Arg4 = Buffer (One)
    {
    0x03
    }
    Return (One)
    }

    If ((Arg2 == One))
    {
    Return (One)
    }
    }
    }

    Arg4 = Buffer (One)
    {
    0x00
    }
    Return (Zero)
    }

    Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
    {
    Local0 = Package (0x02)
    {
    "plugin-type",
    One
    }
    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
    Return (Local0)
    }
    }
    }

    将此编译为asl文件后,放入OC引导的APCI中,并同时在oc的配置文件里写入此ssdt。

  2. EC控制器

    ASUS z370-p 主板的EC控制器名为H_EC

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Device (H_EC)
    {
    Name (_HID, EisaId ("PNP0C09") /* Embedded Controller Device */) // _HID: Hardware ID
    Name (_UID, One) // _UID: Unique ID
    Method (_STA, 0, NotSerialized) // _STA: Status
    {
    ^^^GFX0.CLID = 0x03
    Return (Zero)
    }
    ...
    Return (Zero)
    }

    由于直接返回的Zero,所以这个EC控制器是没有启用的,我们也就不必管它了。

  3. PMCR

    PMCR是苹果的部件,在300系主板中是不存在的。OpenCore引导中直接推荐使用SSDT-PMC补丁。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    DefinitionBlock ("", "SSDT", 2, "ACDT", "PMCR", 0x00001000)
    {
    External (_SB_.PCI0.LPCB, DeviceObj)

    Scope (_SB.PCI0.LPCB)
    {
    Device (PMCR)
    {
    Name (_HID, EisaId ("APP9876")) // _HID: Hardware ID
    Method (_STA, 0, NotSerialized) // _STA: Status
    {
    If (_OSI ("Darwin"))
    {
    Return (0x0B)
    }
    Else
    {
    Return (Zero)
    }
    }

    Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
    {
    Memory32Fixed (ReadWrite,
    0xFE000000, // Address Base
    0x00010000, // Address Length
    )
    })
    }
    }
    }
  4. RTC

    Asus Z370的RTC驱动中没有_STA方法,所以我将其禁用,并仿冒了一个白苹果上的ARTC

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    DefinitionBlock ("", "SSDT", 2, "ACDT", "RTC0", 0x00000000)
    {
    External (_SB_.PCI0.LPCB, DeviceObj)
    External (_SB_.PCI0.LPCB.RTC_, DeviceObj)
    External (RTC_, DeviceObj)

    Scope (_SB.PCI0.LPCB)
    {
    Scope (RTC)
    {
    Method (_STA, 0, NotSerialized) // _STA: Status
    {
    If (_OSI ("Darwin"))
    {
    Return (Zero) //禁用RTC
    }
    Else
    {
    Return (0x0F)
    }
    }
    }

    Device (ARTC) //仿冒ARTC
    {
    Name (_HID, EisaId ("PNP0B00") /* AT Real-Time Clock */) // _HID: Hardware ID
    Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
    {
    IO (Decode16,
    0x0070, // Range Minimum
    0x0070, // Range Maximum
    0x01, // Alignment
    0x08, // Length
    )
    IRQNoFlags ()
    {8}
    })
    Method (_STA, 0, NotSerialized) // _STA: Status
    {
    If (_OSI ("Darwin"))
    {
    Return (0x0F)
    }
    Else
    {
    Return (Zero)
    }
    }
    }
    }
    }
  5. GRPW

    ASUS z370-p 在GLAN、XHC、XDCI、HDAS设备上,电源唤醒存在问题:

    1
    2
    3
    4
    Method (_PRW, 0, NotSerialized)  // _PRW: Power Resources for Wake
    {
    Return (GPRW (0x6D, 0x04))
    }

    这就需要使用0D/6D补丁,我的做法是强制用二进制补丁改成

    1
    Return (GPRW (0x6D, 0x00))

    因为我没有Windows系统。如果和Windows共存,请使用宪武的 https://github.com/daliansky/OC-little/tree/master/12-060D补丁/12-1-普通的060D补丁

  6. BUS0

    Asus Z370-p系统管理总线名称为BUS0,总线地址为“0x001F0004”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Device (SBUS)
    {
    Name (_ADR, 0x001F0004) // _ADR: Address
    Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
    {
    If (PCIC (Arg0))
    {
    Return (PCID (Arg0, Arg1, Arg2, Arg3))
    }

    Return (Buffer (One)
    {
    0x00
    })
    }
    }

    我们通过SSDT-SBUS为其注入一些苹果系统需要的内容。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    DefinitionBlock ("", "SSDT", 2, "ACDT", "SBUS", 0x00000000)
    {
    External (_SB_.PCI0.SBUS, DeviceObj)

    Scope (_SB.PCI0.SBUS)
    {
    Device (BUS0)
    {
    Name (_CID, "smbus") // _CID: Compatible ID
    Name (_ADR, Zero) // _ADR: Address
    Device (DVL0)
    {
    Name (_ADR, 0x57) // _ADR: Address
    Name (_CID, "diagsvault") // _CID: Compatible ID
    Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
    {
    If (!Arg2)
    {
    Return (Buffer (One)
    {
    0x03
    })
    }

    Return (Package (0x02)
    {
    "address",
    0x57
    })
    }
    }

    Method (_STA, 0, NotSerialized) // _STA: Status
    {
    If (_OSI ("Darwin"))
    {
    Return (0x0F)
    }
    Else
    {
    Return (Zero)
    }
    }
    }
    }
    }
  7. PEG0

    主板ACPI中,第一个PCIE插槽没有太多驱动设置,只给出了PCI0-PEG0-PEGP这样的一个路径。实际的显卡路径要多2层,所以显卡需要得到正确的硬件位置,才能正确驱动。方法有两种,一种是SSDT注入,一种是在OpenCore引导的设备属性项目中注入。后一种方法移到下一段中说明。还有一种是以上两种方法联合使用。正确驱动的路径是 _SB.PCI0.PEG0.PEGP. EGP1.GFX0,重点是最后的位置名称为GFX0,在不对ACPI做重命名的情况下,需要再注入两层设备。
    我们先看看原始ACPI中的PEGP部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Device (PEG0)
    {
    Name (_ADR, 0x00010000) // _ADR: Address
    Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
    {
    If (PICM)
    {
    Return (AR01) /* \_SB_.AR01 */
    }

    Return (PR01) /* \_SB_.PR01 */
    }

    Device (PEGP)
    {
    Name (_ADR, Zero) // _ADR: Address
    }
    }

    由于PEGP驱动直接返回了Zero,省去了屏蔽PEG0设备的麻烦,直接将_SB.PCI0.PEG0.PEGP 在SSDT声明中包含进来。

    1
    2
    3
    4
    5
    Scope (_SB.PCI0.PEG0.PEGP)
    {
    Device (EGP1)
    {
    Device (GFX0)

    EGP1和GFX0是自定义的,EGP1的名字只要不冲突就可以了,GFX0则是苹果独显的规范,以便加载AGPM。另外,由于显卡初始化的问题,需要对在此SSDT中使用Mieze大神的方法做寄存器变换,解决BAR初始化错误。以下是不带设备属性的显卡SSDT。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    DefinitionBlock ("", "SSDT", 2, "ACDT", "GRAPHICS", 0x00001000)
    {
    External (_SB_.PCI0, DeviceObj)
    External (_SB_.PCI0.GFX0, DeviceObj)
    External (_SB_.PCI0.LPCB, DeviceObj)
    External (_SB_.PCI0.PEG0, DeviceObj)
    External (_SB_.PCI0.PEG0.PEGP, DeviceObj)
    External (_SB_.PEPD, DeviceObj)
    External (BLCP, FieldUnitObj)
    External (BLCT, IntObj)
    External (BRTL, FieldUnitObj)
    External (CPSC, UnknownObj)
    External (DLHR, FieldUnitObj)
    External (DSEN, UnknownObj)
    External (ECON, IntObj)
    External (EGPS, FieldUnitObj)
    External (MUTX, MutexObj)
    External (OSYS, FieldUnitObj)
    External (PEPD, UnknownObj)
    External (RTC_, DeviceObj)
    External (S0ID, FieldUnitObj)
    External (SSMP, FieldUnitObj)
    External (SSMY, FieldUnitObj)
    External (STAS, IntObj)


    Scope (_SB.PCI0.PEG0.PEGP)
    {
    Device (EGP1)
    {
    Name (_ADR, Zero)
    Method (_STA, 0, NotSerialized)
    {
    If (_OSI ("Darwin"))
    {
    Return (0x0F)
    }
    Else
    {
    Return (Zero)
    }
    }

    Device (GFX0)
    {
    Name (_ADR, Zero)
    OperationRegion (PCIB, PCI_Config, Zero, 0x0100)
    Field (PCIB, AnyAcc, NoLock, Preserve) //定义寄存器变量
    {
    Offset (0x10),
    BAR0, 32,
    BAR1, 32,
    BAR2, 64,
    BAR4, 32,
    BAR5, 32
    }

    Method (_INI, 0, NotSerialized) //寄存器变换
    {
    If ((BAR5 == Zero))
    {
    Local0 = BAR2 /* \_SB_.PCI0.PEG0.PEGP.EGP1.GFX0.BAR2 */
    }
    Else
    {
    Local0 = BAR5 /* \_SB_.PCI0.PEG0.PEGP.EGP1.GFX0.BAR5 */
    }

    OperationRegion (GREG, SystemMemory, (Local0 & 0xFFFFFFFFFFFFFFF0), 0x8000)
    Field (GREG, AnyAcc, NoLock, Preserve)
    {
    Offset (0x6800),
    GENA, 32,
    GCTL, 32,
    LTBC, 32,
    Offset (0x6810),
    PSBL, 32,
    SSBL, 32,
    PTCH, 32,
    PSBH, 32,
    SSBH, 32,
    Offset (0x6848),
    FCTL, 32,
    Offset (0x6EF8),
    MUMD, 32
    }

    FCTL = Zero
    PSBH = Zero
    SSBH = Zero
    LTBC = Zero
    GENA = One
    MUMD = Zero
    }

    Method (_DSM, 4, NotSerialized)
    {
    If ((Arg2 == Zero))
    {
    Return (Buffer (One)
    {
    0x03
    })
    }

    Return (Package (0x02)
    { //设备属性注入位置
    "hda-gfx",
    Buffer (0x0A)
    {
    "onboard-1"
    }
    })
    }
    }

    Device (HDAU) //音频传输驱动
    {
    Name (_ADR, One)
    OperationRegion (HDAH, PCI_Config, Zero, 0x40)
    Field (HDAH, ByteAcc, NoLock, Preserve)
    {
    VID0, 16,
    DID0, 16
    }

    Method (_DSM, 4, NotSerialized)
    {
    If ((Arg2 == Zero))
    {
    Return (Buffer (One)
    {
    0x03
    })
    }

    Return (Package (0x02)
    {
    "hda-gfx",
    Buffer (0x0A)
    {
    "onboard-1"
    }
    })
    }
    }
    }
    }
    }
  8. HDAS

    Z370主板的声卡设备ACPI名称为HDAS,设备位置为“0x001f0003”,新版AppleALC驱动会自动将HDAS重命名为HDEF。所以只要注入合适的id,就可以了。

  9. XHC

    Z370主板USB设备地址为“0x00140000”,包含14个USB2.0和10个USB3.0。ACPI默认驱动名称为XHC。关于USB端口定制下面会单独讲述。
    主板ACPI部分到此结束。


三、设备属性注入

  1. 声卡

    Asus z370-p主板声卡型号为ALC887,只需使用AppleALC.kext驱动并为其注入layou-id即可。layou-id可选数值好像不止一个,台式机选5或7都可以。
    以OpenCore为例:
    在DeviceProperties的Add项目下添加PciRoot(0x0)/Pci(0x1f,0x03)项,然后添加子项layout-id7即可。

  2. 核心显卡

    Intel i7-8700k核显的id为0x3e92。对于iMacPro机型来说,在Bios中关闭它是稳妥的做法。
    一般来讲,使用iMac机型,需要设置核显为无显示连,作为辅助加速用。由于z370主板使用核显需要Whatevergreen.kext驱动,所以不需要对其做额外设置。


四、USB设备定制

我们前面讨论了z370-p主板的XHC情况,默认情况下苹果系统是不找XHC的,因为苹果定义的是XHC1。如果我们把主板的XHC重命名为XHC1的话,系统会开启相应的某几个端口。但是我们不建议对ACPI做重命名,所以要想开启这些USB端口,就需要自己注入。以前流行的是SSDT方式,不过OpenCore上推荐使用UsbPorts做空壳驱动注入USB信息。
我们来看看这块主板的USB接口情况,USB定制是个细活,需要对所有位置的接口号了如指掌。

  • Asus Z370-p背板usb接口图:

    Z370背板usb接口图 我们看到最上段的HS09/HS10是USB2.0接口。下面的四个是2.0与30.复用的。通过排查,得到如上的对应关系。
  • Asus Z370-p主板扩展USB2.0插槽:

    z370扩展主板USB2.0插槽
  • Asus Z370-p主板扩展USB3.0插槽:

    z370扩展主板USB3.0插槽 扩展插槽的使用端口定制,需要看你前面板是怎么连接主板扩展插槽的。 有了上面的数据,我们可以直接用Hcakintool工具生成一个USBPorts.kext文件,然后手动编辑里面的info.plist就可以了。注意:info.plist文件的配置是有机型设置的。Hcakintool会按照你当前机器的机型输出配置,如果我们想做一个几种机型都能用的,也很简单,加入其他机型的设置就可以。 手工编辑需要PlistEdit Pro这个软件,Xcode会不显示port的值。 UsbPort的info模版 name不重要,重要的是port的值。形如 1x000000 的,这种第一位为1的是USB3.0接口,第一位是0的为2.0接口。第二位为端口号,从1到F。因为苹果系统的限制,你所能使用的端口不超过15个,我不建议用 UsbinjetcALL这个驱动把所有端口都开启。

五、内核扩展驱动

常规动作就是需要在OpenCore的Kexts里放入:Lilu.kext VirtualSMC.kext AppkeALC.kext RealtekRTL8111.kext AppkeALC.kext USBPorts.kext USBPower.kext
如果需要使用核显还要加入WhateverGreen.kext
然后在OC的config.plist里写入相应配置。


六、显卡属性注入

  • 特别说明,显卡属性里使用@加数字,作为显示连接器接口的索引,第一个接口为@0,第二个为@1,以此类推。
属性 样例 说明
AAPL,slot-name Slot-1 PCI 插槽名称,不建议使用
device-id 0x6768 仿冒显卡id,不仿冒不需要
model Radeon Pro Vega56 与仿冒id联合使用,不仿冒不需要
hda-gfx onboard-1 显卡音频传输设置,但要注意onboard后的索引不可冲突
CFG,CFG_FB_LIMIT aty_config属性之一,AMD10000为0,AMD9500为6,一般不用设置
ATY,bin_image 显卡VBios数据,64k,为无法载入Vbios的笔记本使用
@0,display-dual-link 索引为0的显示连接器双链路带宽设置
@0,name ATY,japura 注入帧缓存名称
connectors 连接器数据,制定FBName会失效

另外,我们可以注入AMD显卡驱动配置项,如aty_configaty_properties中的项目设置,具体可以查看相应驱动包中的info.plist配置

这些属性可以通过SSDT注入,也可以通过OpenCore或Clover中的DeviceProperties项目注入。
下图是仿照白苹果的参数注入的属性。
显卡属性注入
目前苹果系统的AMD显卡驱动不是很稳定,黑起来很玄学。


七、Vega56显卡输出接口修正

由于品牌与型号的差异,我们使用的显卡多不是苹果定制的类型,这就会出现与苹果显卡的显示接口不一致的问题。虽然WhateverGreen.kext能很好地适配显示接口,但它不负责指定FBName(FrameBufferName)。FBName的作用我理解是能更好地发挥显卡的效能,毕竟一个驱动要适配几种型号的显卡及不同机型,这区别就在FBName上,实际应用也验证了我的猜测。这不是WEG驱动的错,WEG不负责这个,一般情况下WEG还是不可替代的,它会省去我们很多麻烦。

FBName同时定义了显卡的显示接口及顺序,一旦在OC或Clover中指定了显卡的FBName,就有很大的概率出现某个或某几个显示接口不能使用或不正常的问题,不论你是否使用了WEG驱动。

(在翻阅10.13.6/10.14.5/10.15.2的AMD10000Controller时,发现里面的FBName在逐渐增多,由原来的Vega10/vega12增加到了Vega20/24等等,原来Vega56/64被定义为Radeon Pro,后来变成了Radeon RX,而Vega64FE/w9100才是Radeon Pro,这也就是为什么丢功能集问题的由来。)
猜测FBName是分显卡型号的,有某种对应关系,但是具体我们不是很清楚,只能一个一个地试。

修正显卡输出接口,确切地说是修正连接器数据,即connectors。connectors具体数据被指定到相应的FBName中。如果我们在驱动是不指定FBName,我们可以直接注入connectors属性的方法来修正连机器端口。一旦在显卡设备属性中指定FBName,我们自己注入的Connectors数据就失去了作用。因为直接调用了FBName中定义的connectors数据。所以,可靠的办法是使用内核补丁的方式,直接操作FBName中的connectors

比如蓝宝石Vega56超白金OC板的显示接口为DP/DP/HDMI/HDMI,这个在AMD10000驱动的定义中是没有的。
通过筛选,AMD10000的驱动中只两个比较接近并可以使用的FBName。
Kamarang (4) DP, DP, DP, HDMI
Iriri (4) DP, DP, DP, HDMI
显示接口

这是指定FBName后的结果,我们看到@2接口被Kamarang定义成了DP(就是右边显示的connector-type 0x400),这与实际的接口HDMI是不一致的。@2这个端口就不能用了。

在强迫症的驱使下,我决定对@2接口进行修正。首先我们通过ATI_FrameBuffers_Edition.php这个php脚本得到接口的缓冲帧数据,我提取了两组FBName中的connectors,
Kamarang (4) DP, DP, DP, HDMI
000400000403000000010101000000002205020200000000
000400000403000000010201000000001204010100000000
000400000403000000010300000000001000050500000000
000800000402000000010400000000002001060600000000
还有Iriri (4) DP, DP, DP, HDMI 与Kamarang一模一样

据此我猜测,要让FrameBuffers数据变成DP,DP,HDMI,HDMI,大致是这个样。
Kamarang (4) DP, DP, HDMI, HDMI
000400000403000000010101000000002205020200000000
000400000403000000010201000000001204010100000000
000800000402000000010300000000001000050500000000
000800000402000000010400000000002001060600000000

按颜色分组说明以下各部分的意思。

00080000 04020000 0001 0300 0000000 20 01 06 06 00000000
接口类型 控制标志 显示特征 占位符 发射器 解码器 热插拔ID 检测ID

如果想深入了解FrameBuffer的数据结构,请拜读 @ljg-pcbeta 的教程 深入探索AMD显卡Framebuffer结构
热插拔ID和检测ID是显卡硬件物理属性,如果你修改了接口类型、控制标志、占位符等还没有让接口点亮,那就要调整热插拔ID和检测ID,这两个ID需要自行核实。对于比较早的AMD显卡可以用工具提取出这两个id,但是新的AMD显卡,还不能得到满意的结果。

整理一下,需要查找的数据是

1
000400000403000000010300000000001000050500000000000800000402000000010400000000002001060600000000

替换成

1
000800000402000000010300000000001000050500000000000800000402000000010400000000002001060600000000

现在把得到的数据做成补丁,写到kernel的patch里。
显示接口修正补丁
注意Xcode的书写格式。

特别强调,本节非必须。

另外参见 http://zuoyoulz.top/2020/4-9/ ,一种解决AMD显卡问题的全新思路。


八、独显黑屏

对于Vega显卡黑屏问题,确切地说是DP显示接口黑屏,可用的HDMI接口是不黑屏的。
我们在升级系统的时候,有几种应对方式:

  • 使用WhateverGreen驱动;
  • 使用HDMI显示器,不过HDMI显示器的刷新率是个问题;
  • 如果使用DP显示器,不用WhateverGreen的情况下,需要打黑屏补丁。但是还是要先借助HDMI显示器或者WhateverGreen驱动,正常进入系统后重建系统缓存,然后就可以去掉WhateverGreen驱动了。DP显示器黑屏补丁 这个补丁的原理就是把AppleGraphicsDevicePolicy.kext驱动中的字符串"board-id"强行替换为"board-ix",以使AppleGraphicsDevicePolicy.kext驱动对机型设置检测失效。

参考
blog.xjn819.com
宪武 OC-little
WhateverGreen_Sample.dsl