Home misc杂项设备
Post
Cancel

misc杂项设备

背景

/dev/目录下的设备节点文件,每套驱动都需要申请一个主设备号Major,不管是动态申请的或是静态定义的,都需要消耗一个主设备号, 如果一个驱动不需要管理很多的从设备,就会显得有些浪费主设备号。

针对此问题,linux内核提供了一个杂项设备驱动的功能框架。杂项设备也属于字符设备,主要特点是共用同一个主设备号,且固定是10。 实际应用中,通常只有少数一两个从设备的杂项驱动可以使用该框架,如果驱动支持管理的设备较多,就不要用这个了,还是单独申请一个主设备号为宜。

大致实现

杂项设备子系统的实现也不复杂,主要有:

  • 使用固定主设备号10来注册主设备号
  • 调用class_create创建杂项设备类,在 /sys/class/misc/ 可以查看
  • 对于用户注册的杂项驱动,自动调用device_create创建设备节点
  • 杂项设备仅次设备号不同,misc设备组织成一个链表,内核根据次设备号找到对应设备,然后调用其fops

杂项设备,主要就是对字符设备驱动进行了简单的二次封装,稍微简化了字符设备驱动的编写,同时节约了主设备号。主要是软件框架方面的,硬件相关 的地方肯定还是需要用户驱动自行编写。

使用

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
#include <linux/miscdevice.h>   //for misc device

const struct file_operations my_xxx_fops={
    .owner          = THIS_MODULE,
    .read           = my_xxx_read,
    .write          = my_xxx_write,
    .open           = my_xxx_open,
    .release        = my_xxx_release,
    .unlocked_ioctl = my_xxx_ioctl,
};

struct miscdevice misc_demodev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "miscdev_xxx",          //某设备
    .fops = &my_xxx_fops,
    .mode = 0666,
};

int __init misc_dev_init(void)
{
    //全局设备管理结构体初始化等。
    // p_one_inst = kzalloc(sizeof(my_xxx_device_t),GFP_KERNEL);

    //设备管理结构体就直接定义并使用全局的。
    misc_register(&misc_demodev);
}

void __exit misc_dev_exit(void)
{
    misc_deregister(&misc_demodev);
    kfree(p_one_inst);
}

不确定能否通过设备文件获取到设备管理结构体,常见示例都是基于全局变量编写的,比较简单。但是也无法管理多个设备,属于缺陷。

查看系统的misc设备

1
2
$ cat /proc/misc
$ ls /sys/class/misc/
This post is licensed under CC BY 4.0 by the author.

内核-semaphore(信号量)

内核-mutex(互斥锁)