【问题标题】:device_create with existing device name使用现有设备名称的 device_create
【发布时间】:2013-03-15 13:24:00
【问题描述】:

我正在学习如何将字符设备驱动程序编写为 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 允许替换。

【问题讨论】:

    标签: c linux linux-kernel linux-device-driver device-driver


    【解决方案1】:

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

    #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确实存在,你会看到“文件存在!”这里

    【讨论】:

    • 当我尝试在我的模块中使用access 时,gcc 会吐出:error: implicit declaration of function 'access'。我有#include &lt;linux/unistd.h&gt;,所以我不确定我错过了什么。
    • 事实证明,从内核中访问用户空间文件通常是不好的做法:kernelnewbies.org/FAQ/WhyWritingFilesFromKernelIsBad
    • @VilhelmGray - 是的,很抱歉,我正在考虑检查表单用户空间是否存在 /dev/。查看此问题已接受答案中的链接:stackoverflow.com/questions/275386/… 可以从内核访问文件系统,然后执行access() 所做的事情,或者甚至尝试open() 一个特定的 /dev 来检查它的存在......应该有更好的方法,但我需要考虑一下
    • 也许最好的做法是在内核中注册设备,然后实现一个用户态初始化脚本,在执行 mknod 创建设备节点之前检查是否有任何文件名冲突。但话又说回来,这让我想知道为什么 udev 一开始就不执行这样的基本检查。
    【解决方案2】:
    This resulted in /dev/null being replaced by my character device file
    

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

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

    【讨论】:

      【解决方案3】:

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

      传递给device_create 函数的名称只是出现在sysfm 中的建议默认名称以及有关设备的其他数据;最终由用户空间实用程序或用户来决定如何处理这些数据。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-02
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        • 2015-07-14
        相关资源
        最近更新 更多