15個制限を回避するUSBInjectAll.kextの役割と使用法

 

USBInjectAll.kextの役割を確認するために外して調べてみました。マザボ搭載USBポートの情報を正しく反映するために必要でした。さらに正確に反映させるためのSSDTを作りました。

USBInjectAll.kextの役割

このkextを外してみる

RehabManさんが開発してくれているUSBInjectAll.kextは、いつも使用しているのですが、そのありがたみがイマイチ理解できていませんでした。そこで外してみたらどうなるのか調べました。

USBポートの状態を調べるために、macOSから見えるハードウェア構成を確認するツールであるIORegistryExplorerを使用します。これを起動して、右上の検索欄でxhcとタイプすると、USB関連のポート一覧を見ることができます。この時、USBポートの名前がXHCではなくて、XHCIだったりXHC0だったりした場合は、config.plistでパッチを当てておいたほうが良いです。オリジナルのMacで使われている名前と衝突して問題を引き起こす可能性があるらしいです

今回使用したのはASUSのZ390マザーボードであるROG MAXIMUS XI HEROです。これに搭載されているZ390チップセットの仕様を調べると搭載しているUSBは、

  • USB2.0が14本
  • USB3.1が10本(そのうち6本までをGen 2にできる)

だそうです。つまりIORegistryExplorerから見ると、HS01からHS14までの14本のUSB 2.0と, SS01からSS10までの10本のUSB 3.1が見える可能性があります。ただし、macOS El Capitanから導入された制約から、このうちの15本しか見えないはずです。

では、USBInjectAll.kextを外した状態でのMAXIMUS XIのUSBポート一覧です。こんな感じでした。

無意味に番号が飛んでいて、でたらめな感じがします。前の記事で調べたように、HS01はマザーボードのLED電飾機能が使っていて、HS14は内蔵Bluetoothが使っています。OSでもアプリケーションでも使用する重要なポートなのに、見えていません。また、このマザーボードでは、USB 3.1に付随する2.0は同じ番号を持っています。なのでSS01があるのにHS01が無いのは不自然です。明らかに、ASUSが提供しているマザーボード情報では無いと思われます。何かの方法で適当にリストアップされたように見えます。他にもHS13が見えてません。これはマザーボード上のUSB 2.0コネクタに接続しています。今回はここにmacOSと互換性のあるBluetoothモジュールを接続しているので、それがリストに無いと、Bluetoothキーボード、トラックパッドが使えません。

このkextを使ってみる

次に、USBInjectAll.kextを入れて起動した状態でのUSBポート一覧です。こうなります。

HS01から順番に欠番なくポートが見えていることがわかります。HSの次にあまり意味のないUSR1が来ていて、ここで15個の制限に達しています。なのでUSB 3.1のポートは見えていません。15個の制限がなければ、この後、USR2, SS01, SS02, …, SS10が、欠番なく全て見えるはずです。ということでUSBInjectAll.kextは、その名前の通り、もともと備えているUSBポートを全て認識させる機能を持っていることがわかりました。

このkextの中身を見る

このkextが、USBポート一覧をどうやって入手できたのかというと、作者のRehabManさんが用意しておいてくれたからです。kextの中の、Contentsの中に、Info.plistというテキストファイルがあります。これを開くと、前半部分に、USBコントローラのベンダーID、デバイスIDごとに、構成されているポート一覧が記載されていることがわかります。

使っているUSBコントローラのベンダーID、デバイスIDもIORegistryExplorerで知ることができます。

コントローラと思われるあたりをクリックすると、右側の詳細ペーンにvendor-id, device-idが現れます。リトルエンディアン方式なので逆に読みます。これによると、ASUSのこのマザーボードの場合、vendor-idは0x8086でインテル社であることがわかり、device-idは0xA36Dだとわかります。おそらくこれがZ370チップセットのUSBコントローラだと思われます。Info.plistで<key>8086_a36d</key>の場所を探すと、HS01からHS14と、SS01からSS10が記載されていることがわかります。

SSDTを作ってUSB15個制限に対応する

次に、USBInjectAll.kextの機能を使って、USB15個制限に対応する方法を説明します。今までの記事では、Cloverのブートオプションでuia_excludeを使う方法を紹介してきました。例えば、除外したいポートを以下のように指定します。

<key>Arguments</key>
<string>uia_exclude=USR1;USR2;HS01;HS02;HS09;HS10;HS14</string>

などと書く方法です。この方式では、オプションをUSBInjectAll.kextが引き取って、Info.plistのリストから外してくれています。でも、RehabManさんおすすめの方法は、SSDTを作りUSBInjectAll.kextに知らせる方法のようです。

SSDTというのは、ハードウェアの情報を記載するDSDTファイルの補助的なファイルです。DSDTの一部の情報を上書きして変更します。USBポートに関する情報を上書きするSSDTを用意することで、USBInjectAll.kextは、Info.plistの内容ではなく、SSDTの情報を使用してくれるようです。この手順を以下で説明します。

USBポートを調べる

