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

Linux 主要和次要数字在设备驱动程序中的作用,linux,file-io,linux-kernel,linux-device-driver,Linux,File Io,Linux Kernel,Linux Device Driver,我正在学习Linux设备驱动程序,并被困在大调、小调的数字上。到目前为止,我得到的是: 通过文件系统中的名称访问设备。那些名字 被称为特殊文件、设备文件或文件的索引节点 系统 并且每个设备文件都与绑定到dev\u t类型中的主数字和副数字相关联 这些编号由函数register\u chrdev\u region 有些问题仍然困扰着我 fops结构是否链接到文件结构的f_ops字段 初始化设备时的设备文件,如cdev_init(&c_dev,&fops) 如何打开对的调用(“/dev/myde

我正在学习Linux设备驱动程序,并被困在大调、小调的数字上。到目前为止,我得到的是:

  • 通过文件系统中的名称访问设备。那些名字 被称为特殊文件、设备文件或文件的索引节点 系统

  • 并且每个设备文件都与绑定到
    dev\u t
    类型中的主数字和副数字相关联

  • 这些编号由函数
    register\u chrdev\u region
有些问题仍然困扰着我

  • fops
    结构是否链接到文件结构的
    f_ops
    字段 初始化设备时的设备文件,如
    cdev_init(&c_dev,&fops)
  • 如何打开对
    的调用(“/dev/mydev”,通常)
    实际调用
    open()
    驱动程序的功能。这里有数字吗 要查找设备驱动程序的实际写入方法,如果是,如何查找
  • 数字,主要用于识别设备驱动程序和 次要设备文件。这些数字的实际作用是什么 当我们在设备文件上执行操作时,如
    open()
    read()
    write()

  • 我认为故事应该从你打字时发生的事情开始:

    mknod /dev/c83 c 8 3
    
    它将调用ext2_mknod(“/dev”,“c83”,CHAR,dev(8,3)),大多数文件系统将mknod实现为init_特殊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);
    }
    
    最后调用open(“/dev/c83”)时,它将进入函数def_chr_fops.chrdev_open,该函数将用您在cdev_init()中注册的fops替换文件“/dev/c83”的fops:

    之后,每个系统调用(如读/写/关闭)都直接进入在cdev_init()中注册的函数指针

    那么,关于你的第一个问题:

  • 是的,正如您在chrdev_open()中看到的
  • 是的,因为设备的FOP实际上与在cdev_init中注册的FOP相同
  • 在open()中起着重要作用,因为open()使用对来查找正确的设备驱动程序。但在那之后,其他文件操作,如read/write/close(),不再参与,所有操作都通过fops中的函数指针在open()中解析
  • 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;
     }