ストーリーは、次のように入力したときに起こったことから始まるはずだと思います。
mknod /dev/c83 c 8 3
ext2_mknod( "/ dev"、 "c83"、CHAR、DEV(8、3))を呼び出します。ほとんどのファイルシステムは、init_special_inodeのラッパーとしてmknodを実装します。
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
inode->i_mode = mode;
if (S_ISCHR(mode)) {
inode->i_fop = &def_chr_fops;
inode->i_rdev = rdev;
} else if (S_ISBLK(mode)) {
inode->i_fop = &def_blk_fops;
inode->i_rdev = rdev;
} else if (S_ISFIFO(mode))
inode->i_fop = &def_fifo_fops;
else if (S_ISSOCK(mode))
inode->i_fop = &bad_sock_fops;
else
printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n",
mode);
}
最後にopen( "/ dev / c83")を呼び出すと、関数def_chr_fops.chrdev_openに入り、ファイル "/ dev / c83"のfopsがcdev_init()に登録されているfopsに置き換えられます。
int chrdev_open(struct inode * inode, struct file * filp)
{
struct cdev *p;
...
p = inode->i_cdev;
...
filp->f_op = fops_get(p->ops);
...
if (filp->f_op->open) {
lock_kernel();
ret = filp->f_op->open(inode,filp);
unlock_kernel();
}
...
return ret;
}
その後、読み取り/書き込み/クローズなどのすべてのシステムコールは、cdev_init()に登録されている関数ポインタに直接送信されます。
だから、あなたの最初の質問のために:
- はい、chrdev_open()に表示されているように。
- はい、デバイスのfopsはcdev_initに登録されているものと実際に同じなので
- open()はペアを使用して正しいデバイスドライバーを見つけるため、open()で重要な役割を果たします。しかしその後、read / write / close()などの他のファイル操作は再び参加せず、すべてがopen()で解決されたfopsの関数ポインターを通過します。