web-dev-qa-db-ja.com

このマクロの意味は何ですか_IOR(MY_MACIG、0、int)?

ioctlサンプルプログラムを調べて、カーネルスペースとの通信方法を確認していました。プログラムでは、WRITE_IOCTLがコマンドとして使用されます

_#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)
ioctl(fd, WRITE_IOCTL, "hello world")
_

_IOW(MY_MACIG, 1, int)とは何か理解できません。これが私がプログラムをダウンロードしたところからのリンクです。私を助けてください。 http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-4.html

14
Rafal

ご存知かもしれませんが、Linuxデバイスドライバーの本で説明されているように、ioctlは一意である必要があります。

Ioctlコマンド番号は、正しいコマンドを間違ったデバイスに発行することによって引き起こされるエラーを防ぐために、システム全体で一意である必要があります。このような不一致は起こりそうになく、プログラムは非FIFOまたはオーディオデバイスなどのシリアルポート入力ストリーム。各ioctl番号が一意である場合、アプリケーションは意図しない処理に成功するのではなく、EINVALエラーを受け取ります。

さらに、ioctlは、カーネルスペースへのデータの書き込みやカーネルスペースからのデータの読み取りを要求する場合があります。

Ioctlを実行する独自のドライバーを作成するときは、ioctlコマンドでこれらすべてを説明する必要があります。

_IO、_IOW、_IOR、_IORWは、一意のioctl識別子を作成し、必要なR/Wに必要な機能(方向)を追加するためのヘルパーマクロです。

これらは、次のパラメーターを取ることができます:マジック番号、コマンドID、および渡されるデータ型(存在する場合)

マジックナンバーは、LDDの本の引用に記載されているようなエラーをドライバーが検出できるようにする一意の番号です。

コマンドIDは、どのコマンドを呼び出す必要があるかをdirverが理解するための方法です。

最後のパラメーター(タイプ)は、カーネルがコピーされるサイズを理解できるようにします。

お役に立てれば。

PS:Linuxデバイスドライバーの本(第6章)で詳細を確認できます https://lwn.net/images/pdf/LDD3/ch06.pdf

15
Ayman Khamouma

http://www.circlemud.org/jelson/software/fusd/docs/node31.html から:

Linuxヘッダーファイル/usr/include/asm/ioctl.hは、ioctlコマンド番号を作成するために使用する必要があるマクロを定義します。これらのマクロは、次の3つの引数のさまざまな組み合わせを取ります。

  • type、デバイスドライバーに固有の8ビット整数。タイプは、同じファイル記述子を「リッスン」している可能性のある他のドライバと競合しないように選択する必要があります。 (たとえば、カーネル内では、TCPおよびIPスタックは異なる番号を使用します。これは、ソケットファイル記述子に送信されたioctlが両方のスタックによって検査される可能性があるためです。)
  • number、8ビット整数コマンド番号。ドライバー内では、ドライバーがサービスを提供するioctlコマンドの種類ごとに異なる番号を選択する必要があります
  • data_type、クライアントとドライバーの間で交換されるバイト数を計算するために使用される型の名前。この引数は、たとえば、構造の名前です。

コマンド番号の生成に使用されるマクロは次のとおりです。

  • _ IO(int type、int number)、タイプと数値のみを送信し、(整数)のみを受信する単純なioctlに使用されますretval
  • _ IOR(int type、int number、data_type)、デバイスドライバーからデータを読み取るioctlに使用されます。ドライバーは、sizeof(data_type)バイトをユーザーに返すことができます。
  • _ IOW(int type、int number、data_type)、_ IORに似ていますが、ドライバーへのデータの書き込みに使用されます
  • _ IORW(int type、int number、data_type)、_ IORと_IOWの組み合わせ。つまり、データはドライバーに書き込まれ、クライアントによってドライバーから読み取られます。