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


30

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

まず、USBデバイスからドライバーを手動でデタッチし、別のデバイスをアタッチするにはどうすればよいですか?たとえば、接続時に自動的にusbストレージドライバーを使用するデバイスがあります。

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で可能ですか?


1
問題の一部が適切なモジュールをロードしている場合は、AngströmのWebcam
Gilles「SO- stop being evil」

1
あなたはすべてのUSBストレージモジュールが必要ですか?そうでない場合は、ブラックリストに入れてもまったくロードされないためです。
ハナンN.

@ Gilles、LKMを正常にロードできました。私の質問は、手動で自動的にデバイスに接続する方法ですか?
linsek

@Hanan、現在はusb-storageモジュールを使用していません。正しいモジュールを自動的にアタッチするにはブラックリストに登録する必要がありますが、最初にusbnetモジュールをアタッチする方法を知る必要があります。
linsek

1
@njozwiakモジュールusbnetは、それを使用できるハードウェアに関する情報がないため、自動的にロードされません。適切なドライバーを見つけて、たとえばを使用してみてください modinfo kalmia。ではaliasラインあなたは、ベンダーID XXXXとプロダクトID YYYYをとして表示されますusb:vxxxxpyyyy。または、ファイル/lib/modules/kernel_version/modules.usbmapを編集し、HWの行を削除できます。HWモジュールのusb-storageを使用するか、適切なネットドライバーでusbstorageを変更します。しかし、depmod -aこの変更が
Jan Marek

回答:


20

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

質問の2番目の部分については、udevはドライバーの読み込みに反応できますが、特定のドライバーをデバイスに強制的に割り当てることはできません。

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

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

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

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

MODULE_ALIAS("usb:...")

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

サポートされているデバイス(モダリアによる)とそれらに関連するモジュールを表示するには

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

usb-storageデバイスドライバーをgrepすると、ベンダーとデバイスIDでサポートする特定のデバイスが表示され、ベンダー/デバイスに関係なく、適切な(ストレージ)クラスのデバイスもサポートしようとします。 。

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

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

これは一般的な場合の理論です。

実際には、USBの場合、デバイスには2つのインターフェイスがあり、そのうちの1つがストレージであるように見えます。カーネルは、デバイス全体のストレージインターフェイスに接続します。他のインターフェイスに適切なクラスがある場合、usbnetドライバそれに接続できます。はい、USBデバイスは複数のインターフェースをエクスポートするため、同じ物理デバイスに複数のドライバーを接続できます。(例えば、私のLogitech G15キーボード輸出二つそれは別のドライバによって処理されそれぞれがキーボード装置およびLCDスクリーンを有するため) 。

USBデバイスの2番目のインターフェイスが検出されないという事実は、カーネルのサポートが不足していることを示しています。いずれにせよ、以下を使用して、非常に詳細にデバイスのインターフェース/エンドポイントをリストできます。lsusb -v | lessし、特定のデバイスまでスクロールダウンできます(必要に応じて、device:vendor IDまたはUSBパスで出力を制限できます)。

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


4
static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);コードにはすでにありますが、モダリアで冗長ですか?
トーマス14年

私の場合、これらの行は、ドライバー内のどこかでMakefileマジックによって自動生成されます。そのため、MODULE_ALIASの行を3回追加しましたが、リストには表示されません。とにかくlsusb -vに感謝します。それで私はそれをチェックし、私のアイデアの欠陥を見つけることができました。次に、既知の識別子のソースをgrepし、操作する必要があるエントリを含む配列を見つけました。
JackGrinningCat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.