cdev结构体
在内核源码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结构体的更多相关文章
- Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...
- cdev结构体及其相关函数
一.在Linux2.6内核中一个字符设备用cdev结构来描述,其定义如下: struct cdev { struct kobject kobj; struct module *owner; //所属模 ...
- 字符设备驱动1:新的方式添加cdev + 在open函数中将文件私有数据指向设备结构体
本例中,驱动入口处,使用cdev_add添加驱动,这点也可与字符设备驱动0:一个简单但完整的字符设备驱动程序对比一下. 另外主要讲xx_open实现文件私有数据指向设备结构体. 引子: 偶然看到,在j ...
- Linux字符设备中的两个重要结构体(file、inode)
对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...
- inode结构体
inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inod.这里说明的是VFS inode. 重要成员 ...
- cdev成员结构体file_operations文件操作结构的分析
struct file_operations{ struct module *owner; // 指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES loff_t ...
- VFS,super_block,inode,dentry—结构体图解
总结: VFS只存在于内存中,它在系统启动时被创建,系统关闭时注销. VFS的作用就是屏蔽各类文件系统的差异,给用户.应用程序.甚至Linux其他管理模块提供统一的接口集合. 管理VFS数据结构的组成 ...
- 二十四、V4L2框架主要结构体分析和虚拟摄像头驱动编写
一.V4L2框架主要结构体分析 V4L2(video for linux version 2),是内核中视频设备的驱动框架,为上层访问视频设备提供统一接口. V4L2整体框架如下图: 图中主要包括两层 ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
随机推荐
- C# 面向对象之继承后初始化顺序
使用继承之后当我们初始化一个子类时子类的初始化顺序为: (1)初始化类的实例字段 (2)调用基类的构造函数,如果没有指明基类则调用System.Object的构造函数; (3)调用子类的构造函数
- python 多继承(新式类) 二
在python中,要调用父类的某个方法,python2.2之前需要如下代码: class A:def __init__(self): print "enter A" pri ...
- jQuery事件,对象以及插件
回顾 1 基本使用 2 jquery 选择器 3 筛选器 过滤 查找 串联 4 DOM 操作 内部插入 append()appendTo()prepend()prependTo() 外部插入 afte ...
- THML5新增功能
HTML5新增功能 1.语义化标记: 1)article:article标签装载显示一个独立的文章内容.例如一篇完整的论坛帖子,一则网站新闻,一篇博客文章等等,一个用户评论等等 artilce可以嵌套 ...
- 【extjs6学习笔记】0.2 准备:类库结构
- inputStream 与 String 的互相转换
一. String 转换为InputStream String str = "String 与 inputStream转换"; InputStream ins1 = new Byt ...
- jmeter中文件上传配置
- 初习mysql procedure
1.存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户 ...
- 精仿百思不得姐客户端应用iOS源码
XFBaiSiBuDeJie 高仿百思不得姐客户端 初次学习使用RAC,还不是怎么熟悉,使用的仍是MVC模式,MVVM还在摸索中... 如果大家觉得还不错,请给颗星星支持下~~~ 程序中使用到的库 A ...
- 使用Cordova将您的前端JavaScript应用打包成手机原生应用
假设我用JavaScript和HTML开发了一个前端应用,我想把该应用打包成能直接在手机上安装和运行(不通过浏览器)的原生应用,例如像下面这样.对应用的用户来说,他们得到的用户体验和真正的用Andro ...