linux2.6内核驱动程序注册函数,linux 2.6内核 字符设备驱动 相关函数

概述

本文介绍linux字符设备注册相关的四个函数:cdev_alloc、cdev_init、cdev_add和cdev_del。这四个函数在文件:fs/char_dev.c中定义,在头文件include/linux/cdev.h中声明。其中cdev_alloc和cdev_init是一对“互斥”函数,以不同的方式完成“相同”的功能:为函数cdev_add做前期准备。

cdev_alloc

504 /**

505  * cdev_alloc() - allocate a cdev structure

506  *

507  * Allocates and returns a cdev structure, or NULL on failure.

508  */

509 struct cdev *cdev_alloc(void)

510 {

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

512     if (p) {

513         p->kobj.ktype = &ktype_cdev_dynamic;

514         INIT_LIST_HEAD(&p->list);

515         kobject_init(&p->kobj);

516     }

517     return p;

518 }

从函数名称和第511行的代码可以看出:这个函数动态申请结构体struct cdev,并对其进行初始化,最后将其指针返回。下面结合cdev_init进行进一步说明。

cdev_init

520 /**

521  * cdev_init() - initialize a cdev structure

522  * @cdev: the structure to initialize

523  * @fops: the file_operations for this device

524  *

525  * Initializes @cdev, remembering @fops, making it ready to add to the

526  * system with cdev_add().

527  */

528 void cdev_init(struct cdev *cdev, const struct file_operations *fops)

529 {

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

531     INIT_LIST_HEAD(&cdev->list);

532     cdev->kobj.ktype = &ktype_cdev_default;

533     kobject_init(&cdev->kobj);

534     cdev->ops = fops;

535 }

cdev_alloc和cdev_init的主要区别是:前者动态申请结构体struct cdev并对其进行初始化,后者将通过参数传进来的结构体struct cdev进行初始化。

另一个主要区别是:cdev_alloc函数中没有对struct cdev的ops域进行初始化,需要在cdev_alloc函数调用之后有专门的代码对struct cdev的ops域进行初始化,而cdev_init函数中使用通过参数传进来的struct file_operations结构体指针对struct cdev的ops域进行初始化,所以在函数cdev_init调用之后不需要再对struct cdev的ops域进行初始化。

cdev_add

447 /**

448  * cdev_add() - add a char device to the system

449  * @p: the cdev structure for the device

450  * @dev: the first device number for which this device is responsible

451  * @count: the number of consecutive minor numbers corresponding to this

452  *         device

453  *

454  * cdev_add() adds the device represented by @p to the system, making it

455  * live immediately.  A negative error code is returned on failure.

456  */

457 int cdev_add(struct cdev *p, dev_t dev, unsigned count)

458 {

459     p->dev = dev;

460     p->count = count;

461     return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);

462 }

函数cdev_alloc和cdev_init只是(申请)并初始化了(部分)结构体struct cdev,此时,struct cdev和内核还没有任何关系。

函数cdev_add就是将函数cdev_alloc和cdev_init初始化后的struct cdev结构体注册到内核中(第461行),自此内核就可以访问设备了。

cdev_del

本函数和函数cdev_add功能相反,从内核中删除设备。

给出代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MY_MAJOR 250

struct class *my_class;

struct cdev cdev;

dev_t dev;

int hello_open (struct inode *inode,struct file *filp)

{

printk("#########  open  ######\n");

return 0;

}

ssize_t hello_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)

{

printk("#########  read  ######\n");

return count;

}

ssize_t hello_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)

{

printk ("#############  write  ############\n");

return count;

}

int hello_release (struct inode *inode, struct file *filp)

{

printk("#########  release  ######\n");

return 0;

}

struct file_operations hello_fops ={

.owner = THIS_MODULE,

.open = hello_open,

.read = hello_read,

.write = hello_write,

.release = hello_release,

};

int __init hello_init(void)

{

int rc;

dev = MKDEV(MY_MAJOR,0);

printk ("Test hello dev\n");

cdev_init(&cdev,&hello_fops);

cdev.owner = THIS_MODULE;

cdev.ops = &hello_fops;

rc = cdev_add(&cdev,dev,1);

if (rc < 0)

{

printk ("register %s char dev error\n","hello_dev");

return -1;

}

my_class = class_create(THIS_MODULE,"hello_class");

if(IS_ERR(my_class))

{

printk ("err:create class\n");

return -1;

}

device_create(my_class, NULL, dev,NULL, "hello_dev");

printk ("#############  init  ############\n");

return 0;

}

