misc_register() 不检查名称是否存在于 /dev/

问题描述 投票:0回答:1

我是 Linux 内核/设备的新手,我尝试了以下实验:

  • 创建设备名为“mydev”的节点:

sudo mknod /dev/mydev c 100 101

  • 插入一个尝试注册名称为“mydev”的设备的 misc 模块:
// 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 内核如何检测到节点之间的名称冲突?

c linux linux-kernel driver linux-device-driver
1个回答
0
投票

政策规定用户空间对

/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()
函数忽略。

© www.soinside.com 2019 - 2024. All rights reserved.