我能从我的内核模块中调用mknod吗?

3
正如标题所述,我正在编写一个内核模块,并希望该模块创建的字符设备能够自动显示。我可以在module_initmodule_exit中使用mknodrm来创建和删除设备吗?
编辑:不确定是否允许,但作为问题的扩展,我在哪里可以找到更多类似的信息?我的大多数谷歌搜索要么非常令人困惑,要么是非常老的信息(2.6及更早版本的内核),学习编写内核模块的最佳地方是哪里?

1
这看起来不是一个好主意。相反,写一些udev规则会更好。 - undefined
相反,你应该看看其他模块是如何做的,以及它们如何实现类似的结果。 - undefined
@Lazlo Valko 究竟是哪些? - undefined
@n.m. 有没有办法以编程的方式来实现这个?我希望能够在用户不需要做任何工作的情况下完成这个任务。 - undefined
我会检查USB串行端口,例如。 - undefined
当然,你可以将udev规则放在一个文件中,并让你的软件包/安装程序/等等将其放置在/lib/udev/rules.d或者是特定发行版中的标准位置。 - undefined
1个回答

5
不,您不能在内核空间使用mknod和rm cli。这些是bash命令。但是,有其他选项可用于从内核空间创建和删除模块的设备节点文件。在模块init函数中进行设备注册后,您可以使用class_create()函数和device_create()函数来创建节点文件。在cdev_init()调用后,您可以使用这两个函数来进行节点文件创建。同样,您可以在module_exit函数中使用device_destroy()和class_destroy()函数来删除节点文件。
以下是在char设备init函数中创建/dev/kmem的示例代码:
int majorNum;
dev_t devNo;  // Major and Minor device numbers combined into 32 bits
struct class *pClass;  // class_create will set this

static int __init devkoInit(void) {
  struct device *pDev;

  // Register character device
  majorNum = register_chrdev(0, "devko", &fileOps);
  if (majorNum < 0) {
    printk(KERN_ALERT "Could not register device: %d\n", majorNum);
    return majorNum;
  }
  devNo = MKDEV(majorNum, 0);  // Create a dev_t, 32 bit version of numbers

  // Create /sys/class/kmem in preparation of creating /dev/kmem
  pClass = class_create(THIS_MODULE, "kmem");
  if (IS_ERR(pClass)) {
    printk(KERN_WARNING "\ncan't create class");
    unregister_chrdev_region(devNo, 1);
    return -1;
  }

  // Create /dev/kmem for this char dev
  if (IS_ERR(pDev = device_create(pClass, NULL, devNo, NULL, "kmem"))) {
    printk(KERN_WARNING "devko.ko can't create device /dev/kmem\n");
    class_destroy(pClass);
    unregister_chrdev_region(devNo, 1);
    return -1;
  }
  return 0;
} // end of devkoInit


static void __exit devkoExit(void) {
  // Clean up after ourselves
  device_destroy(pClass, devNo);  // Remove the /dev/kmem
  class_destroy(pClass);  // Remove class /sys/class/kmem
  unregister_chrdev(majorNum, DEVICE_NAME);  // Unregister the device
} // end of devkoExit

1
抱歉,但我无法理解你的意思。所以为了澄清,在我的init函数中,我会调用alloc_chrdev_region,然后使用class_create(),接着是device_create(),之后我会调用cdev_init()cdev_add(),这样就能在我的/dev文件夹中创建一个字符设备文件了吗? - undefined
是的。请参考下面的示例驱动代码。对我来说完全可行。 class = class_create(THIS_MODULE, "YYY"); if(IS_ERR(class)) {printk(KERN_WARNING "\n无法创建类"); unregister_chrdev_region(dev, 1); return -1; } if(IS_ERR(dev_ret = device_create(class, NULL, dev, NULL, "scull-1"))) {printk(KERN_WARNING "\n无法创建设备"); class_destroy(class); unregister_chrdev_region(dev, 1); return -1; } scull_setup_cdev(&pdev, 1); - undefined
1
这个答案完美地解决了问题,不过如果能提供一些解释和更多资源的来源就更好了。我发现这是一个可以在这里找到的 scull 代码片段:https://github.com/cmaiolino/scull-driver,同时这本书也可以在这里找到:https://lwn.net/Kernel/LDD3/,如果有人想要添加更多内容,那将会很棒。另外,我想知道这些信息是否可以在内核文档中找到,但我个人找不到任何相关内容。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接