为USBInjectAll.kext创建自定义SSDT

概述

在10.11版本中,Apple完全重写了USB驱动程序。新驱动程序似乎在很大程序上使用了ACPI,比以前的驱动程序更大。这给ACPI(DSDT)的正确性带来了更多的压力。如果不正确,存在的端口可能不会被新的驱动程序启用。

事实上,即使是Apple自己的产品也被发现是不正确的,因此Apple公司发明了一种方法用来一个端口注入器来覆盖DSDT。在事件属性被注入来定义可用端口时,这些属性将被使用而不是ACPI。

内置的端口注入器也可以干扰USB接口,因为一个给定型号的Mac的USB拓朴不太可能与你的PC相同。要解决这些问题,可能需要采取一些步骤。

注意本指南适用于英特尔USB3。第三方USB3,例如Asmedia,NEC/Renasas还是有问题的。这些控制器没有解决方案。对于不支持的USB3控制器(例如,不是英特尔生产的,不是睿思科技生产的)可以试试最新的GenericUSBXHCI.kext

工具/解决方案的概述

  • 选择正确的BIOS选项
  • 在DSDT中使用EHCx->EH0x重命名
  • 通过XHC到EHCI上,使用FakePCIID_XHCIMux路由(route)USB2设备
  • 用一个自定义的端口注入器或自定义SSDT为USBInjectAll.kext注入端口
  • 使用USBInjectAll.kext来注入端口
  • 在运行OSX时,给DSDT打补丁来模拟Windows的一个版本

BIOS选项

USB选制器的配置通常依赖于BIOS设置。对于大多数个人电脑,你应该设置XHCI为“auto”或”和”smart auto”。这些设置通常会影响与XHCI控制器初始化、USB2路由、USB3端口启用。

禁用默认的注射器

第一步是确保默认的注入器没有效果。有这两类注入器:

  • 控制器(Controller)注入器:这些匹配Mac型号(SMBIOS)和ACPI中的控制器名称(EHC1/EHC2/XHC1)。
  • 集线器(Hub)端口注入器:这些匹配Mac型号和locationID(基于控制器和端口的地址)。

第一类端口注入器很容易通过DSDT补丁来禁用。对于大多数个人电脑(PCs),XHCI控制器(USB3)被命名为“XHC”,因此它不会与使用“XHC1”的内置注入器匹配。EHC1和EHC2通常被mac电脑和个人电脑(PCs)用来识别这两个EHCI控制器(USB2)。通过将EHC1重命名为EH01和将EHC2重命名为EH02,您可以有效地禁用与您所使用的SMBIOS匹配的内置端口注入器。重命名可以通过你打了补丁的DSDT中的find/replace来完成,或者通过Clover的config.plist/ACPI/DSDT/Patches。
此类方法可以有效地驱动USB端口,但是对于macOS的每次更新,可通需要创建新的端口限制补丁。

因此,使用端口限制补丁不是一个长期的解决方案。对于可靠的USB,您必须为USBInjectAll.kext实现自定义SSDT,以便在XHC上配置端口。自定义SSDT方式使得不依赖于任何端口限制补丁,它不仅允许您避免端口限制补丁,而且禁用未使用的USB端口可以具有一定的省电属性,并且可以避免睡眠,重启或关闭时的错误。

自定义SSDT

自定义SSDT过程包括如下步骤:

  1. 端口准备
  2. 端口发现
  3. 为USBInjectAll.kext创建自定义SSDT
  4. 测试/验证

MaciASL工具,确保MaciASL->Preferences->iASL中选择了ACPI 6.2a

端口准备

