web-dev-qa-db-ja.com

生データをUSBデバイスに書き込む方法

コンピュータに接続されているUSBデバイスに生データを書き込もうとしています。 Kali Linuxを使用していて、正しいファイルパス "/ dev/usb/003/013"を見つけました。しかし、データを書き込もうとするとエラーが発生します。

root@kali:~/usb# printf "test" > /dev/bus/usb/003/013
bash: printf: write error: Invalid argument

私も猫を使ってみました:

root@kali:~/usb# cat test > /dev/bus/usb/003/013 
cat: write error: Invalid argument

前のケースでは、ファイル「test」は存在し、データが含まれています。ファイル記述子があっても、システムがファイル記述子に書き込むことができないようです。

調査の結果、私はあなたが次のいずれかであるという結論に達しました。

A.デバイスとインターフェイスするUSB​​ドライバーが必要です。

B. SCSIパススルーを使用して、デバイスのエンドポイントに直接データを書き込みます。

私はUSBプログラミングの初心者で、試してみるのは面倒ですが、これまでにドライバーを作成したことがありません。アドバイスや助けをいただければ幸いです。

最初に試したように、生データをデバイスに書き込むことはできますか?そうでない場合、私に利用できるいくつかのオプションを説明できますか?

9
Brian Sizemore

USBデバイスは、単純にパイプで読み取りと書き込みを行うよりもはるかに複雑です。それらを操作するためのコードを記述する必要があります。カーネルドライバーを書く必要はありません。 http://libusb.info (néelibusb.org)および http://libusb.sourceforge.net/api-1. を参照してください。これはLinux、OSX、Windows、Android、OpenBSDなどで動作すると主張しています。MacOS Xでは、USBにアクセスできるユーザーレベルの関数が I/O Kit にあります。 Windowsでは、WinUSBを使用できる場合がありますが、複雑です。

USBのアーキテクチャを理解するのに役立つように一度描いた図は次のとおりです。

                 ╭──────────────────────────────────────╮
    ┌──────┐     │   device     ┌─────┐  ┌───────────┐  │
    │ Port ├──┐  │            ┌─┤ EP0 ├──┤ control   │  │
    └──────┘  │  │ ┌────────┐ │ └─────┘  │┌─────────┐│  │
              ├────┤addr = 2├─┤ ┌─────┐  ││         ││  │
              │  │ └────────┘ ├─┤ EP1 ├──┼┤interface││  │
              │  │            │ └─────┘  ││   #0    ││  │
              │  │            │ ┌─────┐  │├─────────┤│  │
              │  │            ├─┤ EP2 ├──┼┤         ││  │
              │  │            │ └─────┘  ││interface││  │
              │  │            │ ┌─────┐  ││   #1    ││  │
              │  │            └─┤ EP3 ├──┼┤         ││  │
              │  │              └─────┘  │└─────────┘│  │
              │  │                       └───────────┘  │
              │  ╰──────────────────────────────────────╯
              │
              │
              :

エグゼクティブサマリー:すべてのデバイスにはアドレス(O/Sによって割り当てられ、変更される可能性があります)と最大32個のエンドポイント(私は思う)があります。

デバイス内には、1つ以上の「インターフェース」があります。たとえば、ウェブカメラは「カメラ」インターフェースと「マイク」インターフェースを提供する場合があります。多機能プリンターはいくつかのインターフェースを提供します。

エンドポイント0はデバイスの制御と構成に使用され、その他はさまざまなインターフェイスにアクセスするために使用されます。各インターフェースには、ゼロ以上(通常はそれ以上)のエンドポイントがあります。

エンドポイントは、いくつかの転送タイプのいずれかになります。

  • コントロール転送は、デバイスのクエリと構成に使用されます。すべてのデバイスは、最小セットの制御ステートメントをサポートする必要があります。コントロール転送はエンドポイント0でのみ使用されると思います。
  • バルク転送は全帯域幅でデータを送受信します
  • 割り込み転送(これがバルク転送とどのように異なるのか本当にわかりません。USBには割り込みがありません)。例にはキーボードとマウスが含まれます
  • アイソクロナス転送は、リアルタイムの要件で全帯域幅でデータを送受信しますが、信頼性はありません。オーディオ/ビデオアプリケーションに使用されます。

また、注目に値します。USBデバイスは、使用可能なインターフェイスなどを制御する複数の構成を持つことができます。デバイス構成の変更は、デバイスを取り外し、代わりに別のデバイスを接続するのとほとんど同じです。

この情報はすべて、デバイス記述子、構成記述子、インターフェース記述子、エンドポイント記述子などに配置され、エンドポイントゼロを介して照会できます。

(内部的には、データはバイトのストリームではなく、USB仕様の一部である正確な形式のパケットにパックされています。ほとんどの場合、コントローラーとドライバーがこの部分を管理するので、これについて心配する必要はありません。君は。)

実際には、APIライブラリとオペレーティングシステムに応じて、デバイスを検出し、さまざまな記述子を読んで対処方法を見つけ、オプションでその構成を設定し(OSが許可する場合)、インターフェイスを開く必要があります。エンドポイントを開きます。

バルクエンドポイントの場合、未加工のデータを読み書きできます。コントロール転送の場合、APIライブラリは関数呼び出しを提供します。割り込みまたはアイソクロナス転送を使用したことがありません。きっとあなたのAPIライブラリには関連するドキュメントがあるでしょう。


詳細:「関数」は、連携して動作するインターフェースのコレクションです。これは元々USB仕様の一部ではなく、どのインターフェイスをグループ化するかを知るのはデバイスドライバーの責任です。 USBワーキンググループは、機能をサポートするデバイスクラスを定義しています。これは、Interface Association Descriptor(IAD)を介して行われます。

16
Edward Falk