我正在学习编写一个简单的内核模块,该模块实现open, read, write, close, ioctl
的系统调用,用于在内核内存(类似共享内存/ IPC演示)中进行读/写操作。
我曾经打电话给mknod
来将驱动程序分配的主/副号码与字符文件绑定在一起。但是我问自己一个问题,为什么在将USB随身碟连接到系统时为什么不总是需要手动进行操作,所以发现udev
。
我知道如何使用kobject_init_and_add()
和kobject_uevent()
在sysfs
树中创建一个节点并通知udev
,但是在浏览/sys
文件夹时,我注意到/sys/dev/char
文件夹,其中包含指向设备的符号链接,名称为major:minor
。我不明白为什么在这里找不到我的主要/次要驱动程序...我应该在模块内部手动执行其他操作吗?
如何在sysfs树中找到一个完整而简单的示例来说明如何正确描述和处理我的“虚拟”设备?
答案 0 :(得分:2)
阅读 John Madieu 的“ Linux设备驱动程序开发”的第4章之后,我发现它比我想象的要简单:
要在/sys
和/dev
中自动实例化适当的字符设备抽象,您需要做的就是在struct class
函数的帮助下创建一个class_create(...)
,然后使用device_create(...)
。
效果:
假设您有一个名为my_class
的类,并用主号码my_device
和次要号码xx
调用设备yy
/sys/class/my_class
文件夹已创建; /sys/devices/virtual/my_class/my_device
文件夹已创建; /sys/class/my_class/my_device
符号链接指向/sys/class/my_class/my_device
; /sys/dev/char/xx:yy
符号链接指向/sys/class/my_class/my_device
; /dev/my_device
个字符设备已创建(因此不再进行mknod
个调用); /sys/class/my_class/my_device
文件夹非常有趣。它具有:
dev
文件:它包含major:minor
号; uevent
文件:如果在其中写入add
,内核将重新发出add
个uevents; uevents用于向诸如udev
之类的用户空间守护进程发出信号,以通知其在sysfs树中创建/修改/删除内核对象。 subsystem
符号链接:它指向/sys/class/my_class
; power
文件夹:可能有一些接口,例如this。始终记得在模块的退出功能中将每个* _create调用与* destroy调用进行匹配。
class_create
,class_destroy
,device_create
,device_destroy
在include/linux/device.h
中声明,并分别在drivers/base/class.c
和{{1 }}(内核源代码树中的路径)。这些源文件中有很好的文档。