lv14 字符设备驱动基础框架解析 4

news2024/9/22 21:29:13

一、字符设备驱动框架解析

设备的操作函数如果比喻是桩的话(性质类似于设备操作函数的函数,在一些场合被称为桩函数),则:

驱动实现设备操作函数 ----------- 做桩

insmod调用的init函数主要作用 --------- 钉桩

rmmod调用的exitt函数主要作用 --------- 拔桩

应用层通过系统调用函数间接调用这些设备操作函数 ------- 用桩

1.1 两个操作函数中常用的结构体说明

内核中记录文件元信息的结构体
struct inode
{
    //....
    dev_t  i_rdev;//设备号
    struct cdev  *i_cdev;//如果是字符设备才有此成员,指向对应设备驱动程序中的加入系统的struct cdev对象
    //....
}
/*
    1. 内核中每个该结构体对象对应着一个实际文件,一对一
    2. open一个文件时如果内核中该文件对应的inode对象已存在则不再创建,不存在才创建
    3. 内核中用此类型对象关联到对此文件的操作函数集(对设备而言就是关联到具体驱动代码)
*/
读写文件内容过程中用到的一些控制性数据组合而成的对象------文件操作引擎(文件操控器)
struct file
{
    //...
    mode_t f_mode;//不同用户的操作权限,驱动一般不用
    loff_t f_pos;//position 数据位置指示器,需要控制数据开始读写位置的设备有用
    unsigned int f_flags;//open时的第二个参数flags存放在此,驱动中常用
    struct file_operations *f_op;//open时从struct inode中i_cdev的对应成员获得地址,驱动开发中用来协助理解工作原理,内核中使用
    void *private_data;//本次打开文件的私有数据,驱动中常来在几个操作函数间传递共用数据
    struct dentry *f_dentry;//驱动中一般不用,除非需要访问对应文件的inode,用法flip->f_dentry->d_inode
    int refcnt;//引用计数,保存着该对象地址的位置个数,close时发现refcnt为0才会销毁该struct file对象
    //...
};
/*
    1. open函数被调用成功一次,则创建一个该对象,因此可以认为一个该类型的对象对应一次指定文件的操作
    2. open同一个文件多次,每次open都会创建一个该类型的对象
    3. 文件描述符数组中存放的地址指向该类型的对象
    4. 每个文件描述符都对应一个struct file对象的地址
*/

1.2 字符设备驱动程序框架分析

驱动实现端:

驱动使用端:

syscall_open函数实现的伪代码:

int syscall_open(const char *filename,int flag)
{
    dev_t devno;
    struct inode *pnode = NULL;
    struct cdev *pcdev = NULL;
    struct file *pfile = NULL;
    int fd = -1;
    
    /*根据filename在内核中查找该文件对应的struct inode对象地址
        找到则pnode指向该对象
        未找到则创建新的struct inode对象,pnode指向该对象,并从文件系统中读取文件的元信息到该对象*/
    if(/*未找到对应的struct inode对象*/)
    {/*根据文件种类决定如何进行下面的操作,如果是字符设备则执行如下操作*/
    
        /*从pnode指向对象中得到设备号*/
        devno = pnode->i_rdev;
    
        /*用devno在字符设备链表查找对应节点,并将该节点的地址赋值给pcdev*/
    
        /*pcdev赋值给pnode的i_cdev成员*/
        pnode->i_cdev = pcdev;
    }
    
    /*创建struct file对象,并将该对象的地址赋值给pfile*/
    
    pfile->f_op = pnode->i_cdev->ops;
    pfile->f_flags = flag;
    
    /*调用驱动程序的open函数*/
    pfile->f_op->open(pnode,pfile,flag);
    
    /*将struct file对象地址填入进程的描述符数组,得到对应位置的下标赋值给fd*/
    
    return fd;
}

syscall_read函数实现的伪代码

int syscall_read(int fd,void *pbuf,int size)
{
    struct file *pfile = NULL;
    struct file_operations *fops = NULL;
    int cnt;
    
    /*将fd作为下标,在进程的描述符数组中获得struct file对象的地址赋值给pfile*/
    
    /*从struct file对象的f_op成员中得到操作函数集对象地址赋值给fops*/
    
    /*从操作函数集对象的read成员得到该设备对应的驱动程序中read函数,并调用之*/
    cnt = fops->read(pfile,pbuf,size,&pfile->f_pos);
    
    。。。。
    return cnt;
}

1.3 参考原理图

 

1.4 常用操作函数说明

