您的位置:首页 > 其它

字符设备的内核抽象

2017-12-29 10:03 260 查看
Linux内核中处处体现面向对象的设计思想,为了统一形形色色的设备,Linux系统将设备分为三类:字符设备、块设备、网络设备。并将其分别抽象为struct cdev,struct block_device,struct net_devce三个对象,具体的设备都可以包含着三种对象从而继承和三种对象属性和操作,并通过各自的对象添加到相应的驱动模型中,从而进行统一的管理和操作。

顾名思义,字符设备驱动程序管理的是核心对象是字符设备。从字符设备的设计框架角度出发,内核为字符设备抽象出了一个具体的数据结构struct cdev,定义如下:

#include <linux/cdev.h>
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};


各成员描述如下:

struct kobject kobj

内嵌的内核对象,通过它将设备统一加入到“Linux设备驱动模型”中管理(如对象的引用计数、电源管理、热插拔、生命周期、与用户通信等)。

struct module *owner

字符设备驱动程序所在的内核模块对象的指针。

const struct file_operations *ops

文件操作,是字符设备驱动中非常重要的数据结构,在应用程序通过文件系统(VFS)呼叫到设备设备驱动程序中实现的文件操作类函数过程中,ops起着桥梁纽带作用,VFS与文件系统及设备文件之间的接口是file_operations结构体成员函数,这个结构体包含了对文件进行打开、关闭、读写、控制等一系列成员函数。

struct list_head list

用于将系统中的字符设备形成链表(这是个内核链表的一个链接因子,可以再内核很多结构体中看到这种结构的身影)。

dev_t dev

字符设备的设备号,有主设备和次设备号构成。

unsigned int count

属于同一主设备好的次设备号的个数,用于表示设备驱动程序控制的实际同类设备的数量。

以下是具体设备与cdev的关系:



我们知道了具体的字符设备可以通过cdev来管理字符设备,那么我们如何能够在驱动中通过cdev来找到我们具体的设备呢?C语言中没有面向对象语言的继承的语法,但是我们可以通过结构体的包含来实现继承,例如一个字符设备adc_dev 结构体如下(这个一个能够进行ad采集设备):

struct adc_dev {
unsigned int __iomem *adccon;
unsigned int __iomem *adcdat;
unsigned int __iomem *clrint;
unsigned int __iomem *adcmux;

unsigned int adcval;
struct completion completion;
atomic_t available;
unsigned int irq;
struct cdev cdev;
};


可以看到,这个设备结构体中包含着操作此设备的内存信息、中断信息等,其中就嵌入了cdev结构体,然后通过字符设备的驱动框架就可以将此设备注册进Linux系统。

一般在驱动中我们很容易就能知道cdev指针的值,那么我们可以通过cdev来找到设备结构体adc_dev,内核提供了如下的宏接口:

#define container_of(ptr, type, member) ({          \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })


此接口的具体实现在这不在赘述,详见内核链表相关文章。

现在我们来使用此接口获得我们的设备结构体:

int adc_open(struct inode *inode,struct file *filep)

{

struct adc_dev adc_devp;

adc_devp = container_of(inode->i_cdev, struct cdev, cdev);



return 0;

}

非常简单是不是,其中container_of接口的ptr是内嵌的cdev的内存地址,type为数据类型此处为struct cdev,member为内嵌的成员名此处为cdev。

由于Linux系统要管理成百上千中设备,所以这种抽象非常重要且有必要,它提取并抽象了设备的共性,为上层提供统一接口,使得管理和操作设备变的容易。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  字符设备 内核