まずは、マザーボードに搭載されているUSBポートを調べて、使用したい15個のポートを決定します。上記のページには手順が詳しく説明してありますが、以前の記事で紹介したので省略します。その結果、今回使用したマザーボード、ASUS ROG MAXIMUS XI HEROには以下のポートがありました。

  • HS01 AsusTek社のAURA MOTHERBOARDが使用
  • HS02 (不明, マザーボード上のU31G2_2の可能性あり)
  • HS03 バックパネルUSB 3のUSB 2.0 (4列上から3番目、赤、”SS10”)
  • HS04 バックパネルUSB 3のUSB 2.0 (4列上から4番目、赤、”SS10”)
  • HS05 バックパネルUSB 3のUSB 2.0 (Eternetの下、赤、”SS10″)
  • HS06 バックパネルUSB TYPE CのUSB 2.0 (Eternetの下)
  • HS07 バックパネルUSB 3のUSB 2.0 (4列上から1番目、青、”SS”)
  • HS08 バックパネルUSB 3のUSB 2.0 (4列上から2番目、青、”SS”)
  • HS09 マザーボードの3.1 Gen 1端子U31G1_910に付随するUSB2.0
  • HS10 マザーボードの3.1 Gen 1端子U31G1_910に付随するUSB2.0
  • HS11 バックパネルUSB 2.0 (PS/2の真下, 無表記)
  • HS12 バックパネルUSB 2.0 (PS/2の下, “BIOS”)
  • HS13 マザーボードの2.0端子USB_E12, USB_E34 (USB2.0 Hub経由)
  • HS14 マザーボード上のWiFi/Bluetoothモジュールが使用
  • SS01 (不明, 未使用?)
  • SS02 (不明, マザーボード上のU31G2_2の可能性あり)
  • SS03 バックパネルUSB 3.1 Gen 2 (4列上から3番目、赤、”SS10”)
  • SS04 バックパネルUSB 3.1 Gen 2 (4列上から4番目、赤、”SS10”)
  • SS05 バックパネルUSB 3.1 Gen 2 (Eternetの下、赤、”SS10″)
  • SS06 バックパネルUSB TYPE CのUSB 3.1 Gen 2 (Eternetの下)
  • SS07 バックパネルUSB 3.1 Gen 1 (4列上から1番目、青、”SS”)
  • SS08 バックパネルUSB 3.1 Gen 1 (4列上から2番目、青、”SS”)
  • SS09 マザーボードのU31G1_910の USB3.1 Gen 1
  • SS10 マザーボードのU31G1_910の USB3.1 Gen 1

このうち、以下の15個を使うことにしました。

  1. HS03 バックパネルUSB 3のUSB 2.0 (4列上から3番目、赤、”SS10”)
  2. HS04 バックパネルUSB 3のUSB 2.0 (4列上から4番目、赤、”SS10”)
  3. HS05 バックパネルUSB 3のUSB 2.0 (Eternetの下、赤、”SS10″)
  4. HS06 バックパネルUSB TYPE CのUSB 2.0 (Eternetの下)
  5. HS09 マザーボードの3.1 Gen 1端子U31G1_910に付随するUSB2.0
  6. HS10 マザーボードの3.1 Gen 1端子U31G1_910に付随するUSB2.0
  7. HS11 バックパネルUSB 2.0 (PS/2の真下, 無表記)
  8. HS12 バックパネルUSB 2.0 (PS/2の下, “BIOS”)
  9. HS13 マザーボードの2.0端子USB_E12, USB_E34 (USB2.0 Hub経由)
  10. SS03 バックパネルUSB 3.1 Gen 2 (4列上から3番目、赤、”SS10”)
  11. SS04 バックパネルUSB 3.1 Gen 2 (4列上から4番目、赤、”SS10”)
  12. SS05 バックパネルUSB 3.1 Gen 2 (Eternetの下、赤、”SS10″)
  13. SS06 バックパネルUSB TYPE CのUSB 3.1 Gen 2 (Eternetの下)
  14. SS09 マザーボードのU31G1_910の USB3.1 Gen 1
  15. SS10 マザーボードのU31G1_910の USB3.1 Gen 1

テンプレートからdslファイルを作る

この15個のUSBポートを指定するSSDTファイルを作成するために、そのテンプレートになるファイルSSDT-UIAC-ALL.dslを、こちらから入手します。コピーして、SSDT-UIAC.dslと改名しておきます。

このファイルには多数のUSBコントローラの情報が書いてあります。実際に使用するコントローラの項目だけを残して、他を削除します。ASUS Z390マザーボードの場合、vendor-idが0x8086で、device-idが0xA36Dです。この数値は上で説明したように、IORegistryExplorerでXHCの項目の中を探せば、vendor-id, device-idとして書いてあります。0x8086はインテルの番号ですので、インテルのチップセットを表しています。そこで”8086_a36d”と書かれた”Package”の定義だけを残して、他のPackageの定義を削除します。残すのは以下の項目です。

"8086_a36d", Package()
{

...........

},

