/sys/dev/char 如何填充到 Linux 中?
How does /sys/dev/char get populated in Linux?
我正在学习编写一个简单的内核模块,在内核内存中为 reading/writing 实现 open, read, write, close, ioctl
系统调用(类似于共享内存/IPC 演示)。
我曾经调用mknod
将驱动分配的major/minor号绑定到一个字符文件中。但我问自己为什么我们在将 USB 随身碟连接到系统时并不总是需要手动这样做,我发现 udev
.
我知道如何使用 kobject_init_and_add()
和 kobject_uevent()
在 sysfs
树中创建一个节点并通知 udev
,但是在浏览 /sys
文件夹时我注意到 /sys/dev/char
文件夹,其中包含指向设备的符号链接,名称类似于 major:minor
。我不明白为什么我在这里找不到我的 major/minor 一对驱动程序...我是否应该从模块内部手动执行其他操作?
如何在 sysfs 树中找到关于如何正确描述和处理我的 "virtual" 设备的完整但简单的示例?
阅读 John Madieu 的“Linux 设备驱动程序开发”的第 4 章后,我发现它更容易比我想的还要多:
为了在 /sys
和 /dev
中自动实例化适当的字符设备抽象,您需要做的就是在 class_create(...)
函数的帮助下创建一个 struct class
,然后使用 device_create(...)
.
效果:
假设您有一个名为 my_class
的 class 并使用主号码 xx
和次号码 yy
、
调用设备 my_device
/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 树中内核对象的 creation/modification/removal;
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
中分别定义和 drivers/base/core.c
(内核源代码树中的路径)。这些源文件中有很好的文档。
我正在学习编写一个简单的内核模块,在内核内存中为 reading/writing 实现 open, read, write, close, ioctl
系统调用(类似于共享内存/IPC 演示)。
我曾经调用mknod
将驱动分配的major/minor号绑定到一个字符文件中。但我问自己为什么我们在将 USB 随身碟连接到系统时并不总是需要手动这样做,我发现 udev
.
我知道如何使用 kobject_init_and_add()
和 kobject_uevent()
在 sysfs
树中创建一个节点并通知 udev
,但是在浏览 /sys
文件夹时我注意到 /sys/dev/char
文件夹,其中包含指向设备的符号链接,名称类似于 major:minor
。我不明白为什么我在这里找不到我的 major/minor 一对驱动程序...我是否应该从模块内部手动执行其他操作?
如何在 sysfs 树中找到关于如何正确描述和处理我的 "virtual" 设备的完整但简单的示例?
阅读 John Madieu 的“Linux 设备驱动程序开发”的第 4 章后,我发现它更容易比我想的还要多:
为了在 /sys
和 /dev
中自动实例化适当的字符设备抽象,您需要做的就是在 class_create(...)
函数的帮助下创建一个 struct class
,然后使用 device_create(...)
.
效果:
假设您有一个名为 my_class
的 class 并使用主号码 xx
和次号码 yy
、
my_device
/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 树中内核对象的 creation/modification/removal;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
中分别定义和 drivers/base/core.c
(内核源代码树中的路径)。这些源文件中有很好的文档。