Linux字符设备注册函数 register_chrdev详解

2023-05-16

Linux字符设备注册函数 register_chrdev详解

 

当我们需要注册字符设备的时候,需要module_init()中调用register_chrdev()注册。

下面主要介绍接口的实现过程与细节。

内核函数前面添加__  代表内核级函数。谨慎调用。源代码如下:

int __register_chrdev(unsigned int major, unsigned int baseminor,

      unsigned int count, const char *name,

      const struct file_operations *fops)

{

struct char_device_struct *cd;

struct cdev *cdev;

int err = -ENOMEM;

 

cd = __register_chrdev_region(major, baseminor, count, name);

if (IS_ERR(cd))

return PTR_ERR(cd);

cdev = cdev_alloc();

if (!cdev)

goto out2;

 

cdev->owner = fops->owner;

cdev->ops = fops;

kobject_set_name(&cdev->kobj, "%s", name);

err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);

if (err)

goto out;

 

cd->cdev = cdev;

 

return major ? 0 : cd->major;

out:

kobject_put(&cdev->kobj);

out2:

kfree(__unregister_chrdev_region(cd->major, baseminor, count));

return err;

}

1:参数分析

 * @major: major device number or 0 for dynamic allocation

 主设备号,当用户设置为0时,内核会动态分配一个设备号。

 * @baseminor: first of the requested range of minor numbers

次设备号,要在一定范围内从0开始

 * @count: the number of minor numbers required

次设备号的范围

 * @name: name of this range of devices

设备名称

 * @fops: file operations associated with this devices

文件系统的接口指针

2:接口代码分析

 

struct char_device_struct *cd; //字符设备结构体指针,用于检测存储使用。

static struct char_device_struct {

struct char_device_struct *next;

unsigned int major;

unsigned int baseminor;

int minorct;

char name[64];

struct cdev *cdev; /* will die */

} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];

 __register_chrdev_region():

检查设备号是否有效,注册设备到全局变量chrdevs[i]中。

内核中有字符设备和块设备表,根据设备类型和主设备号既能找到对应的结构跳转函数。


struct cdev *cdev; 字符型设备,这个是真正的实用的。

struct cdev {

struct kobject kobj;

struct module *owner;

const struct file_operations *ops;

struct list_head list;

dev_t dev;

unsigned int count;

};

cdev = cdev_alloc();

分配一个字符设备结构内存大小,返回这个结构,失败返回空。

cdev->owner = fops->owner;

cdev->ops = fops;

kobject_set_name(&cdev->kobj, "%s", name);

设置设备用户,文件操作指针,设备名称。

 

err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);

添加设备到系统中 module结构体链表中,使之模块立即生效。此后文件操作,可以正常使用

 

如果注册失败的话,释放以上的配置。

 

重点是 cdev_add的理解源代码如下:

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

{

p->dev = dev;

p->count = count;

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

}

 

int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,

     struct module *module, kobj_probe_t *probe,

     int (*lock)(dev_t, void *), void *data)

{

unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;

unsigned index = MAJOR(dev);

unsigned i;

struct probe *p;

 

if (n > 255)

n = 255;  //检测设备号是否在范围内

 

p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);

 

if (p == NULL)

return -ENOMEM;

 

for (i = 0; i < n; i++, p++) {   //设置字符module结构的配置

p->owner = module;

p->get = probe;

p->lock = lock;

p->dev = dev;

p->range = range;

p->data = data;

}

mutex_lock(domain->lock);

for (i = 0, p -= n; i < n; i++, p++, index++) {

struct probe **s = &domain->probes[index % 255];//添加到全局模块中

while (*s && (*s)->range < range)

s = &(*s)->next;

p->next = *s;

*s = p;

}

mutex_unlock(domain->lock);

return 0;

}

 

取消模块就是删除原来注册的东西,不做详细介绍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux字符设备注册函数 register_chrdev详解 的相关文章