int (*open) (struct inode *, struct file *);    //打开设备
/*
    指向函数一般用来对设备进行硬件上的初始化,对于一些简单的设备该函数只需要return 0,对应open系统调用,是open系统调用函数实现过程中调用的函数,
*/
​
int (*release) (struct inode *, struct file *); //关闭设备
/*
    ,指向函数一般用来对设备进行硬件上的关闭操作,对于一些简单的设备该函数只需要return 0,对应close系统调用,是close系统调用函数实现过程中调用的函数
*/
​
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);   //读设备
/*
    指向函数用来将设备产生的数据读到用户空间,对应read系统调用,是read系统调用函数实现过程中调用的函数
*/
​
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);    //写设备
/*
    指向函数用来将用户空间的数据写进设备,对应write系统调用,是write系统调用函数实现过程中调用的函数
*/
​
loff_t (*llseek) (struct file *, loff_t, int);      //数据操作位置的定位
/*
    指向函数用来获取或设置设备数据的开始操作位置(位置指示器),对应lseek系统调用,是lseek系统调用函数实现过程中调用的函数
*/
​
​
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);//读写设备参数,读设备状态、控制设备
/*
    指向函数用来获取、设置设备一些属性或设备的工作方式等非数据读写操作,对应ioctl系统调用,是ioctl系统调用函数实现过程中调用的函数
*/
​
unsigned int (*poll) (struct file *, struct poll_table_struct *);//POLL机制,实现对设备的多路复用方式的访问
/*
    指向函数用来协助多路复用机制完成对本设备可读、可写数据的监控,对应select、poll、epoll_wait系统调用,是select、poll、epoll_wait系统调用函数实现过程中调用的函数
*/
  
