参考教程 - 用热补丁修理你的触摸板(TouchPad-Hotpatch)- 神楽小白(GZ小白)
由于上方链接内教程已经十分完备,此处只做一个总结。
在确定设备时,也要确定你的 I2C 控制器的 Device_ID 和 Vendor_ID,以此确定需要选择什么卫星kext。当然你也可以通过多次尝试找到能用的那个。
当你在确定ACPI Pin时,若发现自己的Pin > 1024(十进制)或是Pin < 0x2F(十六进制),则无需套公式计算Pin值了。
Pin < 0x2F:APIC 中断模式
只需要放入 SSDT-XOSI.aml,以及对应的 _OSI to XOSI 重命名补丁
并且将VoodooI2C和对应的卫星kext放入,重启即可驱动。如果发现触控板设置内不显示触控板,制作电池补丁可能可以解决此问题。
Pin > 1024:GPIO 中断模式
同样需要放入 SSDT-XOSI.aml 及对应的 _OSI to XOSI 重命名补丁
此外,还需要对 TPD0
设备的 _STA
方法,以及 GPI0
的 _STA
方法打补丁,使 TPD0
禁用,及 GPI0
设备启用。
如原设备中:
// _SB.PCI0.I2C0.TPD0
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (((SDS0 == 0x05) || ((SDS0 == One) || ((SDS0 == 0x02) || (SDS0 == 0x06)))))
{
Return (0x0F)
}
Return (Zero)
}
通过分析,我们可以知道,当 SDS0
不等于 0x05、0x02、0x06、0x01 时,TPD0
的 _STA 返回零,即被禁用。因此我们可以让 SDS0
等于0.
同理,在 GPI0
设备中:
//SB.PCI0.GPI0
Method (_STA, 0, NotSerialized) // _STA: Status
{
If ((SBRG == Zero))
{
Return (Zero)
}
If ((GPEN == Zero))
{
Return (Zero)
}
Return (0x0F)
}
只需要让 SBRG
和 GPEN
都不等于0,即可启用 GPI0
设备。而 SBRG
变量在整个DSDT中都有调用,无法通过预置变量法置1,否则将影响整个DSDT的功能。因此我们可先让 GPEN
置1,若是依然无法启用 GPI0
,则使用 ACPI 重命名和自编写 SSDT 来修改原 _STA 方法。
综上,我们可以得到如下预置变量补丁:
Scope (\)
{
If (_OSI ("Darwin"))
{
Store (One, GPEN) // 启用 GPI0
Store (Zero, SDS0) // 禁用 TPD0
}
}
若是需要使用 ACPI 重命名和自编写 DSDT 方法,请参照:
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (_OSI ("Darwin"))
{
Return (Zero)
}
Else
{
Return (XSTA())
}
}
在进行 ACPI 重命名的时候,不能单单 patch _STA,否则会影响所有设备的_STA方法。我们使用Hex Fiend来寻找_STA关键字,并且扩展到周围的byte,直到能够确保DSDT中的唯一性。
然后参照原教程将原 TPD0 方法的内容复制到补丁中,并把所有 TPD0 替换为 TPDX。
而根据原文,VoodooI2C 使用 SBFG 来启用 GPIO 中断模式。因此在 _CRS 方法中,我们需要返回 SBFB, SBFG
或是 I2CM, SBFG
(根据你机器原本的原文来确定)
如原文是
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
If ((OSYS < 0x07DC))
{
Return (SBFI)
}
If ((SDM0 == Zero))
{
Return (ConcatenateResTemplate (SBFB, SBFG))
}
Return (ConcatenateResTemplate (SBFB, SBFI))
}
我们修改为
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Return (ConcatenateResTemplate (SBFB, SBFG))
}
而若原文是
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
If ((OSYS < 0x07DC))
{
Return (SBFI) /* \_SB_.PCI0.I2C0.TPD0.SBFI */
}
If ((TPDM == Zero))
{
Return (ConcatenateResTemplate (I2CM (I2CX, BADR, SPED), SBFG))
}
Return (ConcatenateResTemplate (I2CM (I2CX, BADR, SPED), SBFI))
}
我们修改为
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Return (ConcatenateResTemplate (I2CM (I2CX, BADR, SPED), SBFG))
}
其他部分在大佬的博客里讲解很清楚了,此处不再赘述。