为了能够正确的为给定的PC配置正确的自定义SSDT,我们必须首先发现所启用的所有端口。一量我们知道了使用哪些端口,我们就可以关闭未使用的端口。首先,先用第一类注入方法也就是在Clover的config.plist/ACPI/DSDT/Patches中注入补丁的方法,注入EXHCx重命名和端口限制补丁。

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ACPI</key>
<dict>
<key>DSDT</key>
<dict>
<key>Patches</key>
<array>
<dict>
<key>Comment</key>
<string>change EHC1 to EH01</string>
<key>Find</key>
<data>RUhDMQ==</data>
<key>Replace</key>
<data>RUgwMQ==</data>
</dict>
<dict>
<key>Comment</key>
<string>change EHC2 to EH02</string>
<key>Find</key>
<data>RUhDMg==</data>
<key>Replace</key>
<data>RUgwMg==</data>
</dict>
<dict>
<key>Comment</key>
<string>change XHC1 to XHC</string>
<key>Find</key>
<data>WEhDMQ==</data>
<key>Replace</key>
<data>WEhDXw==</data>
</dict>
</array>
</dict>
</dict>
<key>KernelAndKextPatches</key>
<dict>
<key>KextsToPatch</key>
<array>
<dict>
<key>Comment</key>
<string>change 15 port limit to 26 in XHCI kext</string>
<key>MatchOS</key>
<string>10.11.x</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCIPCI</string>
<key>Find</key>
<data>g72M/v//EA==</data>
<key>Replace</key>
<data>g72M/v//Gw==</data>
</dict>
<dict>
<key>Comment</key>
<string>change 15 port limit to 26 in XHCI kext</string>
<key>MatchOS</key>
<string>10.12.x</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCIPCI</string>
<key>Find</key>
<data>g710////EA==</data>
<key>Replace</key>
<data>g710////Gw==</data>
</dict>
<dict>
<key>Comment</key>
<string>change 15 port limit to 26 in XHCI kext</string>
<key>MatchOS</key>
<string>10.13.0,10.13.1,10.13.2,10.13.3</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCIPCI</string>
<key>Find</key>
<data>g32MEA==</data>
<key>Replace</key>
<data>g32MGw==</data>
</dict>
<dict>
<key>Comment</key>
<string>disable port limit in XHCI kext (credit PMHeart)</string>
<key>MatchOS</key>
<string>10.13.4,10.13.5</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCI</string>
<key>Find</key>
<data>g32UDw+DlwQAAA==</data>
<key>Replace</key>
<data>g32UD5CQkJCQkA==</data>
</dict>
<dict>
<key>Comment</key>
<string>change 15 port limit to 26 in XHCI kext (credit FredWst)</string>
<key>MatchOS</key>
<string>10.13.4,10.13.5</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCI</string>
<key>Find</key>
<data>g32UDw+DlwQ=</data>
<key>Replace</key>
<data>g32UGg+DlwQ=</data>
</dict>
<dict>
<key>Comment</key>
<string>disable port limit in XHCI kext (credit RehabMan, based prior PMHeart patch)</string>
<key>MatchOS</key>
<string>10.13.6</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCI</string>
<key>Find</key>
<data>g32IDw+DpwQAAA==</data>
<key>Replace</key>
<data>g32ID5CQkJCQkA==</data>
</dict>
<dict>
<key>Comment</key>
<string>disable port limit in XHCI kext (credit PMHeart)</string>
<key>MatchOS</key>
<string>10.14.x</string>
<key>Name</key>
<string>com.apple.driver.usb.AppleUSBXHCI</string>
<key>Find</key>
<data>g/sPD4MDBQAA</data>
<key>Replace</key>
<data>g/sPkJCQkJCQ</data>
</dict>
</array>
</dict>
</dict>
</plist>

禁用了端口限制之后,您应该使用IORegistryExplorer检查端口是否在EHCI和XHCI控制器上为您的芯片组注入了所有预期端口。

端口发现

为了发现SSDT中需要哪些端口,我们将使用IORegistryExplorer,利用测试USB2和USB3设备测试每个端口,IORegistryExplorer可以跟踪对IOKit对象的更改来确定实际使用的端口(现有对象为黑色,绿色为新对象,红色的为断开连接的对象)。
注意:接下来的所有的测试都要在IOService中进行
通过插入USB2设备和USB3设备测试每个端口,如果在插入和删除设备时仔细查看,可以看到哪些端口分配给哪个物理端口。
注意:如果您有USB3集线器,则可以更轻松地测试每个端口。由于USB3集线器连接USB3端口的USB2引脚(并且仅可以在USB2端口中使用),并且无需正确弹出操作,因些您会发现使用USB3的速度更快集线器而不是一组USB2/USB3记忆棒。在下面的示例中,我使用USB3集线器来测试端口。

不要使用IORegistryExplorer.app中的搜索框,只需在左侧窗格中查看ioreg树的正确部分(根据需要滚动以查找适用于您的硬件的EH01/EH02/XHC)。请注意,要正确测试每个端口,您可能需要将任何USB键盘或鼠标设备移动到不同的端口,以便您可以使用USB2和USB3(或USB3集线器)测试每个端口。

为USBInjectAll.kext创建自定义SSDT

USBInjectAll.kext以数据驱动方式编码。在kext代码本身中没有任何硬编码。所有数据都包含在info.plist中。当USBInjectAll.kext启动,匹配EH01/EH02/XHC或连接到EH01/EH02端口1的内部集线器时,它会查询info.plist中与其连接的设备相关的配置数据并注入它找到的数据那里。但是SSDT可用于覆盖info.plist中的数据。

SSDT-UIAC-ALL.dsl中提供了一个模板,该模板覆盖了USBInjectAll.kext info.plist中已有的所有数据。您可以将SSDT-UIAC-ALL.dsl编译为SSDT-UIAC-ALL.aml(文件另存为,格式为MaciASL中的ACPI机器语言二进制文件)并将其置于ACPI/patched中,尽管info.plist中的所有数据都可以将被SSDT覆盖,不会观察到任何净更改,因为SSDT-UIAC-ALL.dsl中的数据与USBInjectAll.kext info.plist中已有的数据相同。

为了实现我们的更改,我们必须修改SSDT-UIAC-ALL.dsl,使其仅包含我们需要的端口

步骤如下:

  • 使用SSDT-UIAC-ALL.dsl作为模板
  • 删除不适用于目标硬件的配置节点
  • 从不需要的各个部分中删除端口
  • 更改UsbConnector值以匹配物理硬件/端口

第一步是从SSDT-UIAC-ALL.dsl中删除不适用于目标硬件和USB配置的配置数据。
例如,如果EH01 / EH02或相关USB集线器(在PR11 / PR21上)没有活动端口,则可以取消EH01 / EH02 / HUB1 / HUB2的配置数据。 在Skylake的情况下,它没有EHCI控制器,因此可以在不需要太多考虑的情况下移除EH01 / EH02 / HUB1 / HUB2配置。 如果您通过BIOS或ACPI(稍后介绍)禁用EHCI,情况也是如此。 并且您可以消除任何与您的XHC设备ID不匹配的XHC配置。 在ioreg中查找您的XHC设备ID。I