深入分析Linux PCI驱动框架分析(二)

news2025/3/1 9:24:03

说明:

  1. Kernel版本:4.14
  2. ARM64处理器
  3. 使用工具:Source Insight 3.5, Visio

1. 概述

  • 本文将分析Linux PCI子系统的框架,主要围绕Linux PCI子系统的初始化以及枚举过程分析;
  • 如果对具体的硬件缺乏了解,建议先阅读上篇文章详细讲解Linux PCI驱动框架分析(一);

话不多说,直接开始。

2. 数据结构

  • PCI体系结构的拓扑关系如图所示,而图中的不同数据结构就是用于来描述对应的模块;
  • Host Bridge连接CPU和PCI系统,由struct pci_host_bridge描述;
  • struct pci_dev描述PCI设备,以及PCI-to-PCI桥设备;
  • struct pci_bus用于描述PCI总线,struct pci_slot用于描述总线上的物理插槽;

来一张更详细的结构体组织图:

  • 总体来看,数据结构对硬件模块进行了抽象,数据结构之间也能很便捷的构建一个类似PCI子系统物理拓扑的关系图;
  • 顶层的结构为pci_host_bridge,这个结构一般由Host驱动负责来初始化创建;
  • pci_host_bridge指向root bus,也就是编号为0的总线,在该总线下,可以挂接各种外设或物理slot,也可以通过PCI桥去扩展总线;

  资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

3. 流程分析

3.1 设备驱动模型

Linux PCI驱动框架,基于Linux设备驱动模型,因此有必要先简要介绍一下,实际上Linux设备驱动模型也是一个大的topic,先挖个坑,有空再来填。来张图吧:

  • 简单来说,Linux内核建立了一个统一的设备模型,分别采用总线、设备、驱动三者进行抽象,其中设备与驱动都挂在总线上,当有新的设备注册或者新的驱动注册时,总线会去进行匹配操作(match函数),当发现驱动与设备能进行匹配时,就会执行probe函数的操作;
  • 从数据结构中可以看出,bus_type会维护两个链表,分别用于挂接向其注册的设备和驱动,而match函数就负责匹配检测;
  • 各类驱动框架也都是基于图中的机制来实现,在这之上进行封装,比如I2C总线框架等;
  • 设备驱动模型中,包含了很多kset/kobject等内容.

3.2 初始化

既然说到了设备驱动模型,那么首先我们要做的事情,就是先在内核里边创建一个PCI总线,用于挂接PCI设备和PCI驱动,我们的实现来到了pci_driver_init()函数:

  • 内核在PCI框架初始化时会调用pci_driver_init()来创建一个PCI总线结构(全局变量pci_bus_type),这里描述的PCI总线结构,是指驱动匹配模型中的概念,PCI的设备和驱动都会挂在该PCI总线上;
  • 从pci_bus_type的函数操作接口也能看出来,pci_bus_match用来检查设备与驱动是否匹配,一旦匹配了就会调用pci_device_probe函数,下边针对这两个函数稍加介绍;

3.2.1 pci_bus_match

  • 设备或者驱动注册后,触发pci_bus_match函数的调用,实际会去比对vendor和device等信息,这个都是厂家固化的,在驱动中设置成PCI_ANY_ID就能支持所有设备;
  • 一旦匹配成功后,就会去触发pci_device_probe的执行;

3.2.2 pci_device_probe

  • 实际的过程也是比较简单,无非就是进行匹配,一旦匹配上了,直接调用驱动程序的probe函数,写过驱动的同学应该就比较清楚后边的流程了;

3.3 枚举

  • 我们还是顺着设备驱动匹配的思路继续开展;
  • 3.2节描述的是总线的创建,那么本节中的枚举,显然就是设备的创建了;
  • 所谓设备的创建,就是在Linux内核中维护一些数据结构来对硬件设备进行描述,而硬件的描述又跟上文中的数据结构能对应上;

