Linux link 设备文件如何与设备驱动程序一起使用? open() 系统调用最终会调用设备驱动程序代码吗?

How does Linux link device file with device driver? Does open() syscall eventually call device driver code?

我有一个关于Linux设备文件和驱动程序的问题,我目前的理解如下:

  1. 当用户在某个设备文件上调用 open() 时,内核会在某个时间点向设备文件的 inode 请求 read()/write()函数。

  2. 设备文件是由udev早先根据/sys文件夹中的设备创建的,也就是说设备文件的inode应该有i_fop 字段指向知道如何与设备对话的函数,例如 read/write/mmap/ioctl/poll。这意味着每个设备文件的 inode->i_fop 字段应该指向不同的 file_operations 结构。

如果是这样,设备驱动程序将提供这些 read()/write() 函数,可能是完整的 file_operations 结构,包括 read/write/mmap/ioctl

现在,ULK 说(在设备文件的 open() 系统调用的描述中)"sets the i_fop field of the inode object to the address of either the def_blk_fops or the def_chr_fops file operation table, according to the type of device file." 这意味着所有块设备文件都具有相同的 read()/write()功能,但用户如何与 不同的 设备通话?

我还检查了 device_driver 结构,确实没有地方可以存储文件访问函数,那么 open() 系统调用究竟是如何使用设备特定驱动程序执行其工作的呢?如果不在 device_driver?

中,设备特定的操作功能在哪里?

简答,它根据主从号知道最终调用哪个open函数。您提供这些或在您注册驱动程序时自动为您生成这些驱动程序,无论是字符、块还是 tty。

udev 或 systemd 或 mdev 的另外一个变化是在 /dev 下自动创建一个设备。在某些情况下,嵌入式发行版(例如 buildroot)和字符设备不会自动发生,您需要手动执行。我建议查看 "Linux Device Drivers, 3rd edition, Chapter 3: Char Drivers" 了解更多详情。

以下适用于开启角色特殊装置

打开文件时,inode 对象的 i_fop 指针被复制到文件对象的 f_op 指针。对于字符特殊设备,这指向 def_chr_fopsdef_chr_fops.open指向chrdev_open,所以chrdev_open(inode, filp)在打开任何字符特殊设备时调用

chrdev_open 查看其已注册的 struct cdev 对象集,这些对象将索引节点的 major/minor 编号(组合成 dev_t 编号)映射到特定的已注册 struct cdev.如果没有找到匹配的 struct cdev,它 returns -ENXIO。否则,它将文件对象中的 f_op 指针替换为来自 struct cdevops 指针,该指针由驱动程序为字符特殊设备设置。

如果文件对象的 f_op->open 不为空,则调用它并且其 return 值由 chrdev_open 编辑 return。否则,此字符特殊设备不需要特殊 "open" 处理,0 是 returned.

如果chrdev_open returns 0,文件对象处于"open"状态并且它的f_op指针指向特定于驱动程序的文件操作。 open 系统调用最终将 return 一个文件描述符。如果 chrdev_open return 是负的 errno 值,文件对象将被销毁,open 系统调用将 return -1 并且 errno 将根据return 来自 chrdev_open.

的值