当前位置:嗨网首页>书籍在线阅读

03-cdev结构体

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

6.1.1 cdev结构体

在Linux 2.6内核中,使用cdev结构体描述一个字符设备,cdev结构体的定义如代码清单6.1。

代码清单6.1 cdev结构体

1 struct cdev {

2 struct kobject kobj; / 内嵌的kobject对象 /

3 struct module owner; /所属模块*/

4 struct file_operations ops; /文件操作结构体*/

5 struct list_head list;

6 dev_t dev; /设备号/

7 unsigned int count;

8 };

cdev结构体的dev_t成员定义了设备号,为32位,其中12位主设备号,20位次设备号。使用下列宏可以从dev_t获得主设备号和次设备号:

MAJOR(dev_t dev)

MINOR(dev_t dev)

而使用下列宏则可以通过主设备号和次设备号生成dev_t:

MKDEV(int major, int minor)

cdev结构体的另一个重要成员file_operations定义了字符设备驱动提供给虚拟文件系统的接口函数。

Linux 2.6内核提供了一组函数用于操作cdev结构体:

void cdev_init(struct cdev , struct file_operations );

struct cdev *cdev_alloc(void);

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *, dev_t, unsigned);

void cdev_del(struct cdev *);

cdev_init()函数用于初始化cdev的成员,并建立cdev和file_operations之间的连接,其源代码如代码清单6.2所示。

代码清单6.2 cdev_init()函数

1 void cdev_init(struct cdev cdev, struct file_operations fops)

2 {

3 memset(cdev, 0, sizeof *cdev);

4 INIT_LIST_HEAD(&cdev->list);

5 kobject_init(&cdev->kobj, &ktype_cdev_default);

6 cdev->ops = fops; /将传入的文件操作结构体指针赋值给cdev的ops/

7 }

cdev_alloc()函数用于动态申请一个cdev内存,其源代码如代码清单6.3所示。

代码清单6.3 cdev_alloc()函数

1 struct cdev *cdev_alloc(void)

2 {

3 struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);

4 if (p) {

5 INIT_LIST_HEAD(&p->list);

6 kobject_init(&p->kobj, &ktype_cdev_dynamic);

7 }

8 return p;

9 }

cdev_add()函数和cdev_del()函数分别向系统添加和删除一个cdev,完成字符设备的注册和注销。对cdev_add()的调用通常发生在字符设备驱动模块加载函数中,而对cdev_del()函数的调用则通常发生在字符设备驱动模块卸载函数中。