在内核源码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));
}
}

最新文章

  1. thinkphp模型
  2. oracle中的函数及其应用
  3. Android ListView 子控件点击事件
  4. JavaScript中__proto__与prototype的关系
  5. linux设备驱动编写_tasklet机制(转)
  6. SecureCRT、FileZilla使用Public证书登录Linux
  7. 第一次用Github desktop(mac)提交代码遇到的问题
  8. win7下设置 WiFi AP
  9. NumPy基础:数组和矢量计算
  10. 【Spark2.0源码学习】-6.Client启动
  11. ORACLE NLS_DATE_FORMAT设置
  12. 什么是LDAP?
  13. 解决WPF导入图片不显示的问题
  14. sass、less是什么,如何使用?
  15. mybatis的插件,挺好支持下
  16. POJ 2240 Arbitrage / ZOJ 1092 Arbitrage / HDU 1217 Arbitrage / SPOJ Arbitrage(图论,环)
  17. js 内置函数 内置对象
  18. java,arduino,C#之间的一些编码转换
  19. delphi自带的SHA1算法
  20. 探路者-Beta发布中间产物

热门文章

  1. tera term 的一个命令解析脚本
  2. rtos概要
  3. 持续集成~Jenkins里的powershell插件发布远程站点了
  4. Rabbitmq~linux环境的部署
  5. Linux系统下安装rz/sz命令及使用说明(文件上传下载)
  6. [问题记录]Ubuntu下chmsee安装失败的解决
  7. .aspx IIS发布404.17时候的问题
  8. git clone fatal: unable to access &#39;https://github.com/carlon/demo.git/&#39;: Failed to connect to github.com port 443: Timed out
  9. Ubuntu下软件的搜索与安装
  10. iOS上线check_list