应用程序open如何调用到驱动程序的open函数,inode和file的理解

news2024/12/25 8:59:03

 基础知识:

1. struct inode

每创建一个文件,都会生成一个设备节点inode;可以通过inode找到设备号,然后找到cdv;


驱动只有一份,存在多个同类字符设备的时候,得由驱动来区分不同的设备,怎么区别呢?

在注册设备驱动程序的时候会使用device_create()函数,会给不同的同类设备分配不同的次设备号主设备号用于区分设备的类型,次设备号用于标记相同类型的设备的不同个体。Linux内核中使用dev_t类型来定义设备号,dev_t这种类型其实质为32位的unsigned int,其中高12位为主设备号,低20位为次设备号。主设备号相同的设备都使用同一个 file_operations 来操作。
        1.知道主设备号与次设备号,可通过dev_t dev = MKDEV(主设备号,次设备号)获得设备号;            2.从设备号分解出主设备号:主设备号=MAJOR(dev_t dev)
        3.从设备号分解出次设备号:次设备号=MINOR(dev_t dev)


在应用层,只需要open对应的/dev/... 即可,因为open会传递一个inode参数,所以驱动可以据此分辨不同次设备。

2.struct file

file结构是设备驱动程序所使用的第二个重要的数据结构。它是一个内核结构,不会出现在用户程序中。它不仅仅代表一个打开的文件。它由内核在open时创建,并将自身传递给该文件上进行操作的所有函数,只到最后的close函数,在文件的所有实例都被关闭后,内核会释放这个数据结构。

小结:

        struct file结构体中包含有struct file_operations结构体,struct file_operations是struct file的一个域;我们在使用系统调用open()打开一个设备节点struct inode时,我们会得到一个文件struct file,同时返回一个文件描述符,该文件描述符是一个整数,我们称之为句柄,通过访问句柄我们能够访问设备文件struct file,描述符是一个有着特殊含义的整数,特定位都有一定的意义或属性。


open调用具体流程:

应用程序执行open函数,将一个inode结构体(/dev/xxx)通过系统调用传入给内核,调用内核中的 static int chrdev_open(struct inode *inode, struct file *filp)函数(注意会传入两个参数),在该函数中通过inode结构体中的成员变量(inode->i_rdev 包含设备号),在 cdev_map 中查找设备号所对应的字符设备驱动程序cdev 结构体的成员变量kobject,利用该成员变量找到对应的 cdev 结构体,此时,完成由设备驱动节点(inode)找到对应设备驱动(cdev)的步骤。之后inode结构体和cdev结构体完成双向链表的建立,并将cdev结构体中的file_opertion结构体赋给file结构体中的程序变量(filp->f_op)。至此,完成了从 inode结构体 --> cedv结构体 --> file结构体 的建立,之后,对设备进行的read, write等操作,就会执行cdev的相应操作。

fd = open("/dev/hello",O_RDWR);		//应用程序调用 open函数	用户空间
	|
	---> sys_open(const char *,int ,int,);	//系统调用		内核空间
		|
		---> static int chardev_open(struct inode *inode,struct file *filp);	//VFS层
			|
			---> kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
			---> new = container_of(kobj, struct cdev, kobj);	//通过在cdev_map中查找到的cdev的成员变量 struct kobject 
																//结构体 地址,转化成字符设备 cdev 结构体的地址。
			---> inode->i_cdev = p = new;
			---> fops = fops_get(p->ops);		// 通过fops_get得到p指向的file_operations对象ops
			---> replace_fops(filp, fops);		// 通过replace_fops用它替换掉file中的f_op,后续就是通过filp来操作文件
			---> ret = filp->f_op->open(inode, filp);	//调用驱动中的open函数

         
具体源码参考:https://blog.csdn.net/qq_41882586/article/details/127012495

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

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

相关文章

SEH异常之编译器原理探究(2)

_try_finally原理 无论try结构体中是什么代码,都会执行finally里面的代码 局部展开 当try里面没有异常,而是return、continue、break等语句时,就不会走_except_handle3这个函数,而是调用_local_unwind2进行展开 然后调用[ebx e…

鸿蒙OS开发问题:(ArkTS) 【解决中文乱码 string2Uint8Array、uint8Array2String】

在进行base64编码中,遇到中文如果不进行处理一定会出现乱码 let result1: string CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse((一二三四五六七八九十123)))LogUtils.i("result1 " result1);let result2: string CryptoJS.enc.Base64.par…

Java:抽象类相关

引言: 在Java编程语言中,抽象类是一种不能被实例化的重要类型,它为类的层次结构提供了一个基础框架。抽象类可以包含抽象方法和具体方法,它们通常用作其他类的父类或基类。本文将详细探讨Java中抽象类的概念、如何使用它们以及在设…

