关于具有现有设备名称的c:device_create

device_create with existing device name

我正在学习如何将字符设备驱动程序编写为Linux的可动态加载的模块。通常,我使用以下函数调用序列来注册设备并创建一个出现在/dev/下的设备文件:

1
2
3
4
5
alloc_chrdev_region(&first, 0, 1,"myclass");
myclass = class_create(THIS_MODULE,"myclass");
device_create(myclass, NULL, first, NULL,"mydevicefile");
cdev_init(&c_dev, &fops);
cdev_add(&c_dev, first, 1);

该设备文件然后出现在/dev/mydevicefile上,我可以与它进行交互。

这让我想知道如果传递现有的设备文件名而不是" mydevicefile"会发生什么:

1
device_create(myclass, NULL, first, NULL,"null");

这导致/dev/null被我的字符设备文件替换-还有更多有关的问题:期望原始/dev/null的守护进程在我的控制台中发出了错误消息。甚至没有删除我的人造null模块即可解决此问题。

在实践中,不应该存在与我的模块使用的设备名称相同的现有设备文件,但从理论上讲,可以覆盖另一个设备文件这一事实仍然困扰着我。

如何防止设备文件已经存在与我要使用的文件名相同的情况?

更新:我想我真正想找出的是为什么udev允许替换。


所有设备驱动程序(位于/dev中)基本上都是文件类型,这意味着检查设备文件是否已存在的方式与检查文件是否存在的方式相同。一种方法是使用:

1
2
3
4
5
6
7
8
9
10
11
12
#include <unistd.h>  // for F_OK and access()

...

if( access("/dev/null", F_OK ) != -1 ) {
    printf("File already exists!\
"
);
} else {
    printf("File doesn't exist!\
"
);
    // create new dev here
}

由于/dev/null确实存在,因此您会在此处看到"文件存在!"


1
This resulted in /dev/null being replaced by my character device file

您可以使用mknod实用程序创建一个新的NULL设备文件

sudo mknod -m 0666 /dev/null c 1 3


设备节点的创建通常由用户空间操作处理。这是udev的目的:通过解释sysfm中的数据来填充和处理用户空间/dev/目录。

传递给device_create函数的名称只是一个建议的默认名称,它与有关该设备的其他数据一起出现在sysfm中。最终由用户空间实用程序或用户决定如何处理该数据。

udev遇到相同名称的设备时,默认行为是用新设备节点覆盖旧设备节点:http://marc.info/?l=linux-hotplug