Linux link 设备文件如何与设备驱动程序一起使用? open() 系统调用最终会调用设备驱动程序代码吗?
How does Linux link device file with device driver? Does open() syscall eventually call device driver code?
我有一个关于Linux设备文件和驱动程序的问题,我目前的理解如下:
当用户在某个设备文件上调用 open()
时,内核会在某个时间点向设备文件的 inode
请求 read()
/write()
函数。
设备文件是由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_fops
。 def_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 cdev
的 ops
指针,该指针由驱动程序为字符特殊设备设置。
如果文件对象的 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
.
的值
我有一个关于Linux设备文件和驱动程序的问题,我目前的理解如下:
当用户在某个设备文件上调用
open()
时,内核会在某个时间点向设备文件的inode
请求read()
/write()
函数。设备文件是由
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_fops
。 def_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 cdev
的 ops
指针,该指针由驱动程序为字符特殊设备设置。
如果文件对象的 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
.