概述
在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过程包括如下步骤:
- 端口准备
- 端口发现
- 为USBInjectAll.kext创建自定义SSDT
- 测试/验证
MaciASL工具,确保MaciASL->Preferences->iASL中选择了ACPI 6.2a
端口准备
为了能够正确的为给定的PC配置正确的自定义SSDT,我们必须首先发现所启用的所有端口。一量我们知道了使用哪些端口,我们就可以关闭未使用的端口。首先,先用第一类注入方法也就是在Clover的config.plist/ACPI/DSDT/Patches中注入补丁的方法,注入EXHCx重命名和端口限制补丁。
1 | <?xml version="1.0" encoding="UTF-8"?> |
禁用了端口限制之后,您应该使用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