void __exit hello_exit(void)

{

cdev_del(&cdev);

device_destroy(my_class,dev);

class_destroy(my_class);

printk("#############  exit  ############\n");

}

MODULE_LICENSE("GPL"); module_init(hello_init); module_exit(hello_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
共计8个压缩包 本压缩包是:part01.rar 出版社:人民邮电出版社 ·页码:368 页 ·出版日期:2008年 ·ISBN:7115187118/9787115187116 ·条形码:9787115187116 ·包装版本:1版 ·装帧:平装 ·开本:16 ·文:文 ·附带品描述:附光盘一张 ·市场价格:49元 内容简介 Linux内核Linux操作系统最核心的部分,用于实现对硬件部件的编程控制和接口操作。《Linux2.6内核标准教程》深入、系统地讲解了 Linux内核的工作原理,对Linux内核的核心组件逐一进行深入讲解。 全书共8章,首先讲解Linux系统的引导过程;然后对Linux内核的3大核心模块——内存管理、进程管理、断和异常处理进行了深入的分析; 在此基础上,对时间度量、系统调用进行了分析和讨论;最后讲解了Linux内核常见的同步机制,使读者掌握每处理器变量和RCU这两种新的 同步机制。 《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统的地位 4 1.3.2 Linux 2.6内核源代码目录树简介 5 1.3.3 Linux 2.6内核的新特性 8 1.4 如何阅读本书 9 1.4.1 内核探索工具 10 1.4.2 推荐阅读方法 12 第2章 引导过程分析 14 2.1 内核镜像的构建过程 15 2.1.1 编译内核的步骤及分析 15 2.1.2 内核镜像构建过程分析 16 2.2 系统引导过程分析 18 2.2.1 傀儡引导扇区 18 2.2.2 探测系统资源 21 2.2.3 解压内核镜像 35 2.2.4 进入保护模式 40 2.2.5 系统最终初始化 47 2.3 系统引导过程总结 47 第3章 内存管理 50 3.1 基础知识 51 3.1.1 存储器地址 51 3.1.2 分段机制 52 3.1.3 分页机制 59 3.2 内核页表的初始化过程 65 3.2.1 启用分页机制 65 3.2.2 构建内核页表 68 3.3 物理内存的描述方法 76 3.3.1 内存节点 77 3.3.2 内存区域 81 3.3.3 物理页框 85 3.4 物理内存的初始化过程 86 3.4.1 探测系统物理内存 87 3.4.2 初始化内存分配器 89 3.5 物理内存的分配与回收 101 3.5.1 伙伴分配算法 101 3.5.2 对象缓冲技术 103 3.6 内核地址空间 105 3.6.1 常规映射地址空间 105 3.6.2 固定映射地址空间 107 3.6.3 长久内核映射空间 109 3.6.4 临时内核映射空间 116 3.6.5 非连续映射地址空间 119 第4章 进程管理 128 4.1 进程与线程的概念 129 4.1.1 程序与进程 129 4.1.2 进程与线程 129 4.2 进程描述符 131 4.2.1 进程标识符 132 4.2.2 进程的状态 132 4.2.3 进程上下文 134 4.2.4 当前进程 139 4.3 进程的组织形式 143 4.3.1 进程标识符构成的哈希表 143 4.3.2 所有进程构成的双向链表 148 4.3.3 执行态进程组成的运行队列 149 4.3.4 阻塞态进程组成的等待队列 152 4.4 进程的创建过程 155 4.4.1 进程创建的接口函数 156 4.4.2 进程创建的处理过程 162 4.5 进程调度算法 177 4.5.1 进程的分类 178 4.5.2 进程优先级 178 4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程的内存描述符 188 4.7.3 空闲进程的硬件上下文 190 4.7.4 空闲进程的任务状态段 190 第5章 断和异常 192 5.1 基础知识 193 5.1.1 断和异常的定义 193 5.1.2 断和异常的分类 193 5.1.3 断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linu

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值