在内核源码include/linux/cdev.h里对cdev结构体的定义:

 struct cdev {
struct kobject kobj; // 内嵌的kobject对象 
struct module *owner; // 所属模块
const struct file_operations *ops; // 文件操作结构体
struct list_head list; //linux内核所维护的链表指针
dev_t dev; //设备号
unsigned int count; //设备数目
};

1. 重要成员:

1.1 dev_t dev;设备号,31位,高12位是主设备号,低20位是次设备号。以下函数可以操作设备号:

 #define MINORBITS    20
#define MINORMASK ((1U << MINORBITS) - 1) #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) //获得主设备号
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) //获得此设备号
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) //由主次设备号得到设备号

1.2 struct file_operations *ops;

2. 初始化cdev

2.1 静态初始化

 /**
* cdev_init() - initialize a cdev structure
* @cdev: the structure to initialize
* @fops: the file_operations for this device
*
* Initializes @cdev, remembering @fops, making it ready to add to the
* system with cdev_add().
*/
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, , sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}

2.2 动态初始化

 /**
* cdev_alloc() - allocate a cdev structure
*
* Allocates and returns a cdev structure, or NULL on failure.
*/
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
}

3. 分配设备号

3.1 指定主设备号

 /**
* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)
{
struct char_device_struct *cd;
dev_t to = from + count;
dev_t n, next; for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+, );
if (next > to)
next = to;
cd = __register_chrdev_region(MAJOR(n), MINOR(n),
next - n, name);
if (IS_ERR(cd))
goto fail;
}
return ;
fail:
to = n;
for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+, );
kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
}
return PTR_ERR(cd);
}

3.2 系统自动分配主设备号

 /**
* alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.
*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
{
struct char_device_struct *cd;
cd = __register_chrdev_region(, baseminor, count, name);
if (IS_ERR(cd))
return PTR_ERR(cd);
*dev = MKDEV(cd->major, cd->baseminor);
return ;
}

4 注销设备号

与上述两个分配设备号对应的注销设备号的函数如下:

 /**
* unregister_chrdev_region() - return a range of device numbers
* @from: the first in the range of numbers to unregister
* @count: the number of device numbers to unregister
*
* This function will unregister a range of @count device numbers,
* starting with @from. The caller should normally be the one who
* allocated those numbers in the first place...
*/
void unregister_chrdev_region(dev_t from, unsigned count)
{
dev_t to = from + count;
dev_t n, next; for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+, );
if (next > to)
next = to;
kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
}
}

cdev结构体的更多相关文章

  1. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  2. cdev结构体及其相关函数

    一.在Linux2.6内核中一个字符设备用cdev结构来描述,其定义如下: struct cdev { struct kobject kobj; struct module *owner; //所属模 ...

  3. 字符设备驱动1:新的方式添加cdev + 在open函数中将文件私有数据指向设备结构体

    本例中,驱动入口处,使用cdev_add添加驱动,这点也可与字符设备驱动0:一个简单但完整的字符设备驱动程序对比一下. 另外主要讲xx_open实现文件私有数据指向设备结构体. 引子: 偶然看到,在j ...

  4. Linux字符设备中的两个重要结构体(file、inode)

    对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...

  5. inode结构体

    inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inod.这里说明的是VFS inode. 重要成员 ...

  6. cdev成员结构体file_operations文件操作结构的分析

    struct file_operations{ struct module *owner; // 指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES loff_t ...

  7. VFS,super_block,inode,dentry—结构体图解

    总结: VFS只存在于内存中,它在系统启动时被创建,系统关闭时注销. VFS的作用就是屏蔽各类文件系统的差异,给用户.应用程序.甚至Linux其他管理模块提供统一的接口集合. 管理VFS数据结构的组成 ...

  8. 二十四、V4L2框架主要结构体分析和虚拟摄像头驱动编写

    一.V4L2框架主要结构体分析 V4L2(video for linux version 2),是内核中视频设备的驱动框架,为上层访问视频设备提供统一接口. V4L2整体框架如下图: 图中主要包括两层 ...

  9. Go结构体实现类似成员函数机制

    Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...

随机推荐

  1. python 基础(十二) 图片简单处理

    pillow 图片处理模块 安装 pip install pillow  pip是安装第三方模块的工具 缩放图片实例 from PIL import Image path = r'C:\Users\x ...

  2. pwnhub 相对路径覆盖

    这个pwnhub小m师傅的题,做的时候完全没有思路. 首先是注册然后可以看到一个加载css的地方,是相对路径加载(当然我并没有觉得有什么问题). 服务端和浏览器解析URL是有区别的,就是%2f 服务器 ...

  3. POJ-325Corn Fields

    链接:https://vjudge.net/problem/POJ-3254#author=freeloop 题意: 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ ...

  4. Elasticsearch之入门知识

    elasticsearch是一个高度可扩展得开源全文搜索和分析的引擎.可以快速.近实时的存储,搜索和分析大量数据.通常用作底层引擎技术,为具有复杂搜索功能和要求的程序提供支持. 用处: • 运行网上商 ...

  5. h5旋转效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. jQuery测试

    1.在div元素中,包含了一个<span>元素,通过has选择器获取<div>元素中的<span>元素的语法是? 提示使用has() $("div&quo ...

  7. dos命令安装windows服务

    以下两种方法都是通过dos命令创建windows服务 1.创建服务 sc create UploadRealVolumeService start= auto binpath= C:\Users\Ad ...

  8. 解决部分浏览器不能显示itext生成的PDF文件文本域内容问题

    利用Itext可以实现pdf的高效动态生成,但在实践过程中遇到了一个问题: 即itext利用map中的值设置到pdf模板上建立的文本域中时:能成功生成,但是在部分浏览器上(360,QQ,等浏览器)无法 ...

  9. mui开发中获取单选按钮、复选框的值

    js获取单选按钮的值 function getVals(){ var res = getRadioRes('rds'); if(res == null){mui.toast('请选择'); retur ...

  10. Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库

    Note:这篇文章是基于Android Studio 3.01版本的,NDK是R16. step1:创建一个包含C++的项目 其他默认就可以了. C++ Standard 指定编译库的环境,其中Too ...