この中にはHS01からSS10までのUSBの情報が書かれています。これに対して以下の作業をします。

  • コメントでポートの説明を記録しておく。後のメモになります。//で書き始めればコメントになります。
  • 不要なポートをコメントアウトする。行頭に//を書いて、使用しないポートを除外していきます。削除せずにコメントにすれば、あとから復活させるのが楽です。
  • UsbConnector情報を更新する。これについては次に説明します。

UsbConnector情報

SSDT-UIAC.dslのそれぞれのUSBポート情報には、コネクタ種類が数字で記載されています。これを更新します。具体的には、以下のように書かれている部分の数字を、実際に合わせて書き換えます。

"UsbConnector", 3,

書き換える値は、以下の通りです。

  • 0: USB 2.0のコネクタ
  • 3: USB 3.1のコネクタ。3.1に付随するUSB 2.0も3にします。
  • 255: 内部接続で外部に接続しないコネクタ。マザーボード内部でBluetoothユニットに接続しているなどの場合にこれを使います。マザーボード上のコネクタで外部に引き出す可能性のあるものは0または3にします。
  • 9: USB Type-Cのコネクタ。逆挿しにしてもHSとSSの番号が変化しない場合。内部でハブに接続されているらしいです。
  • 10: USB Type-Cのコネクタ。逆挿しするとHSとSSの番号が変化する場合。個別に接続されています。

この数字がどのように反映されるのか詳しくは知りません。でもIORegistryExplorerを見ると、255にした場合に電流に関するパラメータなどが消えるので、OSからの扱いが変化する可能性があります。また255にしたポートにArduinoを接続してみたところ、/dev/cu.usbserial-*などのデバイスが見えませんでした。USBシリアルドライバーが、この数字を基準に動作を変えているようです。Arduinoを接続するなら、0や3に設定しておくのが良いです。

どのHSポートがUSB 2.0になるのかUSB 3.1になるのか、さらにはどのポートがType-Cになるのかは、マザーボード次第です。USBInjectAll.kextのInfo.plistにマザーボードごとの情報まで反映できないので、RehabManさんは各自でSSDTを作って、使用するマザーボードに即したUsbConnector情報をOSに伝えることを推奨しています。

port-countを設定する

SSDT-UIAC.dslの最初の部分に、portsのセクションの前に、port-countというセクションがあります。

"port-count", Buffer() { 26, 0, 0, 0 },
"ports", Package()
{

ここに書く数値(10進数)には、今回作ったポートのバッファー値、例えば、

"port", Buffer() { 26, 0, 0, 0 },

などと表される数のうちの最大の数値を書きます。 今回はたまたま末尾のSS10まで使用したので、26のままで変更無しです。

dslをコンパイルしてamlを作る

こうして作ったdslファイルはSSDTのソースファイルのようなものです。これをコンパイルしてSSDTであるamlファイルを作ります。これにはMaciASLを使用します。こちらの記事で説明しています。

MaciASLで、上で作成したSSDT-UIAC.dslを開きます。次に、FileのSave As…を選び、バイナリー出力を指定して書き出すとSSDT-UIAC.amlが出来上がります。

こうして作成したSSDT-UIAC.amlファイルを、ESPのEFI/CLOVER/ACPI/patched/にコピーすれば有効になります。これでCloverのブートオプションにuia_exclude=を指定しなくても、指定したポートのみが有効になるはずです。参考のために、今回作成したSSDT-UIAC.aslファイルを以下に置いておきます。

6件のコメント

  1. お疲れ様です。

    H370もdevice-idがa36dなので、うまくいきました。
    ちょっと、編集に困りましたが、

    DefinitionBlock ("", "SSDT", 2, "hack", "_UIAC", 0)
    {
        Device(UIAC)
        {
            Name(_HID, "UIA00000")
    
            Name(RMCF, Package()
            {
    

    以降の、{
    のインデントだと、気がつきました。
     DSDTやSSDTについて、概略を試して見るいい機会になりました。ありがとうございます。

    1. インデントと言いながら、インデントできてないですね。code,preで囲むんでしょうか・・・^^;

      DefinitionBlock ("", "SSDT", 2, "hack", "_UIAC", 0)
      {
          Device(UIAC)
          {
              Name(_HID, "UIA00000")
      
              Name(RMCF, Package()
              {
      
        1. 勝手ながら編集させていただきました。

          preタグで挟むとタブが出るようです。<pre>と</pre>です。(反応しないように全角で書きました)

          1. ありがとうございます。
            <pre>と</pre>ですね、今度はそれでやってみます。

  2. お世話になります

    全然参考にならないとは思いますが MacのUSB 15個 制限 は MIDI の規格に というか
    KORG とかの DTM 機器との接続 との 兼ね合い なのでは?と思って投稿させて頂きます。

    KORG関連ページ
    >コンピューターへ今まで MIDI デバイスを 10 種類以上接続したことがある場合、MIDI デバイスを認識し>ないことがあります。

    https://support.korguser.net/hc/ja/articles/115004269166-Windows-%E3%81%A7%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%8C%E8%AA%8D%E8%AD%98%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93

mifjpn へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です