IOCTL Linuxデバイスドライバ


0 Answers

ioctl関数は、デバイスドライバを実装してデバイスの設定を行うときに便利です。 例えば、プリンタには、フォント、フォントサイズなどをチェックして設定するための設定オプションがありますioctlは現在のフォントを取得し、フォントを別のフォントに設定するために使用できます。 ユーザーアプリケーションでは、 ioctlを使用してプリンタにコードを送信し、現在のフォントを返すか、新しいフォントにフォントを設定するよう指示します。

int ioctl(int fd, int request, ...)
  1. fdはファイル記述子で、open
  2. requestは要求コードです。 例えば、GETFONTはプリンタから現在のフォントを取得し、SETFONTはプリンタでフォントを設定します。
  3. 3番目の引数はvoid *です。 2番目の引数に応じて、3番目の引数が存在する場合と存在しない場合があります。 たとえば、2番目の引数がSETFONTの場合、3番目の引数はARIALとしてフォント名を与えることができます。

ですから、intリクエストは単なるマクロではなく、ユーザアプリケーションとデバイスドライバモジュールが、どのデバイスの設定を再生する必要があるのか​​を判断するためのリクエストコードを生成する必要があります。 ユーザアプリケーションからioctlを使用してリクエストコードを送信し、デバイスドライバモジュール内のリクエストコードを使用して、実行するアクションを決定します。

リクエストコードは4つの主要部分

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

リクエストコードがSETFONTでプリンタにフォントを設定する場合、データ転送の方向はユーザアプリケーションからデバイスドライバモジュールに向かいます。 ユーザーはプリンタにフォント名Arialを送信します。 リクエストコードがGETFONTの場合、プリンタからユーザーアプリケーションへの方向です。

リクエストコードを生成するために、Linuxはマクロのような事前定義された関数を提供します。

1. _IO(MAGIC, SEQ_NO)両方とも8ビット、0〜255です。例えば、プリンタを一時停止したいとしましょう。 これは、データ転送を必要としません。 そこで以下のようにリクエストコードを生成します

    #define PRIN_MAGIC 'P'
    #define NUM 0
    #define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

今度はioctl

    ret_val = ioctl(fd, PAUSE_PRIN);

ドライバモジュール内の対応するシステムコールがコードを受信し、プリンタを一時停止する。

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGICSEQ_NOは上記と同じですが、3番目の部分は次の引数の型を示しますSEQ_NOの3番目の引数はvoid *です。 __IOWは、データの方向がユーザーアプリケーションからドライバモジュールまでの方向であることを示します。 たとえば、フォントをArialに設定するようプリンタに指示しているとします。

    #define PRIN_MAGIC 'S'
    #define SEQ_NO 1
    #define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)
    

さらに、

    char *font = "Arial";
    ret_val = ioctl(fd, SETFONT, font); 

現在、 fontはポインタであり、 unsigned longとして最もよく表現されているアドレスなので、 _IOWの3番目の部分にはそのような型が_IOWています。 また、このフォントのアドレスは、デバイスドライバモジュールで実装されている対応するシステムコールにunsigned longとして渡され、使用前に適切な型にキャストする必要があります。 カーネルスペースはユーザースペースにアクセスすることができ、したがってこれは機能します。 マクロのような他の2つの関数は、 __IOR(MAGIC, SEQ_NO, TYPE)__IORW(MAGIC, SEQ_NO, TYPE)であり、データフローの方向はそれぞれカーネル空間からユーザ空間へと両方向になります。

これが役に立ったら教えてください!

Question

誰も私を説明することはできますか?

  1. IOCTLとは何ですか?
  2. それは何のために使われますか?
  3. どうすれば使えますか?
  4. IOCTLと同じ作業をする新しい関数を定義できないのはなぜですか?



Related