我刚开始探索Linux角色设备驱动程序。我已经制作了一个简单的内核模块,我在其中使用register_chrdev()函数注册设备。我已将0作为参数传递给函数,内核返回可用的免费主编号。 之后我使用mknod命令创建一个带有返回主编号的字符设备文件,我成功地做到了。 我已将驱动程序加载到内核中,驱动程序,设备文件和用户空间应用程序之间的通信正常。
问题是当我重启系统时,/ dev目录中没有字符设备文件(使用mknod创建)。
因此,请建议解决此问题的方法,以便即使重启后我的字符设备文件也会出现在/ dev目录中。
答案 0 :(得分:1)
一种解决方案是让您的驱动程序动态地在/dev
中创建文件,而不是使用mknod
命令创建它们。基本思想是通过调用class_create
从模块初始化函数创建自定义设备类,然后通过调用device_create
将类设备添加到类中。
您需要一个struct class *
类型的变量来保存指向自定义类的指针。这个变量需要由模块中的各种函数访问,因此需要在任何函数之外声明,并且通常会像这样声明static
:
static struct class *foo_class;
您的模块初始化函数需要创建类并检查错误:
foo_class = class_create(THIS_MODULE, "foo");
if (IS_ERR(foo_class)) {
/* Failed to create class. */
rc = PTR_ERR(foo_class);
goto fail_class_create;
}
(这里,goto fail_class_create
跳转到一个标签,以便在返回错误之前清理到目前为止所做的任何事情。如果你不喜欢这个“on goto gitch”模式,请在返回之前在此明确清理错误。)
如果class_create
函数成功,则在模块退出函数中不再需要时应该销毁它,如果模块初始化函数中有更多错误,也应该作为清理的一部分:
class_destroy(foo_class);
创建类时,您可以通过调用device_create
创建设备来创建(并销毁)属于该类的设备(我称之为“类设备”),device_destroy
摧毁一个设备。这两个函数都使用设备节点号(主设备号和次设备号的组合)来指定要创建或销毁的类设备。例如,可以按如下方式创建类设备:
struct device *csdev;
/* ... */
csdev = device_create(foo_class, hwdev, MKDEV(foo_major, minor), privdata, "foo%u", minor);
if (IS_ERR(csdev)) {
/* Failed to create device. */
rc = PTR_ERR(csdev);
/* Do any clean-up here. */
}
(此处,foo_class
指向先前创建的自定义类; hwdev
指向基础“硬件设备”,或者如果没有底层硬件设备,则可以设置为NULL
; foo_major
是您的主设备号(由register_chrdev
分配,minor
是您要创建的设备的次设备号,privdata
是私有数据指针,通常指向设备的某些私有数据结构,但它可以是NULL
;其余参数由printf样式的格式字符串以及格式字符串创建设备名称所需的任何额外参数组成。)
在上面的示例中,如果minor
为0,则设备将动态创建为/dev/foo0
。
要销毁设备,请按以下方式致电device_destroy
:
device_destroy(foo_class, MKDEV(foo_major, minor));
(此处,foo_class
,foo_major
和minor
与传递给device_create
的内容相同。)
以上功能仅作为GPL导出,因此如果您想使用它们,您的模块将需要使用以下声明声明其许可证:
MODULE_LICENSE("GPL");