枚举的入口函数:pci_host_probe

  • 设备的扫描从pci_scan_root_bus_bridge开始,首先需要先向系统注册一个host bridge,在注册的过程中需要创建一个root bus,也就是bus 0,在pci_register_host_bridge函数中,主要是一系列的初始化和注册工作,此外还为总线分配资源,包括地址空间等;
  • pci_scan_child_bus开始,从bus 0向下扫描并添加设备,这个过程由pci_scan_child_bus_extend来完成;
  • 从pci_scan_child_bus_extend的流程可以看出,主要有两大块:
  • PCI设备扫描,从循环也能看出来,每条总线支持32个设备,每个设备支持8个功能,扫描完设备后将设备注册进系统,pci_scan_device的过程中会去读取PCI设备的配置空间,获取到BAR的相关信息,细节不表了;
  • PCI桥设备扫描,PCI桥是用于连接上一级PCI总线和下一级PCI总线的,当发现有下一级总线时,创建子结构,并再次调用pci_scan_child_bus_extend的函数来扫描下一级的总线,从这个过程看,就是一个递归过程。
  • 从设备的扫描过程看,这是一个典型的DFS(Depth First Search)过程,熟悉数据结构与算法的同学应该清楚,这就类似典型的走迷宫的过程;

如果你对上述的流程还不清楚,再来一张图:

  • 图中的数字代表的就是扫描的过程,当遍历到PCI桥设备的时候,会一直穷究到底,然后再返回来;
  • 当枚举过程结束后,系统中就已经维护了PCI设备的各类信息了,在设备驱动匹配模型中,总线和设备都已经具备了,剩下的就是写个驱动了;

 

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

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

相关文章

详解c++---vector介绍

这里写目录标题什么是vectorvector的定义reservevector数据插入push_backinsertresizeassignvector数据的删除pop_backeraseclearvector性质查看sizecapacityemptymax_sizevector元素修改operator[ ]atfrontbackvector其他函数operatorswap什么是vector vector是表示可变大小数…

深入浅出Cookie、Session、Token:背后的技术原理

目录 简介 . 网站交互体验升级 1.1 无状态的 HTTP 协议 1.2 解决之道 2. Cookie方案 2.1 Cookie 定义和作用 2.2 服务端创建 Cookie 2.4 存在的问题 3. Session 方案 3.1 Session 机制的概念 3.2 简单的交互流程 3.3 Session 的实现方式 3.4 存在的问题 4. Token…

【微服务】Nacos 认证机制

目录 一、背景 二、需求 三、方案 1、安全架构选型 2、会话管理 2.1、会话选型 2.2、Session 登录流程 2.3、Token 登录流程 2.4、jwt 框架选型 2.5、会话超时 3、SSO 支持 4、UI设计 5、接口设计 6、数据库表设计 6.1、user表 6.2、roles表 7、Filter 拦截请求…

C++ —— 模板的基本概念和使用

目录 1.函数模板是什么 1.1函数模板的基本概念 1.2函数模板的基本使用 1.3函数模板的特化 1.4非类型模板参数 2.类模板是什么 2.1类模板的基本使用 2.2非类型模板参数 2.3类模板的特化 2.4模板特化后的优先级 3.函数模板不要分离编译 1.函数模板是什么 模板是一种…

python和MySQL的基础使用和数据的插入导出

一.基础使用第三方库pymysql除了使用图形化工具以外,我们也可以使用编程语言来执行SQL从而操作数据库。在Python中,使用第三方库:pymysql来完成对MySQL数据库的操作。安装创建到MySQL的数据库链接具体代码如下from pymysql import Connect #获取到MySQL数…

LVS+Keepalived+Nginx宏观整体结构与关键问答

视频链接:4-2 为什么要使用 LVS Nginx?_哔哩哔哩_bilibili ———————————————————————————————————————————————————————— 1. 问题: 为什么要使用LVS Nginx?&#xf…

C语言刮刮乐(掩码图的范例)

程序简介 这个程序模拟了刮刮乐的刮卡操作,按下鼠标左键并移动可以刮开刮卡层。 刮卡操作是通过掩码图实现的,一张隐藏的待刮开背景图,一张掩码图。 刮卡的时候,是在黑色的掩码图上画线,显示的时候,通过…

官方正品 | Ultralytics YOLOv8算法来啦(尖端SOTA模型)

🚀🚀🚀卷王之王 | Ultralytics YOLOv8 算法来啦!!✨✨✨ 一、前言简介 🎄🎈 📚 代码地址:卷王之王 | YOLOv8代码下载地址 📚 详细文档:https://…

代码随想录算法训练营第十四天字符串 java :二叉树理论基础 144前序遍历 145后续遍历94 中序遍历

