moduleというと、open,close,read,writeは定番ですが、これらはストレージのようなブロックデバイスのアクセスには便利だけど、IOポートのような単発アクセスにはあまり向いてない.そこで存在するのがioctl()という関数であるらしい.
ユーザープログラムからioctl()をcallするときに、このような意味不明な引数を与えます.
ioctl( fd, _IOR('U', 20, 7), buf );
fdはopenした時に得たファイルディスクリプタなので理解できる.bufはデータの入れ物だろう.だがしかし、_IOR(...)って何ですかと.'U'って何ですかと.一体何をやりたいのと.
_IORはこのようにマクロ定義されています.(ioctl.h)
#define _IOR(type,num,size) _IOC(_IOC_READ,type,num,_IOC_TYPECHECK(size))
さらに_IOCというのが出てきちゃいましたがまとめると、type,num,sizeという3つの引数を、下記のように32bitにアサインしているみたいです.
33222222 22221111 11111100 00000000
10987654 32109876 54321098 76543210
** direction[1:0]
****** ******** size[13:0]
******** type[7:0]
******** num[7:0]
4つの数の意味はこうなってます.
・direction READ/WRITE
・size バイト数
・type 用途を示すマジックナンバー http://goo.gl/omKtYa
・num コマンドかなぁ
typeはmodule識別子のようです.リンク先には様々なmoduleがアサインされています.module自作の際には重複を避けるべきだそうです.(fdでmoduleを指定するのでtypeの重要さは低いように思うんだがどうだろ)
つまり、ioctl()の引数は事実上はこのようにたくさんあるのです.
ioctl( fd, direction, size, type, num, buf );
だったら最初からこうしとけばいいのにと思います.なお練習用プログラムでは_IORに従わない例もあります.
第2引数の_IORは以上のようにbitアサインしているわけですが、direction, size, type, num, bufをどう処理するのかは専らmodule次第であって、統一された処理法は存在しないようです.
moduleのソースコードには、このような定義が山のように記述されていて、switch-case文でブリブリと分岐させて各種処理を行っているのが見られます.
#define BNEPGETCONNLIST _IOR('B', 210, int )
#define BNEPGETCONNINFO _IOR('B', 211, int )
#define CMTPGETCONNLIST _IOR('C', 210, int )
#define CMTPGETCONNINFO _IOR('C', 211, int )
かしこ
人気ブÍグランキングへ
0 件のコメント:
コメントを投稿