質問: ioctl linuxデバイスドライバー 誰も私を説明できますか、 ioctlとは何ですか? それは何に使用されますか? どうすれば使用できますか? ioctlと同じ動作をする新しい関数を定義できないのはなぜですか?
回答: ioctl関数は、デバイスドライバーを実装してデバイスの構成を設定するのに役立ちます。例えばフォントファミリ、フォントサイズなどを確認および設定するための設定オプションを備えたプリンタ。ioctlを使用して、現在のフォントを取得したり、フォントを新しいフォントに設定したりできます。ユーザーアプリケーションは、ioctlを使用して、現在のフォントを返すか、フォントを新しいフォントに設定するように指示するコードをプリンターに送信します。int ioctl(int fd, int request, ...) fdは、openによって返されるファイル記述子です。 requestは要求コードです。例:getfontはプリンターから現在のフォントを取得し、setfontはプリンターのフォントを設定します。 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)は両方とも8ビット、0〜255です。プリンターを一時停止したいとします。これにはデータ転送は必要ありません。以下のようにリクエストコードを生成します#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は上記と同じであり、typeは次の引数のタイプを示します。ioctlの3番目の引数はvoid *であることを思い出してください。 __iowのwは、データフローがユーザーアプリケーションからドライバーモジュールへのものであることを示します。例として、プリンターフォントを"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として渡され、使用する前に適切なタイプにキャストする必要があります。カーネル空間はユーザー空間にアクセスできるため、これは機能します。他の2つの関数のようなマクロは__ior(magic, seq_no, type)と__iorw(magic, seq_no, type)で、データフローはそれぞれカーネル空間からユーザー空間へ、そしてその両方の方向になります。これが役立つかどうか教えてください!