8

私はLinuxデバイスドライバーを学んでいて、メジャー、マイナーの数で立ち往生しています。私がこれまでに持っているのは:

  • デバイスには、ファイルシステム内の名前を介してアクセスします。これらの名前は、特殊ファイル、デバイスファイル、またはファイルシステムのiノードと呼ばれます。

  • dev_tまた、各デバイスファイルは、タイプにバンドルされているMAJOR番号とMINOR番号に関連付けられています。

  • これらの番号は、機能によってデバイスに割り当てられますregister_chrdev_region

いくつかの質問はまだ私を悩ませています...

  1. 次のようにデバイスを初期化すると、構造はデバイスファイルのファイル構造のフィールドにfopsリンクされますか?f_opscdev_init(&c_dev, &fops);
  2. open("/dev/mydev", O_RONLY);toを呼び出すと、実際にopen() ドライバーの関数がどのように呼び出されますか。デバイスドライバの実際の書き込み方法を見つけるために、ここに数字が表示されていますか?はいの場合、どのようにですか?
  3. 番号、メジャーはデバイスドライバーを識別するために使用され、マイナーはデバイスファイルを識別するために使用されます。などのデバイスファイルで操作を実行するときのこの番号の実際の役割は何open() read() write()ですか?
4

1 に答える 1

11

ストーリーは、次のように入力したときに起こったことから始まるはずだと思います。

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()に登録されている関数ポインタに直接送信されます。

だから、あなたの最初の質問のために:

  1. はい、chrdev_open()に表示されているように。
  2. はい、デバイスのfopsはcdev_initに登録されているものと実際に同じなので
  3. open()はペアを使用して正しいデバイスドライバーを見つけるため、open()で重要な役割を果たします。しかしその後、read / write / close()などの他のファイル操作は再び参加せず、すべてがopen()で解決されたfopsの関数ポインターを通過します。
于 2013-01-29T15:00:19.483 に答える