进阶篇-利用GUPC以热补丁定制USB端口
版权©️声明 : 本文章神楽小白(GZ小白)的部落阁
前言
虽然之前就有用热补丁定制USB端口的方法,但那个方法需要搭配USBAllinject.kext使用,在受到Github中一个issue的启发后,我们发现,可以利用ACPI中的GUPC实现USB端口的热补丁定制。最后,通过咨询了哞大相关问题,发此贴,提供方法。
Github的issue链接如下:https://github.com/daliansky/OC-little/issues/18
基本原理
我们这边就以那个issue为样例进行说明
机型原始GUPC方法为:
1 | Method (GUPC, 1, Serialized) |
首先,我们先来了解下PkgObj的一些基本知识
在PCKG, Package (0x04)
中,我们不难发现 0x04 对应了下面的四个项,也就是 Zero
、0xFF
、Zero
、Zero
这些,也就是说,Pkg下有几个项,这里的值就对应是多少,比如有三个那么就是 0x03 (PS:这里的值为16进制)
然后,我们再来看Pkg中的项的位置:
1 | ··· |
这样子应该就一目了然了吧,以此类推下去就行,记住一点,初始位并不是 One 而是 Zero
实现定制
这里我们给出一个修改完成的样例:
1 | DefinitionBlock ("", "SSDT", 2, "INTEL", "GUPC", 0x00000000) |
现在我们来一一解释一下,我们要明白在ACPI中,每个端口都有对应的_UPC
方法来返回GUPC
的值来确定端口的状态(开启或者关闭)以及类型,_UPC
方法见下:
1 | Method (_UPC, 0, NotSerialized) |
那这个返回语句中的One是什么意思呢?其实这个One赋值给了GUPC方法中的Arg0,我们看到原来的GUPC方法中,有这个一句:PCKG [Zero] = Arg0
,也就是这个端口在返回GUPC这个方法时。将Arg0赋值为了One,那么PCKG [Zero] = Arg0
中,PCKG后面跟着的Zero又是什么意思呢?这个其实联系我之前讲的Pkg中项的位置就很好理解了,这里对应的就是PCKG中Zero位置的项,那么整句话的意思就是:将PCKG这个Pkg中Zero位置的项覆盖为Arg0的值
而在GUPC方法里的PCKG中,也正是Zero位置的项和One位置的项决定着端口的状态和类型:
1 | ··· |
One位置的值所对应的端口类型:
1 | --------------------------- |
好了,知道了这些我们就可以正式开始着手定制我们的USB端口了。
你们看我给出的完整补丁里,定义了一个USBP,并赋值为了Zero,然后又在GUPC这个方法中添加了语句:USBP += One
,让USBP的值加上1,其实定义这个USBP其实是为了帮我们定位对应的端口,由于GUPC方法是Serialized,所以每次在一个端口调用完GUPC后,它并不会重置,所以我们可以添加一个USBP,每被一个端口调用一次,USBP的值就增加1,那么当第一个端口调用GUPC时,USBP为1,第二个端口再调用时,USBP的值就在1的基础上再加1,也就是2。
那么就可以很好理解了,这样的话,每一个端口都会按顺序对应一个相应的USBP的值。
接下来,我们在添加判断语句来确定每个端口的状态和类型(见上面给出的完整补丁):
1 | ··· |
我们来先来理解一下第一段判断语句的意思,就是:
- 当 USBP = 0x04 或者 Arg0 = Zero 的时候,将PCKG中Zero位置的值覆盖为Zero,也就是禁用第四个端口和返回的Arg0的值为Zero的端口。
我们再来看第二段判断语句的意思:
- 当 USBP = 0x04 或者 USBP = 0x05 或者 USBP = 0x06 的时候,将PCKG中One位置的项的值覆盖为0xFF,也就是把第四、五、六端口的类型定义为内建。
当然,我们可以根据自己的需求去写判断语句,以达到我们想定制的效果,哪些端口开,哪些端口关,并定义这些端口的类型。
最后我们再返回PCKG就OK了,添加好If (_OSI ("Darwin"))
语句来判定在macOS系统下生效,最后我们在Config中补充重命名:
1 | Comment: USB GUPC to XUPC |
结语
好了,这也是这个教程的主要部分了,希望能给大家定制USB以一个新的方法思路!
加入博主的Hackintosh交流群:679838716