前言
这篇博客文章,是我在远景发布的教程:【他山之石,可以攻玉】黑苹果 I2C 触摸板驱动教程(分步)和【积谷于此,以至四方】黑苹果 I2C 触摸驱动教程(第二版)的姊妹篇。本博客整合了两版帖子(权且定为第三版吧,嘻嘻~)。如远景所言,这篇教程来自 Alexandred 的 VoodooI2C 驱动教程官网,本文基本忠实原文,并尽可能结合我的经验来谈如何修改 DSDT 驱动自己的 I2C 触摸板。
在这篇教程即将开始之前,也欢迎各位加入我的黑苹果触摸板驱动 QQ 群 1:837538729 QQ 群 2:921143329,来询问相关问题。我会尽可能为大家解决问题。
准备工作
参数收集
“工欲善其事,必先利其器”。对于 I2C 触摸板来说,首先要做的是明确你的触摸板是不是 I2C 触摸板。 明确了这一点,我们才能有的放矢,根据自己触摸板类型去有针对性地驱动自己的触摸板。
确认自己的设备是不是 I2C 设备其实很简单,在 win 下打开设备管理器,找到人体学输入设备,如果是 I2C 设备,那么现在你应该能看到一个 I2C HID(I2C USB) 设备:
如果你能看到这个设备,说明你的触摸板是 I2C触摸板。否则,你的触摸板就是 PS2 类型的,请安装 VoodooPS2Controller 或者 AppleSmartTouchpad。(下载地址请参见博客的资源页面)
另外需要注意:你需要确认自己的 CPU 平台以及架构代号。一般来说,根据后面 4 位数字型号的第一位,可以推测你的 Intel CPU 为几代 CPU,以及对应的架构。目前支持的架构有这些:
4 - Haswell
5 - Broadwell
6 - Skylake
7 - Kaby Lake
8 - Kaby Lake R / Coffee Lake / Cannon Lake / Whiskey Lake……
如果你的 CPU 低于 4 代,VoodooI2C 是不能在其上工作的。
对于 VoodooI2C 来说,它能识别下面硬件 ID 的 I2C 设备:
‘INT33C2’ 和 ‘INT33C3’ - Haswell
‘INT3432’ 和 ‘INT3433’ - Broadwell
‘pci8086,9d60’, ‘pci8086,9d61’, ‘pci8086,9d62’, ‘pci8086,9d63’, ‘pci8086,a160’ 和 ‘pci8086,a161’ - Skylake / Kaby Lake / Kaby Lake R
‘pci8086,9de8’, ‘pci8086,9de9’, ‘pci8086,a368’ 和 ‘pci8086,a369’ - Coffee Lake / Cannon Lake / Whiskey Lake
如果你确认了你的触摸板/触摸屏是 I2C 设备并且在支持列表里,那么接下来你就可以继续进行你的准备工作。需要说明的是,对于 I2C USB 设备来说,接下来的步骤都没有必要,请直接移步安装步骤!!!
另外,要特别说明的是,一小部分的I2C控制器可能需要添加控制器id才可以使用,比如如下的控制器id:(具体的id请自行去win的设备属性里查找,此处不再赘述)
寻找对应的ACPI模块
在 DSDT 里,I2C 触摸设备会对应其 BIOS 设备名称下面,但是在一个完整的 DSDT 里,I2C 设备肯定不止一个,所以我们必须通过找出触摸板的 BIOS 设备名称来定位触摸板的 DSDT 代码片段。方法如下:
1、打开设备管理器,找到 I2C HID 设备,双击打开属性
2、进入详细信息,点击下拉菜单,找到 “ BIOS 设备名称” 一项,并将它记录下来
(有几个记录几个)
这样,我们就完成了寻找对应的 ACPI 模块的操作。一般来说,I2C 触摸设备名字是这些中的一个(但并不绝对):
触摸板:
1 | TPDX, ELAN, SYNA, CYPR, TPAD, ETPD |
触摸屏:
1 | TPLX, ELAN, ETPD, SYNA, ATML |
注意:这里的 X 代表某一个数字
安装工具
修改 DSDT 我们需要用到两款工具软件: IORegistryExplorer, Maciasl
这里这两款软件都有特殊的要求。IORegistryExplorer 要求为 2.1 版本,Maciasl要求为 Rehabman 大神的编译版,下载地址可以自行百度搜索。
下载驱动
VoodooI2C 要求必须运行在 Clover(四叶草),除此之外,一个稳定的 Mac 环境也是先决条件,确保在驱动触摸板前你的显卡和电池电量显示已经正常工作,并且你还需要提取好一份完整的DSDT。这个地方我不想过多解释DSDT相关基础知识,有需要了解的请移步这里。
在这些工作完成之后,我们就可以开始下载 VoodooI2C 驱动。 最好的获取方法是进入 Github 获取最新的驱动(下载地址)。在 Releases 下的驱动最稳定。
下载 Releases 的压缩包后,我们解压,会得到 1 个核心驱动和 5 个目标驱动,对 VoodooI2C 来说,它需要两个驱动来完成工作:VoodooI2C.kext(核心驱动)+ 一个目标驱动。
我们一共有四个目标驱动可供选择,它们的区别见下表:
驱动名称 | 功能 | 轮询模式 | 中断模式 | 是否需要调整 IONameMatch |
---|---|---|---|---|
VoodooI2CELAN | 支持 ELAN 触摸板 | ❌ | ✔️ | ✔️ |
VoodooI2CHID | 支持大多数 I2C HID 多点触摸设备 | ✔️ | ✔️ | ❌ |
VoodooI2CUPDDEngine | UPDD 多点触控引擎 | ❌ | ✔️ | ✔️ |
VoodooI2CFTE | 支持 FTE 触摸板 | ❌ | ✔️ | ✔️ |
准备修改
预备知识
我们修改DSDT的目的,其核心在于让驱动识别触摸板的 GPIO 控制器,从而让驱动识别触摸板。对于极少的笔记本来说(如使用 Haswell 和 Boardwell 的设备),由于 GPIO 控制器本身就已经可以驱动,所以这类设备通常不需要打补丁也可以正常使用 VoodooI2C。
VoodooI2C 支持三种模式: APIC 中断模式,GPIO 中断模式与轮询模式,这三种模式各有特点:APIC 中断基本不需要进行修改,功能完美,但是仅有极少数设备支持,GPIO 中断模式功能支持比较完善,但是修改量通常比较大,而且有可能出现 BUG 或者占用资源过高的问题(当然也更容易五国)(现在按理来说可以通过修补 FMCN & SSCN 来解决);而轮询模式是一种非常低效的模式,功能的支持可能会不太完善,不过轮询模式相比较中断模式而言适用范围更广。
这两种模式究竟使用哪一种,需要结合你的 DSDT 代码和使用的驱动来定。目前能够同时支持这两种模式的驱动只有 VoodooI2CHID。
补丁应用
无论你使用哪一种工作模式,你首先都需要给你的 DSDT 应用 Windows 补丁。这个补丁可以在补丁源下面找到,根据你的出厂 Windows 系统版本来应用补丁就好,一般我们用的比较多的都是 Windows 10 Patch。如果你的Maciasl里并没有显示VoodooI2C-Patches补丁源,则接下来你将需要添加补丁源。添加步骤如下:
1.打开Maciasl的设置选项:
2.点击source选项并输入图中地址:(由于gayhub国内连接速度极慢,请自行寻找方法提速)
3.完成后回到主界面,点击patch按钮,应该显示如下的界面:
如果出现了VoodooI2C-Patches的补丁源,则添加补丁源成功。
如果你运行在 Skylake 的 CPU 下,通常你需要应用补丁源下的 SKL I2C Controller 补丁。这个补丁对于 Skylake 不一定会起作用,但是通常打上这个补丁也不会出什么问题,所以最好是应用这个补丁。
如果你是 Skylake 平台或以上,那么如果想使用 GPIO 中断模式,你就必须对 GPIO 打补丁。应用补丁源下 GPIO Controller 补丁(中断模式)。
下面,就针对这轮询和中断这两种方式进行 DSDT 修改讲解。
DSDT 修改
中断模式
接下来我们先介绍 GPIO 中断模式。这里的情况比较复杂,在做这项工作之前,请务必备份好自己的原有 DSDT,然后进行修改。注意:接下来的 DSDT 修改全都在你的触摸设备代码下进行,不要去修改其他地方!!!
确认你的中断控制器类型
这一步需要确认你的中断控制器究竟是何种类型,在没有安装 VoodooI2C 驱动时,打开 IORegistryExplorer,搜索前面保存的 BIOS 设备名称,然后定位到 IOinterruptSpecifiers一项
可以看到,窗口出现了一组十六进制数值。其中,最前面的两位数称为APIC pin值,这个值是你后面 DSDT 修改的重要依据,把它记录下来。
如果你没有 IOinterruptSpecifiers 这一项或者 APIC pin 值不大于 2F(十六进制如何比较大小请自行百度),那么请移步到安装步骤。(此处有概率有例外)
移除 APIC 中断控制器 相关代码
VoodooI2C在以 GPIO 中断模式调用DSDT中触摸设备的_CRS方法时,一律使用 SBFG 参数而不是 SBFI 参数。因此到这里,我们需要对 CRS 方法进行修改,使其正确返回 SBFG 的值。
用 MaciASL 打开你的 DSDT,然后搜索 SBFG (或者你的设备名),定位并仔细翻阅,你应该会找到一段类似于这样的代码:
1 | Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings |
找到之后,首先要将 SBFI 更名为 SBFB,并删除下段代码:
1 | Interrupt (ResourceConsumer, Level, ActiveLow, |
比如以我的为例子:
1 | Name (SBFB, ResourceTemplate () |
根据上面要求,就应该修改为:
1 | Name (SBFB, ResourceTemplate () |
SBFG (Gpioint) 修改
首先尝试在你触摸设备所对应的 DSDT 代码里搜索类似如下的这段代码:
1 | Name (SBFG, ResourceTemplate () |
比如我的是这样:
1 | Name (SBFG, ResourceTemplate () |
如果并没有这段代码,那么你需要在触摸设备的根目录下补上这段代码,像这样:
1 | Scope (_SB.PCI0.I2C0) |
如果有这段代码但蓝色字样的数值为 0,那么你就需要看看自己 _CRS 方法里是不是只有这一行语句:
1 | Return (ConcatenateResTemplate (SBFB, SBFG)) |
如果只有这行代码,那么你就可以转入后续的完善热补丁步骤;否则就需要给其添加 GPIO Pin 数值。
如果你是 SunrisePoint 架构 6 代 至 8 代 Kaby Lake-R 处理器(比如:8250U, 8550U)查找 表一,寻找你之前的 APIC Pin 值,得到一个 IRQ 值;然后再前往 表二 根据 IRQ 找到一个对应的GPIO Pin值(10进制),把它转换为16进制值。如果这个十六进制数介于 5c 到 77 之间,那么这个数就是你需要的 GPIO Pin值。如果这个数不在这俩数之间,那你就会发现:你的 16 进制 APIC pin 值在表一对应了两个或以上的 IRQ 值。这就需要你分别对多个值进行测试,看哪个才是正确的。有的时候,也可能超出区间但是却只有一个值,那么尝试这个值就好。
如果你是 CannonPoint(Lake) 架构 8/9 代标压 Coffee Lake(-R),查找 表一,寻找你之前的 APIC Pin 值,得到一个 IRQ 值;然后再前往 表二 根据 IRQ 找到一个对应的 GPIO Pin 值(10进制),接着转到 GPIO Pin 转换公式,你会看到 “CHIPSET_GPP(数字, 基数, 终止, gpio_基数), /* GPP_X */“ 用之前 IRQ 中 “GPP_” 后面的 英文字母(A, B, C…)找到你对应的转换值,用你的 10 进制 GPIO Pin 值减去“基数”然后加上“gpio_基数”,把最后得到数字转换为 16 进制就是你最后的 GPIO Pin
如果你是 CannonPoint(Lake) 架构 8 代低压刷新 Whiskylake:以 65U 结尾的处理器(比如:8265U, 8565U),查找 表一,寻找你之前的 APIC Pin 值,得到一个 IRQ 值;然后再前往 表二 根据 IRQ 找到一个对应的GPIO Pin值(10进制),接着转到 GPIO Pin 转换公式,你会看到 “CHIPSET_GPP(数字, 基数, 终止, gpio_基数), /* GPP_X */“ 用之前 IRQ 中 “GPP_” 后面的 英文字母(A, B, C…)找到你对应的转换值,用你的 10 进制 GPIO Pin 值减去“基数”然后加上“gpio_基数”,把最后得到数字转换为 16 进制就是你最后的 GPIO Pin
不过在某些极端状况下,你找到的值都不起作用的话。那么此时,你只能去尝试些比较常见的数值了,如0x17、0x1b、0x34和0x55。(仅限 SunrisePoint)
总之,在完成之后,你需要把得到的 16 进制 GPIO pin 数值填入 SBFG 语句块里,像这样:
1 | Name (SBFG, ResourceTemplate () |
CRS 返回值的修改
到这里,去 _CRS 方法下,确保所有返回语句只有这一条存在,像这样:
1 | Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings |
轮询模式
轮询模式所做的修改相对较少,我们只需要保证以下三点即可:
1、确保没有应用GPIO Controller 补丁
2、确保没有做GPIO 的手动修改
3、确保CRS返回值中只不返回 SBFG (Gpioint)
补充说明
在这针对一些问题,楼主进行下补充:
1、不是所有没有 IOinterruptSpecifiers 值或者值小于 2F 的设备都可以直接使用 VoodooI2C。这类设备中,有一部分必须依赖轮询方式。这类触摸板只需按照上面轮询的方法去修改即可。
2、对于八代的支持问题。在八代中,Kaby Lake R是唯一一个完美支持的,而对于 Coffee Lake、Cannon Lake、Whiskey Lake 等,代码移植已经进入尾声,现在诚邀这些设备参与测试,感谢你的配合。
3、GPIO Pin 值问题。在找到 16 进制的 GPIO Pin 值的过程中,有时候可能出现找到的值只有一个却不在区间的情况,此时也要进行试验,如果不满足再试验其他。
热补丁移植
热补丁的修改是基于 DSDT 进行的,所以当这个教程 DSDT 修改部分和安装部分走完后,如果你确认你的 DSDT 可以驱动触摸板,就可以尝试将其提取出来,改造为热补丁。如果你的 DSDT 没有解决问题,也不要想着测试这个方法。
目前六代的 Skylake 的 I2C Controller 热补丁已经制作完成,也可以进行热补丁移植工作了。
添加 GPIO 与 XOSI 热补丁
下载 SSDT-XOSI.aml 与 SSDT-GPIO.aml(如果你使用轮询模式,那么不要下载这个),解压并放在 ACPI/Patched 目录下,然后在四叶草编辑器的 ACPI 选项卡下添加如下两个改名补丁:
1 | change _OSI to XOSI |
如果你是六代Skylake的,那么还需要添加 SKL I2C Controller热补丁(详情见后文下载)
代码复制
接下来,将你修改好的触摸设备的 ACPI 代码复制到SSDT-触摸样本.dsl的 DefinitionBlock 大括号内里,像这样:
复制之后,我们还要修正名称,来确保这个 SSDT 是正确的。修正的地方有三处:
第一处第二处都修正为你的 BIOS 名称,而第三处则还要带上 BIOS 名称的全路径(以我的为例):
补充:经过本人实测,第一处的修不修改其实没有太大影响,不修改也是可以的。
除错
接下来,我们就进入了给热补丁排错的过程。
点击 编译 (Compile),你会发现此时热补丁会报一堆错误。这里面的错误,大多是因为缺少东西所致。你可能需要因此添加很多东西,比如引用Device、Method,还有一些数据等等。
在我提供的样本里,已经提供了两个示例展示如何引用。在这,我还是补几张图说明下引用的过程。比如,以我的报错为例。你可以看到,在其中有一条提示缺少了 TPDD:
所以对应地,我们去 DSDT 搜索,直到最后定位到相应的数值(或者方法、设备以及它们的引用,最后定位只能是这几种):
第一处表示了它的构造区域,第二处则表示这个名称的值。接下来,我们复制这个数据及其对应的构造区域到SSDT中:
再点击 Compile,与 TPDD 相关的报错应该都消失了。
除了这个之外,有时候我们缺失的是设备或者方法,我们只需要从 MaciASL 下方确认它的全路径,然后使用这条语句引用即可:
1 | External (xxxx.xxxx.xxxx, DeviceObj) //如果是方法,就使用Method0bj;如果是区域则使用FieldUnitObj |
注意:这条语句要放在 DefinitionBlock 块内的最前面!
总之,最后你的 SSDT 要同 DSDT 一样没有 ERROR,这才算完成:
热补丁教程中提及的有关热补丁我已经分享出来,点击这里下载。
安装
到这里,我们的修改就完成了,接下来就是安装。将你修改好的 DSDT(热补丁)放入 ACPI/patched,再放入驱动。在这个时候,我们需要注意,系统里 AppleIntelLpssI2C.kext 和 AppleIntelLpssI2CController.kext 这两个驱动有可能会导致 VoodooI2C 驱动不工作,因此,有必要移除这两个驱动。你可以选择直接删除它们然后重建缓存,也可以选择用四叶草 Config进行屏蔽。屏蔽的配置文件详见这里。
如果你使用的是热补丁方式,我们还需要改名 DSDT 里的触摸设备,来保证热补丁工作。
首先利用 Hackintool 的计算器将你的触摸设备 BIOS 名称转换为 16 位 ASCII 码,然后给这个触摸设备改个名字来保证其不加载(比如改 TPAD 为 XPAD),再次生成一串 16 位 ASCII 码,它们共同构成了一个 ACPI 补丁,用四叶草编辑器把它填入:
接下来我们重启,如果配置正确,那么现在你应该可以使用你的触摸板了。如果仍然不能使用,那么你需要重新排查,看看自己的操作是否存在问题。有其是热补丁,要格外注意啰嗦模式里面的 ACPI Error,如果出现这个要及时查看自己的配置文件 ACPI 改名是否正确。
其他
VoodooI2C 使用 CSG 以及白果手势引擎来支持各种多点触控。其中,2.1.1后的版本,换用了白果手势引擎 (Magic Trackpad 2 模拟器)。这类手势可以通过系统设置里面触摸板的相关选项来设置。
下面就是Voodooi2c所支持的所有手势列表:
CSG手势:
1 | ·单击 |
白果手势:
1 | ·双指通知中心 |
另外,2.1.2以上的版本,加入了“鼠标插入时忽略内建触摸板”的功能配置以及“打字防误碰支持”(需要配合新版VoodooPS2Controller)
教程已经大致更新完毕,后续仍会有补充。
教程中少部分内容由 Bat.bat 修补