Linux系统调用过程详解:应用程序调用驱动过程

news2024/11/20 17:39:19

Linux下应用程序调用驱动程序过程:

(1)加载一个驱动模块(.ko),产生一个设备文件,有唯一对应的inode结构体

                a、每个设备文件都有一个对应的’inode‘结构体,包含了设备的主次设备号,是设备的唯一标识。

                b、驱动加载至内核,初始化时通常会调用’register_chrdev()‘或’register_blkdev()‘(字符设备和块设备),注册设备号和关联文件操作file_operation。

                c、有了设备号后,用class_create()和 device_create()创建设备文件 ,device_create()该函数需要一个有效设备号

                d、当设备文件创建后,文件系统会为其创建和初始化一个’inode‘结构体,包含文件类型、权限、所有者信息以及重要的设备号

(2)应用层调用open函数打开设备文件(该函数是在应用层中写好的),对于上层open调用到内核时,发生一次软中断,从用户空间进入到内核空间

(3)open会调用到sys_open(内核系统调用函数),sys_open根据文件的地址(文件的路径),找到设备文件对应的struct inode结构体描述的信息,得知要操作的设备类型(字符设备还是块设备),还会分配一个struct file结构体。

  • sys_open:

                内核级的系统调用函数,用于打开文件和设备。系统调用是用户空间和内核空间之间的接口,通过系统调用可从用户态切换至内核态。

  • sys_open函数的基本操作:

                a、解析用户提供的文件名,确定文件位置和权限(通常为文件的路径名,如/dev/设备名)

                b、检查文件访问权限

                c、分配并初始化一个文件描述符(对该文件操作的引用,非负的整数,是该文件表条目在文件表中的索引)

                d、将文件描述符返回给用户空间

  • struct file:
    • 内核中的重要结构体,表示一个已打开的文件(信息)。
    • 包含相关的文件状态信息,如当前偏移量、文件操作指针file_operation(包含对文件读写的操作函数指针)、'inode'结构体指针
    • 由sys_open创建,内核为打开的文件创建一个新的'struct file'实例

