web-dev-qa-db-ja.com

USBドライバーをデバイスに割り当てる方法

この質問は2つあります。

まず、USBデバイスからドライバーを手動で切り離し、別のドライバーを接続するにはどうすればよいですか?たとえば、接続すると自動的にusb-storageドライバーを使用するデバイスがあります。

usbview出力

Vendor Id: xxxx
Product Id: xxxx
...
    Number of Interfaces: 2
    Interface Number: 0
        Name: usb-storage
        Number of Endpoints: 2
        ...
    Interface Number: 1
        Name: (none)
        Number of Endpoints: 2
        ...

私はusb-storageドライバーを使用したくないので、アプリケーションでlibusbライブラリを使用してusb-storageドライバーをデタッチし、インターフェイスを要求します。その後、USBデバイスとホストLinuxシステムで実行されているアプリケーションとの間でデータを送受信できます。

アプリケーションの外でドライバーを手動で切り離すにはどうすればよいですか?


次に、デバイスプラグインにアタッチするドライバーを自動的に割り当てるにはどうすればよいですか?現在、デバイスの権限を自動的に設定するためのudevルールを設定しています。

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

Udevルールを使用して、USBデバイスの特定のインターフェイスにドライバーを割り当てることはできますか?たとえば、usb-storageの代わりにインターフェイス0でusbnetモジュールを自動的に使用したい場合、udevではそれが可能ですか?

30
linsek

質問の最初の部分では、USBドライバーをデタッチする方法を探しましたが、libusbで既に実行している方法よりも良い方法を見つけることができませんでした。

質問の2番目の部分については、udevはreactをドライバーのロードに使用できますが、-forceはデバイスに割り当てる特定のドライバーを使用できません。

Linuxカーネルのすべてのドライバーは、1つ以上のデバイスを担当します。ドライバ自体が、サポートするデバイスを選択します。これはプログラムで行われます。つまり、デバイスのベンダーと製品IDを確認するか、それらが利用できない場合(古いデバイスなど)は、自動検出ヒューリスティックとサニティチェックを実行します。ドライバーは、サポートするデバイスが見つかると確信すると、自分自身をそれにアタッチします。つまり、特定のドライバーに特定のデバイスを使用させることはできません。ただし、場合によっては、デバイスドライバーが受け入れるものに寛大であること、およびデバイスcanが認識しないことで動作することがあります。あなたの走行距離は異なります!以前は、奇妙なPCIデバイス/ベンダーIDをサポートする必要があるドライバーに手動で追加する必要がありましたが、さまざまな成功といくつかの面白いカーネルクラッシュがありました。

さて、モジュールの場合、追加のステップがあります。 モジュールローダーは、新しいデバイスが検出されるとカーネルによって起こされます。これには、デバイスを識別し、USBデバイスの場合は次のように見える「modalias」文字列が渡されます。

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

この文字列には、デバイスクラス(usb)とクラス固有の情報(ベンダー/デバイス/シリアル番号、デバイスクラスなど)が含まれています。各カーネルドライバーには、次のような行が含まれています。

MODULE_ALIAS("usb:...")

Usbaliasと一致する必要があります(ワイルドカードは複数のデバイスとの一致に使用されます)。 modaliasがドライバーがサポートするものと一致する場合、このドライバーがロードされます(または、新しいデバイスが既に存在する場合は通知されます)。

(modaliasによって)サポートされているデバイスとそれらに関連付けられているモジュールを表示できます

less /lib/modules/`uname -r`/modules.alias

Usb-storageデバイスドライバーのgrepを実行すると、ベンダーとデバイスIDによってサポートされる特定のデバイスがいくつかあり、ベンダー/デバイスに関係なく、適切な(ストレージ)クラスを持つデバイスをサポートしようとすることがわかります。

OSのユーザースペースメカニズムを使用して、これに影響を与えることができます(Debianおよび友人では/etc/modprobe.d/)。 modules.aliasファイルと同じように(同じ構文を使用して)、モジュールをブラックリストに登録するか、modaliasによってロードされるモジュールを指定できます。 depmod -aは、モジュールローダーのパターンを再生成します。

ただし、この特定の馬を水に導くことはできても、彼に飲ませることはできません。ドライバーがデバイスをサポートしていない場合は、無視してください。

これが一般的なケースの理論です。

実際には、USBの場合、デバイスには2つのinterfacesがあり、そのうちの1つがストレージであるようです。カーネルは、デバイス全体のストレージinterfaceに接続します。他のインターフェースに適切なクラスがある場合、usbnetドライバーcouldがそれに接続されます。はい、USBデバイスは複数のインターフェースをエクスポートするため、同じ物理デバイスに複数のドライバーを接続できます(たとえば、Logitech G15キーボードは、キーボードデバイスを備えているため、2つをエクスポートします。 LCD画面、各画面は個別のドライバーによって処理されます)。

USBデバイスの2番目のインターフェイスが検出されないという事実は、カーネルでのサポートの欠如を示しています。どちらの場合でも、lsusb -v | lessを使用して、デバイスインターフェース/エンドポイントを詳細な説明で一覧表示し、特定のデバイスまで下にスクロールできます(必要に応じて、device:vendor IDまたはUSBパスで出力を制限できます)。 。

注意:USBデバイスの論理構造に関して、ここでは少し単純化しすぎています。 USBコンソーシアムのせいにします。 :)

20
Alexios