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

iibxawm4  于 2023-04-29  发布在  Linux
关注(0)|答案(2)|浏览(150)

我有一个关于Linux设备文件和驱动程序的问题,我目前的理解如下:
1.当用户在某个设备文件上调用open()时,在某个时间点,内核将向设备文件的inode请求read()/write()函数。
1.设备文件是由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()系统调用的描述中)“根据设备文件的类型,将inode对象的i_fop字段设置为def_blk_fopsdef_chr_fops文件操作表的地址。“这意味着所有块设备文件都具有相同的read()/write()功能,但用户如何与不同的设备进行对话?
我还检查了device_driver结构,确实没有地方存储文件访问函数,那么open()系统调用如何使用设备特定的驱动程序执行其工作呢?如果不在device_driver中,那么设备特定的操作功能在哪里?

6kkfgxo0

6kkfgxo01#

以下内容适用于开启字符专用设备。
当文件打开时,inode对象的i_fop指针被复制到文件对象的f_op指针。对于字符特殊设备,它指向def_chr_fopsdef_chr_fops.open指向chrdev_open,因此在打开任何字符专用设备时调用chrdev_open(inode, filp)
chrdev_open查看其注册的struct cdev对象集,这些对象将inode的主/次编号(组合成dev_t编号)Map到特定的注册struct cdev。如果没有找到匹配的struct cdev,则返回-ENXIO。否则,它会用struct cdev中的ops指针替换文件对象中的f_op指针,该指针由驱动程序为字符特殊设备设置。
如果文件对象的f_op->open非空,则调用它,并由chrdev_open返回其返回值。否则,对于该字符特殊设备不需要特殊的“打开”处理,并且返回0。
如果chrdev_open返回0,则文件对象处于“打开”状态,其f_op指针指向驱动程序特定的文件操作。open系统调用最终将返回一个文件描述符。如果chrdev_open返回负的errno值,则文件对象将被销毁,open系统调用将返回-1,errno将根据chrdev_open的返回值设置。

bf1o4zei

bf1o4zei2#

简单地说,它知道最终根据主函数和次函数调用哪个打开函数。您提供这些或获得自动生成的为您当您注册您的驱动程序,无论是字符,块或tty。
udev或systemd或mdev还会自动在/dev下创建设备。有一些情况下使用嵌入式发行版(e.例如buildroot)和字符设备,这不会自动发生,你需要手动完成。我建议查看“Linux Device Drivers,3rd edition,Chapter 3:Char Drivers”以了解更多详细信息。

相关问题