Linux 中的字符设备驱动程序 Read/Write

Character Device Driver Read/Write in Linux

我写了一个字符设备驱动程序,我相信它应该可以工作。

我想测试 read/write 功能。在另一个堆栈溢出问题上,显然这可以通过写入 /dev 中的设备文件并回显输出来完成。

我不明白这是怎么回事:

当我通过分配主编号并调用 mknod 创建文件来加载我的设备驱动程序时,文件 "open"?如果它没有打开,那么 reading/writing 不应该像命令行那样工作,或者我是这么想的?

设备驱动程序在 /proc/devices 中初始化并在 /dev 中创建文件时处于什么状态?

是否需要在尝试在 c 程序中打开设备文件之前进行此初始化?

这些答案在网上很难找到,而且很多资源都已经过时了。谢谢

一个很好的资源是 Linux device driver. A shorter and simpler explanation can be found here

当你创建一个文件驱动程序时,你将在文件操作(fops)中实现一些功能:

  • open
  • close
  • read
  • write
  • seek
  • ...

并非所有功能都必须实现。例如,如果 write 未实现,您的设备将不支持写入。

When I load up my device driver by allocating a major number and calling mknod to create the file, is the file "open"?

创建 /dev 文件后,您的模块仅 已初始化 。像init_module这样的函数被调用

删除文件后,您的模块将deinited。调用了类似 module_cleanup 的函数。

What state is the device driver in when it has been initialized in /proc/devices and a file created in /dev?

在那种情况下,模块被初始化,文件没有打开。

If it isn't open, then reading/writing shouldn't work like that from the command line, or so I thought?

当您从命令行读取文件时,文件会打开、读取然后关闭,作为用户,您不必显式关心 open/close 文件。

如果您是 C 程序员,情况就不同了,在那种情况下,您必须明确地打开、读取、关闭文件。

您可以检查在您的内核代码中添加跟踪(使用 printk 将一些信息打印到内核控制台,使用 dmesg 读取它)或使用 strace 来跟踪系统调用。

Does this initialization need to happen before attempting to open the device file in a c program?

让我们继续:

  • 调用的第一个函数将在module_init被调用之前,文件不存在于/dev
  • 调用后最后调用的函数是module_cleanup,文件不存在/dev
  • 在init和cleanup之间,可以调用不同的openclosereadwrite函数。 一般在openclose之间调用read/write