Linux PCIe驱动框架分析(第二章)
目录
项目背景
1. 概述
2. 数据结构
3. 流程分析
3.1 设备驱动模型
3.2 初始化
3.2.1 pci_bus_match
3.2.2 pci_device_probe
3.3 枚举
项目背景
- Kernel版本:4.14
- ARM64处理器
- 使用工具: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桥去扩展总线;
3. 流程分析
3.1 设备驱动模型
Linux PCI驱动框架,基于Linux设备驱动模型,因此有必要先简要介绍一下,实际上Linux设备驱动模型也是一个大的topic,先挖个坑,有空再来填。来张图吧:
- 简单来说,Linux内核建立了一个统一的设备模型,分别采用总线、设备、驱动三者进行抽象,其中设备与驱动都挂在总线上,当有新的设备注册或者新的驱动注册时,总线会去进行匹配操作(
match
函数),当发现驱动与设备能进行匹配时,就会执行probe函数的操作; - 从数据结构中可以看出,
bus_type
会维护两个链表,分别用于挂接向其注册的设备和驱动,而match
函数就负责匹配检测; - 各类驱动框架也都是基于图中的机制来实现,在这之上进行封装,比如I2C总线框架等;
- 设备驱动模型中,包含了很多
kset/kobject
等内容,建议去看看之前的文章《linux设备模型之kset/kobj/ktype分析》
- 好了,点到为止,感觉要跑题了,强行拉回来。
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设备的各类信息了,在设备驱动匹配模型中,总线和设备都已经具备了,剩下的就是写个驱动了;
Linux PCIe驱动框架分析(第二章)相关推荐
- Linux PCI驱动框架分析:(Peripheral Component Interconnect,外部设备互联)
<DPDK 20.05 | rte_pci_bus思维导图 | 第一版> <linux系统下:IO端口,内存,PCI总线 的 读写(I/O)操作> <Linux指令:ls ...
- Linux USB驱动框架分析 【转】
转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...
- 深入分析Linux PCI驱动框架分析(二)
说明: Kernel版本:4.14 ARM64处理器 使用工具:Source Insight 3.5, Visio 1. 概述 本文将分析Linux PCI子系统的框架,主要围绕Linux PCI子系 ...
- Linux i2c驱动框架分析 (二)
Linux i2c驱动框架分析 (一) Linux i2c驱动框架分析 (二) Linux i2c驱动框架分析 (三) 通用i2c设备驱动分析 i2c core i2c核心(drivers/i2c/i ...
- OS相关驱动 Linux USB驱动框架分析
初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结当然不可缺,更何况我决定为嵌入式卖命了.好,言归正传,我说一说这段时间的收获,跟大家分享一下Linux的驱动开发 ...
- linux pcie驱动框架_Linux设备驱动框架设计
引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Li ...
- linux内核usb驱动框架,基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析
基于S3C2440平台的linux2.6.22内核版本的USB驱动框架分析 发布时间:2014-07-18 16:47:31来源:红联作者:linux08071151 driver/usb/host/ ...
- Linux I2C驱动框架(超详细)
Linux I2C驱动框架 文章目录 Linux I2C驱动框架 一.几个重要的对象 1.I2C总线 2.I2C驱动 3.I2C设备 4.I2C设配器 小结 二.内核源码分析 1.注册I2C驱动 2. ...
- Linux SPI驱动框架(1)——核心层
概述 linux SPI驱动框架主要分为核心层,控制器驱动层以及设备驱动层.具体结构可参考下图 图中,最下层是硬件空间,SPI总线控制器,总线控制器负责硬件上的数据交互.内核空间中,需要有对应 ...
最新文章
- 0x08.基本算法 — 总结与练习
- scala学习笔记-面向对象编程之Trait
- tapable源码分析
- oracle 计划中的view,执行计划里的view
- project template
- 访问 Neutron 外部网络 - 每天5分钟玩转 OpenStack(143)
- css外墙法_外墙设计模式示例
- 2014.9.13模拟赛【数位和乘积】
- Ghost 2.18.3 发布,基于 Markdown 的在线写作平台
- mysql一样的查询在我本地很快但是线上很慢_Mysql读写分离原理及主众同步延时如何解决...
- Sqlite 数据库出现database disk image is malformed报错的解决方法
- 最新浅析java源代码转换为机器码的编译执行过程
- 计算机网络基础中职期中,中职计算机网络基础试题.doc
- 烤仔的朋友们 | 细数11位身价超十亿美元加密富豪,灰度创始人仅排第七
- hdu 4125 Moles
- python_练习2:输入a,b,c,d 4个整数,计算a+b-c*d的结果
- 智能合约--如何实现可升级的智能合约
- 无线路由dns服务器地址,无线路由器更换DHCP地址段、DNS地址设置
- 如何判断产品的生命周期
- 读《互联网创业的四种玩家》有感
热门文章
- 《项目管理就是这么简单》--读书笔记
- Mycat分库分表详细操作
- 维修计算机机房管理员职责,机房管理员职责
- 五证 两书 三表
- Win10如何删除Windowsapps文件夹?Windowsapps文件夹删除方法
- RSNA-MICCAI Brain Tumor Radiogenomic Classification
- Verilog自顶向下设计24进制和60进制计数器(FPGA)
- 解决小程序开发生成B类小程序码scene参数长度受限的问题
- wincc web发布与PHP,西门子wincc组态软件的项目web发布操作步骤
- MySQL关系运算和连接运算_关系数据库系统能够实现的三种基本关系运算