(4)根据struct inode结构体内记录的主次设备号,在驱动链表(管理所有设备驱动)里面,找到字符设备驱动。

        这一步也是后续为了给创建的file结构体内的f_ops成员,文件操作指针赋值

  • 驱动链表:
    • Linux内核中用于管理设备驱动的关键数据结构,是一个链表或哈希表结构,其中包含了所有注册的设备驱动。
    • 字符设备的驱动链表中,每个成员(设备)确实是通过 struct cdev 结构体来表示的。
    • 字符设备驱动通过调用 cdev_add() 函数将自己的 cdev 结构体添加到内核的设备表中(这通常是在调用 register_chrdev_region() 或 alloc_chrdev_region() 注册设备号之后进行的。

(5)每个字符设备都有一个struct cdev结构体。描述了字符设备的所有信息,其中最重要的一项是字符设备的操作函数接口

(6)找到struct cdev结构体后,linux内核就会将struct cdev结构体所在内存空间首地址记录在struct inode结构体i_cdev成员中,将struct cdev结构体中记录的函数操作接口地址记录在strct file结构体的f_ops成员中

(7)执行xxx_open驱动函数。

流程架构参考自:最全Linux驱动开发全流程详细解析(持续更新)-CSDN博客

inode结构体组成

变量赋值的来源

这些变量的值大多是由文件系统、内核的设备管理子系统,或驱动自身在注册设备时设置的。

例如:

  • i_mode(文件模式):通常由驱动设置以标识设备文件的类型(字符设备或块设备)
  • i_rdev(实际设备ID):包含主设备号和次设备号(高12位和低20位),由register_chrdev()或register_blkdev()设置

文件系统中对于'inode'

在创建和管理'inode'结构体中起到核心作用,当一个文件系统被挂载时,它会初始化其管理的所有 inode,并负责管理它们的生命周期。文件系统会定义自己的'inode'操作方法('inode_operation'结构体,也是inode结构体的成员变量),包括:

        a、创建 (create):当新文件被创建时,文件系统会分配和初始化一个 inode 结构体。这包括设置文件类型、权限、所有者等。

        b、查找 (lookup):在访问文件时,文件系统需要通过路径查找相应的 inode。

        c、删除 (delete):当文件被删除时,文件系统负责清理 inode 结构体,并可能将其空间释放回 inode 缓存。

文件描述符:
用于访问文件和设备的一个抽象表示。文件描述符本质上是一个非负整数,当一个程序打开一个文件(包括设备文件)时,操作系统返回的文件描述符作为未来所有对该文件的操作的引用。

文件描述符的形式和功能

  • 形式:文件描述符是一个简单的整数值。在一个进程的上下文中,每打开一个文件或设备,内核就会分配最低未被使用的文件描述符。
  • 功能:文件描述符提供了一个通用的方法来引用所有类型的文件,无论它们是普通的磁盘文件、目录、链接还是设备(如键盘、硬盘、网络设备等)。

文件描述符的操作

当一个文件或设备被打开时,内核会创建一个文件表条目。文件描述符就是这个文件表条目在文件表中的索引。

文件表条目包括:文件位置、当前偏移量、访问权限、指向具体文件操作的指针等。

  • 基于文件描述符的标准操作:

                a、打开操作open(pathname, flags, ... ):打开一个已存在的文件或创建一个新文件,并返回一个文件描述符

                b、读操作 (read(fd, buffer, size)):从由 fd 指定的文件或设备中读取数据。

                c、写操作 (write(fd, buffer, size)):向由 fd 指定的文件或设备写入数据。

                d、输入输出控制操作 (ioctl(fd, command, ...)):对特定的设备执行控制和配置操作。

                e、文件控制操作(fcntl(fd, command, ...)):改变已打开的文件性质。

                f、关闭操作 (close(int fd)):关闭文件描述符。

file结构体组成

struct file主要成员解释

  • f_path:包含文件的路径和文件系统信息,struct path 结构体包括一个指向 dentry(目录项)和 vfsmount(文件系统挂载点)的指针。
  • f_inode:指向与文件关联的 inode 结构体的指针,它存储了文件的大部分元数据。
  • f_op:指向文件操作表的指针,这个表包含了各种文件操作相关的函数指针,如 readwriteopenrelease 等。
  • f_lock:自旋锁,用于保护文件相关的敏感操作。
  • f_count:原子类型,表示文件描述符的引用计数,用于文件描述符的复制和释放管理。
  • f_flags:打开文件时使用的标志,如 O_RDONLYO_NONBLOCK 等。
  • f_mode:文件模式,指定文件的访问模式,如只读、只写等。
  • f_pos:当前文件的偏移量,表示下一次读/写的起始位置。
  • f_owner:文件所有者的信息,常用于信号发送。
  • f_mapping:指向文件的地址空间结构,用于文件映射和内存管理。

驱动链表的设备匹配

当一个应用程序尝试通过系统调用(open())访问一个字符设备时,内核在驱动链表中找到相应的设备驱动的步骤:

1、设备号解析

应用程序请求打开一个设备文件(/dev/example)时,内核首先获取该设备文件的'inode'结构体,从中读取主次设备号

  • 主设备号:用于识别该设备的驱动程序
  • 次设备号:用于识别该驱动程序控制的特定设备实例(控制的是哪个设备)

2、驱动链表搜索

内核中维护了一个包含所有已注册字符设备的列表(register_chrdev()),每个注册设备通过一个'struct cdev'实例表示,并链接到全局链表中。内核遍历这个链表,比较每个'struct cdev'的设备号

  • 链表遍历:从链表头部开始,内核遍历每个'cdev'条目
  • 匹配主设备号:内核检测每个'cdev'的主设备号是否与请求的主设备号匹配

3、文件操作结构体关联

一旦找到匹配的'cdev'结构体,内核将使用该结构体中的'file_operations'指针。

  • 设备操作:应用程序通过系统调用请求的操作(如读取或写入数据)将由file_operations结构体中相应的函数处理。

4、f_op指针设置

内核在打开文件时会创建file struct结构体,但此时部分成员未设置,包括f_op指针(file_operation的指针)。一旦找到正确的驱动,f_op指针会被设置为指向该驱动的file_operations结构体。

后续的操作(如再次读写文件)都会通过这些函数处理(file_operation中的函数)。

Linux设备号:

Linux中每个设备都有一个设备号,由主设备号和次设备号组成。主设备号对应一个具体的驱动,次设备号表示使用这个驱动的各个设备。Linux中提供了一个名为dev_t的数据类型表示设备号,定义在include/linux/types.h中。

1、dev_t类型

  • _u32类型别名为_kernel_dev_t;
  • _kernel_dev_t别名为dev_t
  • 所以dev_t 是__u32 类型的(即unsigned int)

  • _u32:32位的无符号整形unsigned int。

该32位数据构成了主设备号和次设备号,高12位为主设备号,低20位为次设备号,所以系统中主设备号范围为0~4095。

2、设备操作函数:

  • MINORBITS:次设备号位数,20位。
  • MINORMASK:次设备号掩码
  • MAJOR(dev):从dev_t中获取主设备号,将dev_t右移20位
  • MINOR(dev):从dev_t中获取次设备号,取dev_t低20位的值
  • MKDEV(ma,mi):将给定的主设备号和次设备号的值组合成dev_t类型的设备号。(主设备号左移20位)

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

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

相关文章

AScript纯本地离线文字识别插件

目的 AScript是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务,节省大量人工操作的时间。但按键精灵是不包含图色功能,无法识别屏幕上的图像,根据图像的变化自动执行相应的操作。本篇文章主要讲解下…

全网最详细使用war包的方式结合Tomcat和向量数据库PostgreSQL本地部署Xwiki教学

部署 XWiki 在 CentOS 7 上的过程涉及多个步骤,主要包括安装环境依赖、配置数据库以及安装和配置XWiki。以下是一个详细的步骤说明: 1. 系统准备 首先,确保您的系统是最新的: sudo yum update2. 安装 Java 这里需要注意一下版本…

综述列表(~2024.05.10)

(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 每周末更新,完整版进群获取。 Q 群在群文件,VX 群每周末更新。

vivado新版本兼容老版本,vitis classic兼容sdk教程

new version: vivado版本2023.2 和vitisv classic 2023.2 old version: vivado 2018.3以及之前的版本 打开工程 自动升级到当前版本,选择OK 点击Yes,合并当前的目录架构 点击OK 点击Report IP status 勾选要升级的IP核,点击升级 在项目工程文件夹…

leetcode-括号生成-101

题目要求 思路 1.左括号的数量等于右括号的数量等于n作为判出条件,将结果存到res中 2.递归有两种,一种是增加左括号,一种是增加右括号,只要左括号的数量不超过n,就走增加左括号的递归,右括号的数量只要小于…

Microsoft Edge浏览器,便携增强版 v118.0.5993.69

01 软件介绍 Microsoft Edge浏览器,便携增强版,旨在无需更新组件的情况下提供额外的功能强化。这一增强版专注于优化用户体验和系统兼容性,具体包含以下核心功能的提升: 数据保存:通过优化算法增强了其数据保存能力&…

结构体与联合体的嵌套使用

代码如下 #include <iostream> #include <string> using namespace std;typedef struct t_in_struct1 {int var1;int var2; }name_in_struct1;typedef struct t_in_struct2 {int var3;int var4; }name_in_struct2;typedef struct t_struct {int a;union {name_in_…

重生我是嵌入式大能之串口调试UART

什么是串口 串口是一种在数据通讯中广泛使用的通讯接口&#xff0c;通常我们叫做UART (通用异步收发传输器Universal Asynchronous Receiver/Transmitter)&#xff0c;其具有数据传输速度稳定、可靠性高、适用范围广等优点。在嵌入式系统中&#xff0c;串口常用于与外部设备进…

串口初始化自己独立的见解--第九天

1.SM0,SM1 我们一般用 8位UART&#xff0c;波特率可变 &#xff08;方式1的工作方式&#xff09; SCON &#xff1a;SM2 一般不用&#xff0c;SM0 0 ,SM1 1 PCON : 有两位 我们不动它&#xff0c;不加速&#xff0c;初始值 TMOD&#xff1a;8位自动重装定时器&#xff0…

初识ADMM算法!ADMM算法在分布式配电网调度中的应用程序代码!

前言 随着分布式电源(distributed generation&#xff0c;DG)的渗透率不断提高&#xff0c;传统的配电网系统从被动单向的供电网络转变为功率双向流动的有源网络&#xff0c;使得配电网运行和控制面临诸多新挑战。依靠网络升级或运行结构变化等方法维持配电网可靠运行的成本高…

7 系列 FPGA 产品介绍及选型

目录 Spartan-7 FPGAsArtix-7 FPGAsKintex-7 FPGAsVirtex-7 FPGAsFPGA芯片命名规则DSP资源BRAM资源Transceivers 资源Transceivers 总带宽I/O 个数及带宽参考文档 Spartan-7 FPGAs Artix-7 FPGAs Kintex-7 FPGAs Virtex-7 FPGAs FPGA芯片命名规则 DSP资源 BRAM资源 Transceiver…

代码随想录算法训练营第六十三天|84.柱状图中最大的矩形

代码随想录算法训练营第六十三天|84.柱状图中最大的矩形 84.柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&…

浅谈如何自我实现一个消息队列服务器(7)——编写服务器部分

文章目录 一、编写服务器代码1.1、分析一个服务器应具备的功能1.1.1、成员变量1.1.2、对外提供的接口 一、编写服务器代码 再次拿出这张图&#xff0c;前面我们已经将重要概念&#xff1a;VirtualHost、exchange、msgQueue、message、binding 都实现了&#xff0c;此时就可以开…

【程序设计和c语言-谭浩强配套】(适合专升本、考研)

一晃大半年没更新了&#xff0c;这一年一直在备考&#xff0c;想着这几天把前段时间学的c语言给大家分享一下&#xff0c;在此做了一个专栏&#xff0c;有需要的小伙伴可私信获取o。 简介&#xff1a;本专栏所有内容皆适合专升本、考研的复习资料&#xff0c;本人手上也有日常…

在哪里打印资料比较便宜

在数字时代&#xff0c;我们常常需要在各种文档、资料之间穿梭&#xff0c;然而&#xff0c;有时候我们需要的并不是数字版&#xff0c;而是纸质版。那么&#xff0c;在哪里打印资料比较便宜呢&#xff1f; 琢贝云打印以其超低的价格&#xff0c;优质的打印服务&#xff0c;赢…

HFSS学习-day4-建模操作

通过昨天的学习&#xff0c;我们已经熟悉了HFSS的工作环境&#xff1b;今天我们来讲解HFSS中创建物体模型的县体步骤和相关操作。物体建模是HFSS仿真设计工作的第一步&#xff0c;HFSS中提供了诸如矩形、圆面、长方体圆柱体和球体等多种基本模型(Primitive)&#xff0c;这些基本…

基于SSM的文化遗产的保护与旅游开发系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的文化遗产的保护与旅游开发系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

[C++][数据结构]哈希2:开散列/哈希桶的介绍和简单实现

前言 接着上一篇文章&#xff0c;我们知道了闭散列的弊端是空间利用率比较低&#xff0c;希望今天学习的开散列可以帮我们解决这个问题 引入 开散列法又叫链地址法(开链法)&#xff0c;首先对关键码集合用散列函数计算散列地址**&#xff0c;具有相同地址的关键码归于同一子…

论文研读 Disentangled Information Bottleneck

解耦信息瓶颈 摘要&#xff1a; 信息瓶颈方法是一种从源随机变量中提取与预测目标随机变量相关的信息的技术&#xff0c;通常通过优化平衡压缩和预测项的IB拉格朗日乘子f来实现&#xff0c;然而拉格朗日乘子很难优化&#xff0c;需要多次实验来调整拉格朗日乘子的值&#xff0c…