设备驱动程序中主要和次要数字的作用

Yog*_*R.L 7 linux file-io linux-device-driver linux-kernel

我正在学习Linux设备驱动程序并且卡在主要的次要数字上.到目前为止我所拥有的是:

  • 可以通过文件系统中的名称访问设备.这些名称称为特殊文件或设备文件或文件系统的inode.

  • 并且每个设备文件与捆绑在一个dev_t类型中的MAJOR和MINOR号相关联.

  • 这些数字由功能分配给设备 register_chrdev_region

有些问题令我不安......

  1. 当我们初始化设备时,fops结构是否链接到f_ops设备文件的文件结构字段cdev_init(&c_dev, &fops);
  2. 如何调用open("/dev/mydev", O_RONLY);实际调用open() 驱动程序的功能.这里是否有数字来查找设备驱动程序的实际写入方法,如果是,如何?
  3. 数字,major用于标识设备驱动程序和次要设备文件.当我们对设备文件open() read() write()等执行操作时,这个数字的实际作用是什么?

小智 10

我认为故事应该从你输入时发生的事情开始:

mknod /dev/c83 c 8 3
Run Code Online (Sandbox Code Playgroud)

它将调用ext2_mknod("/ dev","c83",CHAR,DEV(8,3)),大多数文件系统将mknod实现为init_special_inode的包装:

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);
}
Run Code Online (Sandbox Code Playgroud)

当你最后调用open("/ dev/c83")时,它将进入函数def_chr_fops.chrdev_open,它将用你在cdev_init()中注册的fops替换文件"/ dev/c83"的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;
 }
Run Code Online (Sandbox Code Playgroud)

之后,每个系统调用(如read/write/close)都直接转到cdev_init()中注册的函数指针!

所以,对于你的第一个问题:

  1. 是的,正如你在chrdev_open()中看到的那样.
  2. 是的,因为设备的fops与cdev_init中注册的设备完全相同
  3. 在open()中扮演重要角色,因为open()使用对来找到正确的设备驱动程序.但之后,其他文件操作,如read/write/close(),不再参与,一切都通过open()中解决的fops中的函数指针.