誰か説明してくれませんか
- とは
IOCTL
? - それは何のために使用されますか?
- どのように使用できますか?
- と同じ働きをする新しい関数を定義できないのはなぜ
IOCTL
ですか?
誰か説明してくれませんか
IOCTL
?IOCTL
ですか?このioctl
関数は、デバイス ドライバを実装してデバイスの構成を設定する場合に役立ちます。たとえば、フォント ファミリ、フォント サイズなどを確認および設定する構成オプションを持つプリンタをioctl
使用して、現在のフォントを取得したり、フォントを新しいフォントに設定したりできます。ユーザー アプリケーションはioctl
、現在のフォントを返すか、フォントを新しいフォントに設定するように指示するコードをプリンターに送信するために使用します。
int ioctl(int fd, int request, ...)
fd
によって返されるファイル記述子open
です。request
リクエストコードです。たとえばGETFONT
、プリンタから現在のフォントを取得し、プリンタにSETFONT
フォントを設定します。void *
です。2 番目の引数に応じて、3 番目の引数が存在する場合と存在しない場合があります。たとえば、2 番目の引数が の場合、3 番目の引数は;SETFONT
などのフォント名になります。"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);
ドライバー モジュール内の対応するシステム コールがコードを受け取り、プリンターを一時停止します。
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
とSEQ_NO
は上記と同じで、次の引数の型を与えます。 isTYPE
の 3 番目の引数を思い出してください。W inは、データ フローがユーザー アプリケーションからドライバー モジュールへのものであることを示します。例として、プリンターのフォントを に設定したいとします。ioctl
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
表現されるアドレスであることを意味します。また、このフォントのアドレスは、デバイス ドライバー モジュールに実装されている対応するシステム コールに渡されるため、 使用する前に適切な型にキャストする必要があります。カーネル空間はユーザー空間にアクセスできるため、これは機能します。他の 2 つの関数のようなマクロは、データ フローがカーネル空間からユーザー空間へ、およびその両方である場所です。unsigned long
_IOW
unsigned long
__IOR(MAGIC, SEQ_NO, TYPE)
__IORW(MAGIC, SEQ_NO, TYPE)
これが役立つかどうか教えてください!
ioctl
「入出力制御」を意味する は、デバイス固有のシステム コールの一種です。Linux にはわずかなシステム コール (300 ~ 400) しかなく、デバイスが持つ固有の機能をすべて表現するには不十分です。したがって、ドライバーは、ユーザー空間アプリケーションが注文を送信できるようにする ioctl を定義できます。ただし、ioctl はあまり柔軟ではなく、少し雑然とする傾向があり (何十もの "マジック ナンバー" が機能するかどうかに関係なく)、カーネルにバッファーを渡すと安全性が低下する可能性もあります。簡単に物事。
別の方法は、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
ライブラリを使用してユーザー空間から通信します。