企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # 【指南】为Sierra(以及后来的版本)进行USB功率特性注入 > 英文原文:[[Guide] USB power property injection for Sierra (and later)](https://www.tonymacx86.com/threads/guide-usb-power-property-injection-for-sierra-and-later.222266/) # 综述 看来Sierra已经改变了USB功率特性(USB power properties)的设置方式。在之前的版本中,我们已经直接对`XHC/EHCI`这个ACPI对象(on the XHC/EHCI ACPI objects),注入了AAPL,current-available, AAPL,current-extra, AAPL,current-extra-in-sleep, and AAPL,max-port-current-in-sleep。在`Sierra`中,这些似乎被注入到`ioreg`中的`AppleBusPowerControllerUSB`对象的新属性所取代。 让我们看一下所需的更改... # 跟踪证据(Tracing the evidence) 其中一些变化是在USBInjectAll.kext开发期间注意到的... 我还记得一些看起来很有趣的“`kUSB*`”属性,这些属性在一个USB kext 的 `Info.plist`文件中。一个简单的grep搜索就能揭示我们查看的位置: ``` SPEEDY-NUC:nuc.git rehabman$ grep -l kUSB.* -R /System/Library/Extensions/IOUSBHostFamily.kext /System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist /System/Library/Extensions/IOUSBHostFamily.kext/Contents/MacOS/IOUSBHostFamily /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCI.kext/Contents/MacOS/AppleUSBEHCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/Info.plist /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/MacOS/AppleUSBEHCIPCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostCompositeDevice.kext/Contents/MacOS/AppleUSBHostCompositeDevice /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostMergeProperties.kext/Contents/Info.plist /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/Info.plist /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/MacOS/AppleUSBHub /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBOHCIPCI.kext/Contents/MacOS/AppleUSBOHCIPCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCI.kext/Contents/MacOS/AppleUSBUHCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCIPCI.kext/Contents/MacOS/AppleUSBUHCIPCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCI.kext/Contents/MacOS/AppleUSBXHCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/Info.plist /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/MacOS/AppleUSBXHCIPCI /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/IOUSBHostHIDDevice.kext/Contents/MacOS/IOUSBHostHIDDevice ``` 嗯... 看起来`/System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist` 是个开始的好位置: 看看我们的发现了什么: ![](https://box.kancloud.cn/dd36bd0f026dbe0468bc3d2f534b13f9_727x597.png) 正如你所看到的有各种属性(`kUSBSleepPortCurrentLimit`、`kUSBSleepPowerSupply`,`kUSBWakePortCurrentLimit`,`kUSBWakePowerSupply`),通过一个`AppleUSBHostMergeProperties`注射器,使它被注入到`AppleBusPOwerControllerUSB`提供者(provider)。 但是我检查自己的`ioreg`,发现`AppleBusPowerControllerUSB`并没有在任何地方被加载。那么问题是,是什么使它加载…另一个简单的grep搜索将告诉我们: ``` SPEEDY-NUC:nuc.git rehabman$ grep -l AppleBusPowerControllerUSB -R /System/Library/Extensions /System/Library/Extensions/AppleBusPowerController.kext/Contents/Info.plist /System/Library/Extensions/AppleBusPowerController.kext/Contents/MacOS/AppleBusPowerController /System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist ``` 现在看看`AppleBusPowerController.kext`的`Info.plist`: ![AppleBusPowerController.kext-Info.plist](https://box.kancloud.cn/d6f39785de98a1b35b3e47abe98802f1_596x157.png) 我们可以看到它匹配了一个名为“`EC`”的ACPI设备。有些电脑使用`EC`作为嵌入式控制器(Embedded Controller),但大多数使用`EC0`或`H_EC`。 有了这些知识,我们可以简单地重命名`H_EC->EC`,或者 `EC0->EC`,然后`AppleBusPowerControllerUSB`被加载,而且在`IOUSBHostFamily.kext/Contents/Info.plist`中,对每个支持的`SMBIOS`的相关注入也是如此。 现在,如果你仔细看 `IOUSBHostFamily`的`Info.plist`,你会发现新的SMBIOS不见了。例如`MacBookPro9,1`, `iMac17,1`, 和 `MacBookPro13,x`.。这些型号必须使用不同的方法来进行USB功率特性的注入。 `AppleBusPowerController`的反编译显示,它正在在`IOACPIPlane`中查找一个名为“`USBX`”的对象。然后,它似乎会从设备属性中提取必要的数据。如果我们看一个`iMac17,1`的`ioreg`,我们会发现这个: ![](https://box.kancloud.cn/ff2961db4b186fce68ca37bb751e2e01_683x478.png) 还有我们的能量性能(power properties ) 看看 iMac17.1 中的`DSDT.aml `,我们找到`USBX` 的源代码: ``` Scope (_SB) { ... Device (USBX) { Name (_ADR, Zero) // _ADR: Address Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method { Store (Package (0x08) { "kUSBSleepPowerSupply", 0x13EC, "kUSBSleepPortCurrentLimit", 0x0834, "kUSBWakePowerSupply", 0x13EC, "kUSBWakePortCurrentLimit", 0x0834 }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } ``` 嗯,不要惊讶这些... 四个USB能量性能(USB power properties)的标准的`_DSM`注入。 摘要: - 如果该电脑存在`EC`,那么命名为“'EC”并且`AppleBusPowerControllerUSB`将被加载。 - 如果SMBIOS匹配`IOUSBHostFamily.kext/Contents/Info.plist` 中的其中一个“legacy SMBIOS”,该Mac型号的能量性能将被注入(它们可能适合您的硬件,也可能不适合) - 如果在`IOUSBHostFamily.kext/Contents/Info.plist`没有SMBIOS存在,那`ACPI`中的`USBX`设备会通过正常的`_DSM`属性注入 来决定能量性能。 # 保证 AppleBusPowerControllerUSB 的加载 如果你有一个嵌入式控制器(大多数笔记本电脑,一些台式机),你只需确保ACPI设备被命名为`EC`。这很容易通过`config.plist`的ACPI hotpatch来完成。我已经将两个普通的`renames`添加到所有的笔记本指南`plist`文件中。 看起来就这样: ![renames](https://box.kancloud.cn/f7a1d50a065a361d8a3a7dd2f9faed8b_491x375.png) 注意:如果你正在使用静态的打补丁的SSDTs(就是说,`ACPI/patched`目录有打补丁的`OEM SSDTs`),你要确保在这些文件中都手动完成`EC`重命名。Clover的`config.plist/ACPI/DSDT/Patches`只对`ACPI/patched`的`DSDT.aml` 以及从BIOS中加载的`OEM DSDT`和`SSDTs`生效,…不会对`ACPI/patched`中的`SSDTs`生效。 如果你没有嵌入式控制器,可以使用下面的`SSDT-EC.dsl`(编译为AML)添加一个“假”的: ``` // Inject Fake EC device DefinitionBlock("", "SSDT", 2, "hack", "EC", 0) { Device(_SB.EC) { Name(_HID, "EC000000") } } //EOF ``` 注意: 您可能会发现您的`DSDT`中有一个`EC`:带有“`Name (_HID, EisaId ("PNP0C09"))`”的设备,即使它不活动。 例如,这是在我的NUC6i7KYK: ``` Scope (_SB.PCI0.LPCB) { Device (H_EC) { Name (_HID, EisaId ("PNP0C09")) // _HID: Hardware ID Name (_UID, One) // _UID: Unique ID Method (_STA, 0, NotSerialized) // _STA: Status { Store (0x03, ^^^IGPU.CLID) Return (Zero) } ... ``` 正如您所看到的,它从`_STA`返回`0`。根据ACPI规范,这是“不存在”的。这意味着`H_EC`设备被有效地忽略了。你会注意到它没有显示在`ioreg`,`IOService`板面上。 不要试图通过更改`_STA`的返回值来激活EC设备。这里返回`0`的原因是**该计算机没有`EC`** 。在这种情况下,您应该添加上面提到的“假”`EC`。 # 一个SSDT注入USBX设备 对于`IOUSBHostFamily.kext/Contents/Info.plist`中尚未覆盖的`SMBIOS` ,您将需要注入`USBX`设备来提供`AppleBusPowerControllerUSB`的能量性能。 下面是一个 `SSDT-USBX.dsl`示例: ``` // USB power properties via USBX device DefinitionBlock("", "SSDT", 2, "hack", "USBX", 0) { Device(_SB.USBX) { Name(_ADR, 0) Method (_DSM, 4) { If (!Arg2) { Return (Buffer() { 0x03 } ) } Return (Package() { // these values from iMac17,1 "kUSBSleepPortCurrentLimit", 2100, "kUSBSleepPowerSupply", 5100, "kUSBWakePortCurrentLimit", 2100, "kUSBWakePowerSupply", 5100, }) } } } //EOF ``` 你可能会认为你也可以重写(override) 该例子中`IOUSBHostFamily.kext/Contents/Info.plist`提供的值。在这种情况下,将使用支持的SMBIOS。但不幸的是,事实并非如此。`IOUSBHostFamily.kext/Contents/Info.plist`中的值重写了由`USBX`提供的那些。 还有,如果你已经有了`SSDT-UIAC.aml`(你本该如此),通过简单地添加`_SB.USBX`设备到那个`SSDT`,而不是创建一个新的,这可能会有意义的。 # 重载(override) `IOUSBHostFamily.kext/Contents/Info.plist` Although you could patch this kext Info.plist to provide different properties for any supported SMBIOS, it is desirable to do so without patching since patching would need to be redone after any update that provided a new copy of the file. 虽然可以修补这个`kext`的 `Info.plist`来为任何受支持的SMBIOS提供不同的属性,这样不需要修补还是需要的,因为在提供了新文件副本的任何更新之后,会需要重新修改补丁。 I have added support in to inject these properties. And, at least in my testing, the properties injected by USBInjectAll.kext are succesful in overriding those from IOUSBHostFamily.kext. 我增加了`USBInjectAll.kext`的支持,来注入这些属性。而且,至少在我的测试中,由`USBInjectAll.kext` 注入的属性成功地重载了那些来自`IOUSBHostFamily.kext`的。 通过`USBInjectAll.kext`指定功率特性(power property)重写,你必须在你的`UIAC.RMCF`中提供一个“`AppleBusPowerControllerUSB`” 。 例如: ``` DefinitionBlock ("", "SSDT", 2, "hack", "usb", 0) { // // Override for USBInjectAll.kext // Device(UIAC) { Name(_HID, "UIA00000") Name(RMCF, Package() { // USB Power Properties for Sierra (using USBInjectAll injection) "AppleBusPowerControllerUSB", Package() { // these values happen to be iMac14,2 values... "kUSBSleepPortCurrentLimit", 2100, "kUSBSleepPowerSupply", 4700, "kUSBWakePortCurrentLimit", 2100, "kUSBWakePowerSupply", 4700, }, // XHC overrides (8086:9cb1, NUC5) "8086_9cb1", Package() { // other UIAC.RMCF content follows (for custom port injection) ... } //EOF ``` 这个功能是在`USBInjectAll.kext`的v0.6.0版本中新增的,所以不要期望它在旧的版本中工作。 # 问题报告 阅读FAQ,“问题报告” https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/