文章目录
  1. 1. 杂项设备
  2. 2. 杂项设备注册文件

瓦肯举手礼

Linux到2.6版本时候改动巨大,2.6版本以前的基本都废弃了。不用关注2.6以前的版本

杂项设备

杂项设备可以说对一部分字符设备的封装,还有一部份不好归类驱动也归到杂项设备。

为何会引入杂设备?

  1. 节省主设备号
    如果所有的驱动都是用字符设备,那么所有的设备号很快就用完了,总共就是255个主设备号。

  2. 驱动写起来相对简单
    如果直接使用封装好的杂项设备,那么就可以减少一步注册主设备号的过程

杂项设备注册文件

  • 杂项设备初始化部分源文件drivers/char/misc.c

    通过drivers/char/Makefile文件可知misc.c是强制编译

1
2
3
4
5
6
7
#
# Makefile for the kernel character device drivers.
#

obj-y += mem.o random.o
obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
obj-y += misc.o

Linux官方出来就自带强制编译,为了一些简单的驱动更容易实现

  • 杂项设备注册头文件include/linux/miscdevice.h

结构体miscdevice以及注册函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct device;

struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};

extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice *misc);

常用参数

  • .minor设备号

    系统自动分配

  • .name生成设备节点的名称

    与注册设备的.name不同,这里没有匹配的要求

    注册设备的.name必须要和platform_driver结构体中的id.name相同

  • .fops指向一个设备节点文件

  • 内核文件的结构体file_operations
    注册设备节点,本质也是心渐渐一个特殊文件,包含文件名、打开、关闭、操作等函数

    包含文件结构体的头文件是 include/liinux/fs.h

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
/*
* NOTE:
* all file operations except setlease can be called without
* the big kernel lock held in all filesystems.
*/
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
/* remove by cym 20130408 support for MT660.ko */
#if 0
//#ifdef CONFIG_SMM6260_MODEM
#if 1// liang, Pixtree also need to use ioctl interface...
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
#endif
#endif
/* end remove */
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);

file_operations参数非常多,要根据需求选择
必选参数

  • .owner

一般是THIS_MODULE

  • .open打开文件函数

  • ``.release```关闭文件函数

  • .unlokced_ioctl对GPIO的操作,应用向底层传值

实例:

文章目录
  1. 1. 杂项设备
  2. 2. 杂项设备注册文件