キャプチャされたUSBトラフィックに基づいて既存のUSBデバイス用のLinuxドライバを作成しようとしています。
この装置は様々な構成で提供される。残念ながら、デバイスはUSB仕様に従わないようです。最初の設定構成要求のみが機能します。 2番目の設定の構成を要求している間、デバイスがロックされ、最終的にクラッシュが発生しました。 USBリセットまたは設定リセット(0に設定)も役に立ちませんでした。
Linux USBコアは、何らかの理由でデバイス構成を無効な値に設定することに決めたようです(最初の値のみを選択)。そうする前に私が介入する機会はありません。カーネルモジュールとユーザー空間libusbドライバの両方で試しました。
usb_choose_configuration()
カーネルのソースコードを読むと、設定を選択する関数が通常のドライバにあるようです。/drivers/usb/core/generic.c。 trueを返すと、関数をスキップできることがわかりますが、usb_device_is_owned()
関数の結果にどのような影響があるのかわかりません。
USBドライバを追加するためにカーネル全体を再コンパイルする必要はありません。
私の質問は次のとおりです。
- ドライバーに制御を渡す前にシステムが構成を設定できないようにするにはどうすればよいですか。
- 最新のカーネルバージョンでは usbcore が組み込みモジュールなので交換できないようです。
usb_choose_configuration
汎用ドライバ(usbcoreの一部であるように見える)の機能をオーバーライドする他の方法はありますか? usb_device_is_owned()
デバイスが接続されたときにtrueを返すようにデバイスをどのように持つことができますか?
答え1
システムがデバイスの構成を設定しようとするのを防ぐ方法があるようです。ユーザースペースでも機能します。私は偶然発見したこの機能をカーネルに追加することを約束、幸いにも、いくつかのサンプルコードが含まれています。
ユーザー空間プログラムは、usb_device_is_owned()
デバイスファイルシステムを介してUSBハブの特定のポートの所有権を主張することによってtrueを返すことができます。
秘訣は次のとおりです。
unsigned int port = 2; // Just as an example
// Send request 24 of type 'U' (USB), which returns an unsigned int
unsigned int ioctl_id = _IOR('U', 24, unsigned int);
// fd is a file descriptor to the hub's file in the devfs
ioctl(fd, ioctl_id, &port);
USB サブシステムに対する一部の ioctl 要求に関する情報は、次の場所にあります。カーネル文書。完全なリストは以下で見ることができます。カーネルソースコード。 #定義はここ。
興味深いことに、システムはまだ構成0(構成リセット)の構成設定要求を送信します。