int (*fasync) (int, struct file *, int); //信号驱动
/*
    指向函数用来创建信号驱动机制的引擎,对应fcntl系统调用的FASYNC标记设置,是fcntl系统调用函数FASYNC标记设置过程中调用的函数
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1353786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL窗口函数大小详解

窗口大小 OVER 子句中的 frame_clause 选项用于指定一个滑动的窗口。窗口总是位于分区范围之内,是分区的一个子集。指定了窗口之后,分析函数不再基于分区进行计算,而是基于窗口内的数据进行计算。 指定窗口大小的语法如下: ROWS…

怎么将视频转换为mp4?

怎么将视频转换为mp4?转换视频文件为 MP4 格式是非常普遍的需求,因为 MP4 是广泛支持的视频格式之一,能够在各种设备上流畅播放。MP4 格式具有很好的兼容性,基本上可以在所有的播放器中播放,也可以在大多数剪辑软件中打…

WEB 3D技术 three.js 补间动画(tween)

本文 我们来说 补间动画 比如说 我们有一个正方体 默认在如下图位置 然后 我们希望 一秒中之后 它到达如下图位置 那么 我们知道 终点和起点的位置 从起点到终点 一共需要一秒的时间 需要程序自己去处理这个图形 0.1 0.2 直到 1秒 它都分别要达到什么位置 通过开始和结束位…

尚硅谷大数据技术-数据湖Hudi视频教程-笔记01

大数据新风口:Hudi数据湖(尚硅谷&Apache Hudi联合出品)尚硅谷数据湖Hudi视频教程 B站直达:https://www.bilibili.com/video/BV1ue4y1i7na百度网盘:https://pan.baidu.com/s/1NkPku5Pp-l0gfgoo63hR-Q?pwdyyds阿里云…

爬虫如何使用代理IP通过HTML和CSS采集数据

目录 前言 1. 了解代理IP 2. 通过HTML和CSS采集数据 3. 使用代理IP进行数据采集 3.1 获取代理IP列表 3.2 配置代理IP 3.3 发送请求和解析网页内容 总结 前言 爬虫是一种自动化工具,用于从互联网上获取数据。代理IP是一种用于隐藏真实IP地址并改变网络请求的…

Python电能质量扰动信号分类(四)基于CNN-BiLSTM的一维信号分类模型

往期精彩内容: 引言 1 数据集制作与加载 1.1 导入数据 1.2 制作数据集 2 CNN-BiLSTM分类模型和超参数选取 2.1定义CNN-BiLSTM分类模型 2.2 设置参数,训练模型 3 模型评估 3.1 准确率、精确率、召回率、F1 Score 3.2 十分类混淆矩阵&#xff1a…

Stata各版本安装指南

Stata下载链接 https://pan.baidu.com/s/1ECc2mPsfNOUUwOQC9hCcYg?pwd0531 1.鼠标右击【Stata18(64bit)】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到 Stata18(64bit)】。 2.打开解压后的文件夹,鼠标右击【Setup】选择【以管…

修复移动硬盘显示盘符但打不开问题

问题: 移动硬盘显示盘符,但无法打开。点击属性不显示磁盘使用信息。 分析解决: 这是由于硬盘存在损坏导致的,可以通过系统自带的磁盘检查修复解决,而无需额外工具。 假设损坏的盘符是E,在命令行运行以下命令…

【日积月累】Java中 正则表达式

目录 日积月累】Java中 正则表达式 1.前言2.基本语法3.Pattern和Matcher类4.校验的表达式大全5.参考文章所属专区 日积月累 1.前言 正则表达式是一种用于匹配文本模式的语法,它通常与编程语言一起使用。在Java中,正则表达式用于匹配字符串,可以使用Pattern和Matcher类来实…

性能测评高效云盘、ESSD Entry云盘、SSD云盘、ESSD云盘、ESSD PL-X云盘及ESSD AutoPL云盘

阿里云服务器系统盘或数据盘支持多种云盘类型,如高效云盘、ESSD Entry云盘、SSD云盘、ESSD云盘、ESSD PL-X云盘及ESSD AutoPL云盘等,阿里云百科aliyunbaike.com详细介绍不同云盘说明及单盘容量、最大/最小IOPS、最大/最小吞吐量、单路随机写平均时延等性…

Vue 中的 ref 与 reactive:让你的应用更具响应性(上)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

uniapp中uview组件库丰富LoadingPage 加载页

目录 基本使用 #显示或隐藏 #文字内容 #动画模式 #动画图片 #文字颜色 #文字大小 #图标大小 2.0.32 #背景颜色 #图标颜色 API #Props 基本使用 <template><view><u-loading-page></u-loading-page></view> </template>#显示或…

Flink版本更新汇总(1.14-1.18)

0、汇总 1.14.0 1.有界流支持 Checkpoint&#xff1b; 2.批执行模式支持 DataStream 和 Table/SQL 混合应用&#xff1b; 3.新增 Hybrid Source 功能&#xff1b; 4.新增 缓冲区去膨胀 功能&#xff1b; 5.新增 细粒度资源管理 功能&#xff1b; 6.新增 DataStream 的 Pulsar …

.mallox勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

引言&#xff1a; 随着技术的不断发展&#xff0c;网络空间也不可避免地面临着各种威胁&#xff0c;其中之一就是勒索病毒&#xff0c;而.mallox是近期引起关注的一种恶意软件。本文将介绍.mallox勒索病毒&#xff0c;以及如何有效地恢复被其加密的数据文件&#xff0c;并提供…

高德地图经纬度坐标导出工具

https://tool.xuexiareas.com/map/amap 可以导出单个点&#xff0c;也可以导出多个&#xff0c;多个点可以连成线&#xff0c;可用于前端开发时自己模拟“线“数据

修复键盘问题的十种方法,总有一种可以帮到你

坏了的键盘可不是闹着玩的。这就是为什么苹果公司向人们支付395美元,以解决其蝴蝶键盘故障的集体诉讼。但这个问题并不总是那么普遍,所以这通常意味着如果出现问题,你只能靠自己了。 重新启动电脑 你有没有试过反复打开电脑?在你尝试任何随机修复之前,一个简单的重新启动…

基于SSM的滁艺咖啡在线销售系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

【致远OA】获取指定人员的协同待发列表

接口请求说明 V6.0接口更新:不在传入ticket&#xff0c;改为传memberId人员ID V6.0之前http请求方式&#xff1a;GET http://ip:port/seeyon/rest/affairs/draft 如 http://127.0.0.1/seeyon/rest/affairs/draft?ticketxxxxxx V6.0http请求方式&#xff1a;GET http://ip:p…

Grafana UI 入门使用

最近项目上需要使用Grafana来做chart&#xff0c;因为server不是我在搭建&#xff0c;所以就不介绍怎么搭建grafana server&#xff0c;而是谈下怎么在UI上具体操作使用了。 DOCs 首先呢&#xff0c;贴一下官网doc的连接&#xff0c;方便查询 Grafana open source documenta…

记一个sqlserver数据库查询死锁异常

一、报错日志&#xff1a; Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 事务(进程 ID 117)与另一个进程被死锁在 锁 | 通信缓冲区 资源上&#xff0c;并且已被选作死锁牺牲品。请重新运行该事务。 二、数据库现象 注&#xff1a;下图中最后一条记录是解决后…