🚀 杂项设备驱动简介

杂项设备是字符设备的一种,它比常规字符设备驱动更加简单。

杂项设备驱动可以自动生成设备节点,而且所有杂项设备的主设备号均为 10,可以有效节约内核资源。

可以用 cat /proc/misc 来查看系统当前的杂项设备。

🚀 miscdevice 结构体

misc 设备用 miscdevice 结构体表示, miscdevice 结构体的定义在内核源码具体定义在 include/linux/miscdevice.h 中, 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
// 一般只需要给 minor、name、fops 这三个成员变量赋值即可
struct miscdevice {
int minor; //次设备号
const char *name; //设备节点的名字
const struct file_operations *fops; //文件操作集
struct list_head list;
struct device *parent;
struct device *this_device;
const struct attribute_group **groups;
const char *nodename;
umode_t mode;
};

🚀 杂项设备驱动程序框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <linux/init.h>         // 包含初始化宏定义的头文件
#include <linux/module.h> // 包含初始化加载模块的头文件
#include <linux/miscdevice.h> // 杂项设备驱动相关的头文件
#include <linux/fs.h> // 包含文件操作集定义的头文件

struct file_operations misc_fops = {
.owner = THIS_MODULE,
};

struct miscdevice misc_dev = {
.minor = MISC_DYNAMIC_MINOR, // 动态分配次设备号
.name = "hello_misc", // 设备节点的名字
.fops = &misc_fops,
};

/* 模块的入口 */
static int misc_init(void)
{
int ret;
ret = misc_register(&misc_dev); // 注册杂项设备
if (ret < 0)
{
printk("misc register is error!");
return -1;
}
printk("misc register is succeed!\n");
return 0;
}

/* 模块的出口 */
static void misc_exit(void)
{
misc_deregister(&misc_dev);
printk("goodbye!\n");
}

/* 声明模块的入口和出口 */
module_init(misc_init);
module_exit(misc_exit);

MODULE_LICENSE("GPL"); /* 声明模块的开源许可证 */