キャラクタ型ドライバ
キャラクタ型ドライバは単純なハードウェアに適している。
/dev中にある。
メジャー番号とマイナー番号
- メジャー番号:カーネルがデバイスに関係するドライバを識別。装置により、決まっているものがある。(例:
USB=180)
マイナー番号:カーネルは関知せず、ドライバ内で識別。
コンピュータに新しいドライバを追加=ドライバにメジャー番号を割り当てること
register_chrdev()でメジャー番号とジャンプテーブルを与える。
デバイスドライバの作成、登録方法のまとめ
1:モジュールをコンパイラ。
% gcc -O -c <ドライバ名>.c
2:スーパーユーザで、モジュールを登録。
# insmod <ドライバ名>.o
3:デバイスノードを
/dev内に作成。
# mknod -m 666 /dev/<ノード名> c <メジャー番号> <マイナー番号>
メジャー番号の動的割り当て
register_chrdev()でメジャー番号に0を与えると、空いている番号を返す。
すべてのドライバ関数はメジャー番号とマイナー番号を組み合わせた
inode->i_rdevを持つ。
MAJOR(inode->i_rdev)、MINOR(inode->i_rdev)
ファイル操作、ドライバは通常のファイル操作のようにデバイスを操作することができる。
file_operations構造体で、跳び先の関数を指定し、register_chrdev()で引き渡す。open()、write()、read()、ioctl()、close()に対応する関数
ファイル構造体_
struct file_operations
open
メソッド
- デバイス固有のエラーチェック、マイナー番号検査、初期化、利用度数を1増やす。(利用度数は、
MOD_INC_USER_COUNTで1増やす)
release
メソッド(なぜ closeを使わないのか?)
- メモリの解放、デバイスのシャットダウン、利用度数を1減らす。(利用度数は、
MOD_DEC_USER_COUNTで1減らす)
read
メソッド
- 戻り値:要求値に等しければ正常、小さければ未完了、ゼロなら
EOF、負ならエラー
write
メソッド
- 戻り値:要求値に等しければ正常、小さければ未完了、負ならエラー
サンプルプログラムは本書(オライリージャパン)の
Webページからたどれます。
キャラクタ型ドライバの高度な機能
ioctl
メソッド
read()、write()と違い、機器の設定などに使用される。
int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
cmd:コマンド、各デバイスごとに一意であった方がミス防止。
arg:設定データ、型チェックを行なわない。コピーにcopy_to/from_user()使用。直値の書き込みには使用しなくても良い。
I/O
のブロック
read()、write()で、データ転送未完了時にスリープなどで、プログラムが待たされる。
スリープと目覚め:
interruptible_sleep_on()、sleep_on()、wake_up_interruptible()、wake_up()
ドライバをリエントラントなコードで書く
待ち列
ブロック処理と非ブロック処理
select
メソッド
非同期通知
lseek
メソッド:デバイスを探す
デバイスファイルでアクセス制御
single-open:一度にただひとつのプロセスだけがデバイスをオープンできる。
一度にただひとりのユーザだけがデバイスをオープンできる。
ブロックオープン:オープン時に空くまで待たされる。
仮想デバイス:デバイスが特定のハードウェアでない場合、デバイスをクローンする。