我正在学习如何将字符设备驱动程序编写为Linux的动态可加载模块。通常,我使用以下函数调用序列来注册设备并创建一个显示在/dev/
下的设备文件:
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”会发生什么:
device_create(myclass, NULL, first, NULL, "null");
这导致/dev/null
被我的角色设备文件替换 - 更令人担忧的是:我的控制台中的一系列错误消息来自期望原始/dev/null
的守护进程。甚至没有删除我的虚假null
模块。
虽然在实践中不应该存在与我的模块使用的名称相同的现有设备文件,但理论上可以覆盖另一个设备文件这一事实仍然困扰着我。
如何防止已存在的设备文件与我打算使用的设备文件同名的情况?
更新:我想我真正想要找出的是为什么udev允许更换。
答案 0 :(得分:2)
所有设备驱动程序(在/dev
中找到)基本上都是文件类型,这意味着您检查设备文件是否已存在的方式与查看 any <的方式相同/ em>文件存在。一种方法是使用:
#include <unistd.h> // for F_OK and access()
...
if( access( "/dev/null", F_OK ) != -1 ) {
printf("File already exists!\n");
} else {
printf("File doesn't exist!\n");
// create new dev here
}
由于/dev/null
存在,您会看到“文件存在!”这里
答案 1 :(得分:1)
This resulted in /dev/null being replaced by my character device file
您可以使用mknod实用程序
创建新的NULL设备文件sudo mknod -m 0666 / dev / null c 1 3
答案 2 :(得分:0)
设备节点创建通常由用户空间操作处理。这是udev
的目的:通过解释/dev/
中的数据来填充和处理用户空间sysfm
目录。
传递给device_create
函数的名称只是sysfm
中显示的建议默认名称以及有关该设备的其他数据;最终由用户空间实用程序或用户决定如何处理该数据。
恰好udev
遇到具有相同名称的设备时的默认行为是用新设备节点覆盖旧设备节点:http://marc.info/?l=linux-hotplug&m=125559736630729