IOCTL Linuxデバイスドライバー[終了]


126

誰かが私を説明できますか、

  1. なにIOCTL
  2. 何に使うの?
  3. どうすれば使用できますか?
  4. と同じように機能する新しい関数を定義できないのはなぜIOCTLですか?

回答:


99

ioctlデバイス固有のシステムコールの一種である手段「入出力制御」。Linuxのシステムコールはほんのわずか(300〜400)であり、デバイスが持つ可能性のあるすべての固有の機能を表現するには不十分です。そのため、ドライバーは、ユーザースペースアプリケーションがオーダーを送信できるようにするioctlを定義できます。ただし、ioctlはあまり柔軟ではなく、少し雑然とする傾向があります(機能する数十の「マジックナンバー」...かどうかにかかわらず)。また、カーネルにバッファを渡すと、安全性が低下する可能性があります。不適切な処理は失敗する可能性があります。物事は簡単に。

もう1つの方法は、ドライバーで情報を取得するためにsysfsファイルを設定して/sys/読み取り/書き込みを行うインターフェイスです。これを設定する方法の例:

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

そして、ドライバーのセットアップ中:

device_create_file(dev, &dev_attr_version);

次に/sys/、たとえば、/sys/block/myblk/versionブロックドライバー用のデバイス用のファイルを作成します。

より頻繁に使用するもう1つの方法はnetlinkです。これは、BSDソケットインターフェイスを介してドライバーと通信するためのIPC(プロセス間通信)メソッドです。これは、たとえばWiFiドライバーによって使用されます。次に、libnlまたはlibnl3ライブラリを使用して、ユーザー空間から通信します。


3
この答えは質問に部分的に「答え」ます。
Vishal Sahu

163

この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 request単なるマクロではありません。ユーザーアプリケーションは、要求コードとデバイスドライバーモジュールを生成して、デバイスのどの構成で操作する必要があるかを決定する必要があります。アプリケーションはを使用して要求コードを送信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)どちらも0〜255の8ビットです。たとえば、プリンタを一時停止したいとします。これはデータ転送を必要としません。したがって、以下のようにリクエストコードを生成します

#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) MAGICそしてSEQ_NO上記と同じであり、TYPE次の引数の型を与え、第三引数を思い出すioctlですvoid *。W in __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番目の部分はそのようなものです。また、このフォントのアドレスは、デバイスドライバーモジュールに実装されている対応するシステムコールに渡されるため、unsigned long 使用する前に適切なタイプにキャストする必要があります。カーネル空間はユーザー空間にアクセスできるため、これは機能します。他の二つの関数のようなマクロがある__IOR(MAGIC, SEQ_NO, TYPE)__IORW(MAGIC, SEQ_NO, TYPE)どこのデータフローは、それぞれカーネル空間からユーザ空間との両方の方法になります。

これが役立つかどうか私に知らせてください!


上記の__IOW、__ IOR、__ IORW関数が正しいかどうか疑問に思います(場合によっては、二重下線を使用することもあれば、使用しないこともあります。二重の下線を使用したことがありません)...明確な説明をありがとう!
jcoppens

非常によく説明されています。ありがとうございます!このioctlを使用するドライバー側の小さなコードスニペットを提供できますか?
アーディシュリ2018年

たとえば、opensourceforu.com
2011/08 / io

とてもよく説明されました。ありがとうございました。_IOWRではなく_IOWRだと思います
Mohamed Samy

ブログの投稿のように回答してください。
Fredrick Gauss
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.