В настройке USB на хакинтоше мне почудилось какое-то неуловимое сходство с настройкой музыкального инструмента. Потребовалось в процессе и после: программы IORegistryExplorer и maciASL, расширения USBInjectAll.kext и XHCI-200-series-injector.kext, редактор для plist (сойдет TextMate), устройства USB 2.0 и USB 3.0. На выходе получился файл SSDT-USB.aml.
![IORegistry / XHC / USB]()
Для начала нужно положить USBInjectAll.kext и XHCI-200-series-injector.kext в папку /EFI/CLOVER/kexts/other. Первый нужен всем и скорее всего уже будет куда-либо установлен проверьте обычные места (/S/L/E /L/E). Второй необходим для материнских плат на чипсетах 200 серии, без него у меня не работал USB3. Далее нужно устранить ограничение на 15 портов, делается правкой /EFI/CLOVER/config.plist.
Ахтунг, никогда не редактируйте plist/xml и т.п. в приложениях типа TextEdit.
<key>KextsToPatch</key>
<array>
<dict>
<key>Comment</key>
<string>change 15 port limit to 26 in XHCI kext (200-series) 10.12</string>
<key>Find</key>
<data>
g710////EA==
</data>
<key>Name</key>
<string>AppleUSBXHCIPCI</string>
<key>Replace</key>
<data>
g710////Gw==
</data>
</dict>
...
После перезагрузки у вас должны работать все имеющиеся USB порты. На этом можно было бы остановиться, но если делать по-уму, то дальше начинается забавная рутина. Суть — оставить только те порты, которые реально существуют на вашей машине и назначить им правильный тип.
Запускаем IORegistryExplorer и ищем HS01, находится он в ветке XHC. Смотрим список соседей. Я не удосужился сделать скриншот «до», но изначально там было 26 устройств типа HSxx SSxx и какие-то USRxx. Для каждого устройства есть набор параметров, из которых нас будет интересовать только port и UsbConnector.
Теперь развлекушка — нужно поочередно подключить к каждому USB 2.0 (черные) и USB 3.0 (обычно синие) разъему на корпусе и материнке USB 2.0 устройство, отследить изменения в IOReg и записать ID устройства, его порт и расположение. Типа такого: HS01 — <04 00 00 00> — Top MB USB3 port. Затем нужно подключить USB 3.0 устройство ко всем USB 3.0 портам и разъемам на материнской плате и сделать похожий список: SS03 — <13 00 00 00> — Internal USB3_1 header. В общем списке должно получиться USB2_count + USB3_count x 2 записей — для каждого USB3 порта будет одна HSxx запись и одна SSxx.
У меня получился такой список:
HS01 USB2 on Back bottom outer USB3 <01 00 00 00>
HS02 USB2 on Back bottom inner USB3 <02 00 00 00>
HS03 USB2 on Back top outer USB3 <03 00 00 00>
HS04 USB2 on Back top inner USB3 <04 00 00 00>
HS06 USB2 on Case top slot USB3 mobo header 1 <06 00 00 00>
HS08 USB2 on Case top slot USB3 mobo header 2 <08 00 00 00>
HS09 USB2 on Case bottom slot USB_1 mobo header <09 00 00 00>
HS11 USB2 on Case bottom slot USB_2 mobo header <0b 00 00 00>
HS13 USB2 on Back topmost inner USB2 <0d 00 00 00>
HS14 USB2 on Back topmost inner USB2 <0e 00 00 00>
SS01 USB3 on Back bottom outer USB3 <11 00 00 00>
SS02 USB3 on Back bottom inner USB3 <12 00 00 00>
SS03 USB3 on Back top outer USB3 <13 00 00 00>
SS04 USB3 on Back top inner USB3 <14 00 00 00>
SS06 USB3 on Case top slot USB3 mobo header 1 <16 00 00 00>
SS08 USB3 on Case top slot USB3 mobo header 2 <18 00 00 00>
В списке есть «дыры» — на внутренних коннекторах USB доступны по 2 порта, но у меня на корпус выведены только 1xUSB2 и 1xUSB3, то есть к оставшимся 4 разъемам я подключиться не могу. Можно их просто заполнить по порядку, но большого смысла нет, поскольку в конце рабочих портов все равно останется только 15.
С этой табличкой на руках запускаем maciASL, создаем новый dsl файл и заполняем нашими данными. Значение для UsbConnector такие: 0 для обычного USB2, 3 для USB3 type A, 10 для USB3 type C, 255 для внутреннего разъема для того самого Bluetooth. В итоге должно получиться что-то типа такого.
DefinitionBlock ("SSDT-USB.aml", "SSDT", 1, "sample", "USBFix", 0x00003000)
{
// "USBInjectAllConfiguration" : override settings for USBInjectAll.kext
Device(UIAC)
{
Name(_HID, "UIA00000")
// "RehabManConFiguration"
Name(RMCF, Package()
{
// XHC overrides for 100-series boards
"8086_a2af", Package()
{
"port-count", Buffer() { 0x18, 0, 0, 0}, // Highest port number is SS** at 0xNN
"ports", Package()
{ // TO COMPLETE THIS FILE, ADD ALL YOUR PORTS BELOW HERE, THEN SET port-count ABOVE
"HS01", Package() // USB2 on Back bottom outer USB3 <01 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x01, 0, 0, 0 },
},
"HS02", Package() // USB2 on Back bottom inner USB3 <02 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x02, 0, 0, 0 },
},
"HS03", Package() // USB2 on Back top outer USB3 <03 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x03, 0, 0, 0 },
},
"HS04", Package() // USB2 on Back top inner USB3 <04 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x04, 0, 0, 0 },
},
"HS06", Package() // USB2 on Case top slot USB3 mobo header 1 <06 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x06, 0, 0, 0 },
},
"HS08", Package() // USB2 on Case top slot USB3 mobo header 2 <08 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x08, 0, 0, 0 },
},
"HS09", Package() // USB2 on Case bottom slot USB_1 mobo header <09 00 00 00>
{
"UsbConnector", 0,
"port", Buffer() { 0x09, 0, 0, 0 },
},
"HS11", Package() // Bluetooth on slot USB_2 mobo header <0b 00 00 00>
{
"UsbConnector", 255,
"port", Buffer() { 0x0b, 0, 0, 0 },
},
"HS13", Package() // USB2 on Back topmost inner USB2 <0d 00 00 00>
{
"UsbConnector", 0,
"port", Buffer() { 0x0d, 0, 0, 0 },
},
"HS14", Package() // USB2 on Back topmost outer USB2 <0e 00 00 00>
{
"UsbConnector", 0,
"port", Buffer() { 0x0e, 0, 0, 0 },
},
"SS01", Package() // USB3 on Back bottom outer USB3 <11 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x11, 0, 0, 0 },
},
"SS02", Package() // USB3 on Back bottom inner USB3 <12 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x12, 0, 0, 0 },
},
"SS03", Package() // USB3 on Back top outer USB3 <13 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x13, 0, 0, 0 },
},
"SS04", Package() // USB3 on Back top inner USB3 <14 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x14, 0, 0, 0 },
},
"SS06", Package() // USB3 on Case top slot USB3 mobo header 1 <16 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x16, 0, 0, 0 },
},
"SS08", Package() // USB3 on Back bottom outer USB3 <11 00 00 00>
{
"UsbConnector", 3,
"port", Buffer() { 0x18, 0, 0, 0 },
},
},
},
})
}
}
В port-count нужно вписать цифровое значение port самого последнего порта, у меня это SS08 и порт 0x18.
Полученный файл нужно сохранить в формате ACPI Machine Language Library (asl). Если по ходу компиляции никаких ошибок не будет, то полученный SSDT-USB.aml кладем в /EFI/CLOVER/ACPI/patched и перезагружаемся. Если все прошло нормально, то в XHC должны остаться только описанные порты, все они должны нормально работать.
Опционально — можно довести число портов до 15 и избавиться от патча в config.plist. Сделать это можно при помощи параметра загрузки uia_exclude в том же config.plist. У меня эта строчка выглядит так:
<key>Boot</key>
<dict>
<key>Arguments</key>
<string>dart=0 nv_disable=1 uia_exclude=HS08;SS08</string>
<key>Debug</key>
...
Я исключил порты HS08 и SS08, это внутренний разъем USB3_2, который я не использую — всего осталось 14 штук. В принципе, можно просто выкинуть пару портов из самого asl, наверно, поскольку еще 4 порта я вообще не вписал.
Размышления напоследок
- Тип разъема мало на что-то влияет, по-моему. Разницы между 0 и 255 я не увидел — Bluetooth не заработал ни так, ни эдак, при этом обычная флэшка в обоих случаях работает.
- У меня все синие порты вроде заявлены как USB 3.1 Gen 1 (он же новый 3.0), в системной информации показывает Speed: Up to 5 Gb/sec, но фактическую скорость померить нечем.
- Зачем избавляться от патча, делающего доступными все порты? Чем чревато — непонятно.
- USB 3.1 Gen 2 у меня нет, как и Type-C, так что двумя проблемами меньше.
Ссылки и респекты