Linux如何将设备文件与设备驱动程序链接? open()syscall最终会调用设备驱动程序代码吗?

时间:2019-09-03 13:42:56

标签: c linux linux-kernel linux-device-driver device-driver

我对Linux设备文件和驱动程序有疑问,据我目前的理解如下:

  1. 当用户在某个设备文件上调用open()时,内核会在某个时间点向设备文件inode询问read() / write()功能。

  2. 设备文件由udev之前根据/sys文件夹中的设备创建,这意味着设备文件的inode应指向i_fop字段到知道如何与设备通话的功能,例如read()write()。这意味着每个设备文件的inode->i_fop字段应指向不同的file_operations结构。

如果是这样,设备驱动程序将提供这些read() / write()函数,也许提供完整的file_operations结构,包括读/写/ ioctl等。

现在,ULK说(在对设备文件的open()系统调用的描述中)“将i_fop对象的inode字段设置为def_blk_fops的地址或def_chr_fops文件操作表,具体取决于设备文件的类型。”这意味着所有块设备文件都具有相同的read() / write()函数,但是用户如何与不同设备对话?

我还检查了device_driver结构,实际上,没有位置存储文件访问功能,那么open() syscall如何使用设备特定的驱动程序执行其工作呢?设备专用的操作功能(如果不在device_driver中)存放在哪里?

2 个答案:

答案 0 :(得分:3)

以下内容适用于打开字符特殊设备。

打开文件时,来自inode对象的i_fop指针被复制到文件对象的f_op指针。对于特殊字符设备,它指向def_chr_fopsdef_chr_fops.open指向chrdev_open,因此打开任何字符特殊设备时都会调用chrdev_open(inode, filp)

chrdev_open浏览其已注册的struct cdev对象集,这些对象将索引节点的主要/次要数字(组合为dev_t)映射到特定的已注册struct cdev。如果找不到匹配的struct cdev,则返回-ENXIO。否则,它将用驱动器为特殊字符设备设置的f_op中的ops指针替换文件对象中的struct cdev指针。

如果文件对象的f_op->open不为空,则调用该文件对象,并由chrdev_open返回其返回值。否则,此特殊字符设备不需要特殊的“打开”处理,并返回0。

如果chrdev_open返回0,则文件对象处于“打开”状态,并且其f_op指针指向特定于驱动程序的文件操作。 open系统调用最终将返回文件描述符。如果chrdev_open返回负errno值,则文件对象将被销毁,open系统调用将返回-1,并且errno将根据来自chrdev_open的返回值进行设置。

答案 1 :(得分:1)

简短的回答,它知道根据大数和小数最终要调用哪个开放函数。注册驱动程序时,您可以提供这些文件或获取为您自动生成的文件,无论是字符,块还是tty。

udev或systemd或mdev还会发生的另一情况是,设备会自动在/dev下创建。在某些情况下,嵌入式发行版(例如buildroot)和角色设备不会自动发生,您需要手动执行操作。我建议检查“ Linux设备驱动程序,第三版,第3章:字符驱动程序”以获取更多详细信息。

相关问题