我是 Linux 内核/设备的新手,我尝试了以下实验:
sudo mknod /dev/mydev c 100 101
// misc_hello.c
static struct miscdevice helloworld_miscdevice = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mydev",
.fops = &my_dev_fops,
};
static int __init hello_init(void)
{
int ret_val;
ret_val = misc_register(&helloworld_miscdevice);
// ret_val is 0 so the device is registered succesfully
执行
insmod misc_hello.ko
后,我在dmesg
中没有看到任何错误。当我使用 ls /dev/ | grep mydev
检查设备时,我看到 dev/mydev/
节点是之前使用 mknode
命令手动创建的节点。如果sysfs
发现有另一个同名的设备节点,模块注册不应该失败吗? Linux 内核如何检测到节点之间的名称冲突?
政策规定用户空间对
/dev
的内容负有最终责任,即使动态填充也是如此。
如果支持 devtmpfs 文件系统(自内核版本 2.6.32 起通过
CONFIG_DEVTMPFS
选项),内核将尝试填充它,但它不关心是否无法创建设备节点,就像它一样不关心 devtmpfs 文件系统是否挂载。挂载后,devtmpfs 文件系统的内容可以随时被用户空间(例如udevd)修改。正如它在原始commit中所说:
Devtmpfs 可以由用户空间在任何时间以任何需要的方式更改和改变——就像今天的 udev-mounted tmpfs 一样。未修改的 udev 版本将在其上运行得很好,并将识别一个已经存在的内核创建的设备节点并使用它。默认节点权限为 root:root 0600。适当的权限和用户/组所有权、有意义的符号链接、所有其他策略仍需要由用户空间应用。
如果节点是由devtmps创建的,devtmpfs会在设备消失时移除该设备节点。如果设备节点是由用户空间创建的,或者 devtmpfs 创建的节点被用户空间替换,它将不再被 devtmpfs 删除。
如果
/dev
挂载为tmpfs而不是devtmpfs,内核根本不会填充它,但它仍然可以由用户空间填充(例如由udevd)。
内核自动创建设备节点是通过
devtmpfs_create_node(dev);
函数调用device_add()
完成的,自动删除是通过devtmpfs_delete_node(dev);
函数调用device_del()
完成的。尽管 devtmpfs_create_node()
和 devtmpfs_delete_node()
函数在出错时返回负错误数,调用这些函数的返回值会被 device_add()
和 device_del()
函数忽略。