系列文章目录 第十一天笔记 文章目录系列文章目录前言1、二叉树理论基础1.1二叉树的种类1.1 如何区分二叉树的遍历方式1.2 如何定义二叉树节点2 递归遍历2.1**前序遍历 AC代码**2.2**后序遍历 AC代码**2.3 **中序遍历 AC代码**3 迭代法4 层次遍历总结**什么是List<List <…

组态王软件与S7-1200无线MODBUS通信方案详解

本方案是组态软件与西门子 S7-1200进行无线 MODBUS 通信的实现方法。此方案可以作为西门子 S7-1200与组态软件的无线 MODBUS 通信实例。在本方案中采用了西门子PLC专用无线通讯终端DTD434MC&#xff0c;作为实现无线通讯的硬件设备。 一、方案概述 组态王配置为标准 MODBUS 主…

基础面试问题

在Java中获取当前的工作目录System.getProperty("user.dir")public class Test {public static void main(final String[] args) {final String dir System.getProperty("user.dir");System.out.println("current dir " dir);} }获取一定范围…

Redis01之Windows版本的Redis安装配置

目录 0. 学习网址 https://www.w3cschool.cn/redis/https://www.w3cschool.cn/redis/ 1. Redis简介 2. 下载 3. 安装和配置 3.1 window(略...) 3.2 linux(CentOS) 4. Redis支持五种数据类型 5.通过命令操作redis 0. 学习网址 https://www.w3cschool.cn/redis/http…

一文搞懂CPU如何控制I/O设备

1 接口和设备&#xff1a;经典适配器模式 输入输出设备不只是一个设备。大部分输入输出设备&#xff0c;都有&#xff1a; 它的接口&#xff08;Interface&#xff09;实际的I/O设备&#xff08;Actual I/O Device&#xff09; 硬件设备并非直接接入到总线上和CPU通信&#…

UOS 录制电脑播放的音频 / 内录音频

Windows 里面有一个“立体声混音”&#xff0c;可以内录电脑播放的音频&#xff0c;而不受到外界噪音的干扰。前段时间接到反馈说 UOS 的设置里面的音频输入里面没有可以选择的设备&#xff0c;这里就稍微探索了一下&#xff0c;发现 UOS 也是可以配置内录的。这里参考了一下这…

网络基础(一)

网络基础&#xff08;一&#xff09;计算机网络背景网络发展独立模式: &#xff08;计算机之间相互独立&#xff09;网络互联: ( 多台计算机连接在一起, 完成数据共享)局域网LAN: (计算机数量更多了, 通过交换机和路由器连接在一起);广域网WAN: &#xff08;将远隔千里的计算机…

vue入门到精通(一)

一、vue简介 Vue是一款用于构建用户界面的 JavaScript 框架。 它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 二、vue3选项式…

Linux编译器-gcc/g++使用

目录 1. 背景知识 2. gcc如何完成 2.1 预处理(进行宏替换) 2.2 编译&#xff08;生成汇编&#xff09; 2.3 汇编&#xff08;生成机器可识别代码&#xff09; 2.4 链接&#xff08;生成可执行文件或库文件&#xff09; 3 函数库 3.1 分类 3.2 图解 4 gcc选项 1. 背景知…

开源工具系列2:Trivy

在云原生安全的场景中&#xff0c;一个常见的场景就是对漏洞和配置进行扫描&#xff0c;以发现整个 K8s 环境的安全问题。今天我们来介绍一个高效的扫描工具Trivy。 Trivy 是什么 Trivy&#xff08;tri 发音为 trigger&#xff0c;vy 发音为 envy&#xff09;是一个简单而全面…

QT 学习笔记(十七)

文章目录一、多线程简介1. 基础知识2. 多线程的优缺点及注意事项二、多线程详解1. 背景案例2. 通过多线程对背景案例进行优化3. 方法一&#xff1a;多线程的创建使用&#xff08;QT 4.7 以前&#xff09;3.1 方法一的创建步骤3.2 方法一的具体实现及实现代码4. 方法二&#xff…

Android Hook之Frida安装使用

目录Frida安装安装frida-serverfrida-server配置和启动Frida Hook实例1&#xff1a;实例2&#xff1a;Frida 常用命令Frida 是一个动态检测框架&#xff0c;允许开发人员在 Windows、macOS、Linux、iOS 和 Android 上的原生应用程序中注入 JavaScript 或 Python 脚本。该框架可…