我正在学习编写一个简单的内核模块,该模块实现open、read、write、close、ioctl
系统调用以在内核内存中进行读/写(类似于共享内存/IPC 演示)。
我曾经调用mknod
将驱动程序分配的主次编号绑定(bind)到一个字 rune 件中。但我问自己为什么我们在将 USB 随身碟连接到系统时并不总是需要手动这样做,我发现了 udev
。
我知道如何使用 kobject_init_and_add()
和 kobject_uevent()
在 sysfs
树中创建一个节点并通知 udev
,但是在浏览 /sys
文件夹时,我注意到 /sys/dev/char
文件夹,其中包含指向设备的符号链接(symbolic link),命名为 major:minor
。我不明白为什么我在这里找不到我的驱动程序的主要/次要夫妇......我是否应该从模块内部手动执行其他操作?
如何找到一个完整但简单的示例来说明如何在 sysfs 树中正确描述和处理我的“虚拟”设备?
最佳答案
看完John Madieu的《Linux设备驱动程序开发》第四章后,我发现它比我想象的要简单:
为了在 /sys
和 /dev
中自动实例化适当的字符设备抽象,您需要做的就是创建一个 struct class
借助class_create(...)
函数,然后使用device_create(...)
。
效果:
假设您有一个名为 my_class
的类,并使用主编号 xx
和次编号 yy
调用设备 my_device
,
/sys/class/my_class
文件夹已创建;/sys/devices/virtual/my_class/my_device
文件夹已创建;/sys/class/my_class/my_device
符号链接(symbolic link)指向/sys/class/my_class/my_device
;/sys/dev/char/xx:yy
符号链接(symbolic link)指向/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
符号链接(symbolic link):它指向/sys/class/my_class
;power
文件夹:可能是一些接口(interface),比如 this .
始终记得在模块的退出函数中将每个 *_create 调用与 *destroy 调用相匹配。
class_create
, class_destroy
, device_create
, device_destroy
声明在include/linux/device.h
,分别定义在drivers/base/class.c
和drivers/base/core.c
(内核源码树中的路径)。这些源文件中有很好的文档。
关于linux -/sys/dev/char 如何在 Linux 中填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53308573/