随机推荐

  • 一文了解DTU、FTU、TTU、RTU的区别

    电力自动化有一堆 某TU xff08 不敢写X 怕被认为新设备 xff09 的设备 xff0c 搞得不做自动化的同学们很晕 xff0c 这里为大家收集下这几者的定义和区别 想要了解更加详细的内容 xff0c 可以点击电力知识图谱网站 xff
  • PIC单片机的配置字总结

    平台为 xff1a MPLAB V8 92 xff0c 这个ID有两个编译选项 xff1a DEBUG和RELEASE xff0c 那么可以根据系统预定宏来自动根据选择模式 xff0c 配置配置字 一 PIC18F系列配置字编写 MUC P
  • USB 2.0 A型、B型、Mini和Micro接口 type-c 定义及封装

    免责声明 xff1a 所有资料均来自互联网 xff0c 如有错误之处 xff0c 本人概不负责 出处 xff1a http blog 163 com wilicedon lee blog static 8158848320101174142
  • 对于嵌入式初学者建议读的书

    刚加入了几个嵌入式群 xff0c 群里提问最多的是怎么能够快速入门 xff1f 对于这个问题 xff0c 一千人个人可能有一千个答案 我也在嵌入式行业里混了几年 xff0c 虽然说技术很水 xff0c 经 验不多 xff0c 但是比起没有入
  • matlab学习笔记二:plot画图怎么设置线条类型和颜色

    出处 xff1a https jingyan baidu com article 48b558e338aaa37f38c09a80 html matlab的绘图功能很强大 xff0c 因此它在科学实验和社会调研中被广泛应用 我们在 绘制图形
  • XModem协议

    出处 xff1a XModem协议 XModem协议介绍 xff1a XModem是一种在串口通信中广泛使用的异步文件传输协议 xff0c 分为XModem和1k XModem协议两种 xff0c 前者使用128字节的数据块 xff0c 后
  • 详解,N沟道MOS管和P沟道MOS管

    出处 xff1a P沟道mos管作为开关的条件 xff08 GS gt GS xff08 TH xff09 xff09 1 P沟道mos管作为开关 xff0c 栅源的阀值为 0 4V xff0c 当栅源的电压差为 0 4V就会使DS导通 x
  • python通过pip安装torch错误及解决办法ERROR: Could not find a version that satisfies the requirement torch

    错误代码 pip install torch 61 61 1 6 0 43 cu101 to rchvision 61 61 0 7 0 43 cu101 f https download pytorch org whl torch sta
  • 智能代码补全工具 tabnine

    安装方法链接 xff1a https www tabnine com install 亲测有效 xff1a tabnine vim Without Vundle Run git clone depth 1 https github com
  • ovsdb <7> OVSDB操作实践及各种机制的分析

    4 2OVSDB操作实践及各种机制的分析 在安装了上述的openvswitch和做了相应的配置之后 xff0c 下面对openvswitch中提供的各种ovsdb的工具 操作方式和工作机制做一些简单的说明 xff1a 1 Ovsdb ser
  • ovsdb <10> Ops-cli结合ovsdb部分流程及接口分析

    4 6Ops cli结合ovsdb部分流程及接口分析 Ops中对于ovsdb的应用主要是基于上述的ovsdb的简单用法上的一个扩展和函数封装 xff0c 现在就其与之前不同的地方做补充说明并就各个函数的使用做相应的说明 根据前面的ovsdb
  • 项目管理:代码检查 pre-commit 使用详解

    Git钩子脚本对于在提交代码审查之前识别简单问题很有用 我们在每次提交时都运行钩子 xff0c 以自动指出代码中的问题 xff0c 例如缺少分号 xff0c 尾随空白和调试语句 通过在代码审阅之前指出这些问题 xff0c 代码审阅者可以专注
  • SOCAT详解

    概述 socat xff0c 是linux下的一个工具 xff0c 其功能与有 瑞士军刀 之称的netcat类似 xff0c 不过据说可以看做netcat的加强版 的确如此 xff0c 它有一些netcat所不具备却又很有需求的功能 xff
  • sonic 架构学习

    射人先射马 xff0c 擒贼先擒王 在我们学习sonic的过程中 xff0c 无疑了解sonic的架构是非常重要的 xff0c 然后再去了解各个模块的细节 xff0c 总分学习模式 下面是我自我学习并翻译的链接https github co
  • 以配置MTU 了解SONIC网络操作系统命令配置流程

    介绍 总览 本文档介绍了SONiC中的最大传输单元 xff08 MTU xff09 配置和行为 在计算机网络中 xff0c 层的通信协议的MTU定义了允许该层通过一个接口传输的最大协议数据单元的大小 xff08 以字节为单位 xff09 每
  • Mellanox CX4 offload 卸载功能介绍

    无状态功能卸载 cx4支持多种类型的无状态卸载 xff0c 如下面列表所示 Checksum OffloadLarge Send OffloadsReceive Side ScalingTransmit Side ScalingInterr
  • Mellanox cx4 驱动总结

    以下要点总结了基本的以太网驱动程序流程 xff1a 驱动加载 通过命令 QUERY HCA CAP 检查以太网卸载支持的设备功能建立发送rings 分配中断 xff0c 创建Event Queues 和 Completion Queues
  • 希腊符号读法大全

    是希腊字母 的古典写法 xff0c 读偏导数 xff0c 读round 1 alpha a lf 阿尔法 角度 xff1b 系数 2 beta bet 贝塔 磁通系数 xff1b 角度 xff1b 系数 3 gamma ga m 伽马 电导
  • 遍历ip开放的端口

    用于检测服务器上某个ip地址开放的端口 xff0c 查漏洞等 bin bash port range to check for i in 20 25 do echo now is i check open port and save to
  • Linux字符设备注册函数 register_chrdev详解

    Linux字符设备注册函数 register chrdev 详解 当我们需要注册字符设备的时候 xff0c 需要 module init 中调用 register chrdev 注册 下面主要介绍接口的实现过程与细节 内核函数前面添加 代表