C++类基础5——拷贝构造函数,拷贝赋值运算符(复制构造函数,复制赋值运算符)

拷贝控制操作 当定义一个类时,我们显式地或隐式地指定在此类望的对象拷贝,移动、赋值和销毁时做什么。 一个类通定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数(copy consinuctor)、拷贝赋值运算符(copy-assignment op…

某国投集团知识竞赛活动方案

一、抽签分组办法 1.抽签:参赛队伍赛前进行抽签分组。 2.分组:全部报名参赛队伍按照抽签顺序分为4组,每组7支队伍进行预赛,9月16日上午1、2组进行初赛,9月16日下午3、4组进行初赛。每组决出的前三名进入决赛。 二、初…

【Frida】【Android】工具篇:ZenTracer

🛫 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

Leetcode刷题记录面试基础题day1(备战秋招)

hello,你好鸭,我是康康,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!💪💪💪 目前博客主要更新Java系列、数据库、项目案例、计算机基础等知识点。感谢你的阅读和…

P2802 回家

P2802 回家 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 虽然是普及-难度的题,但是感觉细节有很多。 细节: bfs第一次到 ( i , j ) (i, j) (i,j),但是距离不一定是最小的 鼠标是一次性物品 血量到达 ( x x , y y ) (xx, yy) (xx,yy)为…

【二分图】【二分图最大匹配】LCP 04. 覆盖

作者推荐 视频算法专题 本文涉及知识点 二分图 二分图最大匹配 LeetCode LCP 04. 覆盖 你有一块棋盘,棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌,你想把这些骨牌不重叠地覆盖在完好的格子上,请找出你最多能在棋盘…

探索C语言中的联合体和枚举:让处理数据更加得心应手

✨✨小新课堂开课了,欢迎欢迎~✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:http://t.csdnimg.cn/Oytke 小新的主页:编程版小新-CSDN博客 C语言中有内置类型, 比如&…

JavaScript:快速入门

1. 数据类型 /** * 数据类型: number(包含整数、小数) * string(字符串类型) * boolean(布尔类型) * object(对象类型) * function(函数类型) …

Roxlabs代理服务:智能化数据采集的加速器

TOC 一、引言 在这个数据驱动的时代,无论是企业还是个人,对于准确、及时的信息获取都有着前所未有的需求。网络数据采集已成为洞察市场趋势、分析竞争对手动态、优化营销策略的关键手段。然而,面对全球范围内的网站和服务,如何高…

【美团笔试题汇总】2024-03-30-美团春招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新美团近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢&#x1f…

使用python将pdf插入到docx中

from pdf2image import convert_from_path from docx import Document from docx.shared import Inches,Cm# 将PDF转换为图片 pages convert_from_path(4.pdf, 200) # 200是DPI,可以根据需要调整doc Document()# 计算图片在docx中应该显示的宽度 img_width Cm(2…

【文献分享】 机器学习 + 分子动力学 + 第一性原理计算 + 热力学性质(熔化温度 热导率 热膨胀系数)

分享一篇关于机器学习 分子动力学 第一性原理 熔化温度(熔化温度 & 热导率 & 热膨胀系数)的文章。 感谢论文的原作者! 关键词: 1. Al−Li alloy 2. Neural network potential 3. Molecular dynamics 4. Thermal pr…

二维码门楼牌管理应用平台建设:三维白模数据建设的意义

文章目录 前言一、三维白模数据建设的意义二、二维码门楼牌管理系统的构建三、二维码门楼牌管理系统的优势四、面临的挑战与未来展望 前言 随着城市管理的精细化和智能化需求日益增强,二维码门楼牌管理应用平台的建设成为推动城市管理现代化的重要手段。本文将探讨…

【漏洞复现】WordPress Plugin LearnDash LMS 敏感信息暴漏

漏洞描述 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress Plugin LearnDash LMS 4.10.2及之前版本存在安全漏洞&#x…

labelme的安装与使用以及如何将labelme标注的json格式关键点标签转为yolo格式的标签

有任何问题我们一起交流,让我们共同学习 标注的json格式以及转换后的yolo格式示例希望得到您的指导背景及代码可用范围一、yolo关键点检测数据集格式二、labelme的安装和使用(一)labelme的安装(二)labelme的使用 三、j…

Unity-C#进阶——3.27更新中

文章目录 数据结构类ArrayListStackQueueHashtable 泛型泛型类、泛型方法、泛型接口ListDictionaryLinkedList泛型栈,泛型队列 委托和事件委托事件匿名函数Lambad 表达式**闭包** List 排序逆变协变多线程进程线程多线程方法:线程之间共享数据&#xff1…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《强沙尘暴下新能源基地的弹性评估及其提升方法 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…