深入分析 Linux PCI Express 子系统

深入分析 Linux PCI Express 子系统

一、PCI Express 工作原理

PCIe 是一种高速串行点对点互连协议,采用分层架构:

TLP包
DLLP包
电气信号
事务层
数据链路层
物理层
物理介质
  1. 事务层:处理TLP(事务层包),包括读/写请求和完成报文
  2. 数据链路层:处理DLLP(数据链路层包),负责错误检测和重传
  3. 物理层:处理电气信号、时钟恢复和链路训练

关键特性:

  • 点对点拓扑
  • 差分信号传输
  • 基于信用的流控
  • 多种数据包类型(Memory, IO, Config, Message)
二、Linux PCIe 实现机制

代码架构

PCI Core
Host Controller Drivers
Endpoint Drivers
ECAM Access
设备操作
  1. 枚举过程

    • BIOS/UEFI 或内核扫描总线
    • 分配设备ID(BDF:Bus, Device, Function)
    • 资源配置(BAR, IRQ)
  2. 地址空间

    • 配置空间:256字节/4KB(PCIe扩展)
    • BAR空间:内存映射I/O(MMIO)或端口I/O
三、核心数据结构
  1. struct pci_dev (include/linux/pci.h)
struct pci_dev {struct list_head bus_list;  // 总线链表struct pci_bus *bus;        // 所属总线unsigned int devfn;         // 设备功能号u16 vendor;                 // 厂商IDu16 device;                 // 设备IDstruct resource resource[DEVICE_COUNT_RESOURCE]; // BAR资源struct pci_driver *driver;  // 绑定驱动// ...
};
  1. struct pci_driver (include/linux/pci.h)
struct pci_driver {const char *name;const struct pci_device_id *id_table; // 设备ID表int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); // 探测函数void (*remove)(struct pci_dev *dev);   // 移除函数// ...
};
  1. struct pci_bus (include/linux/pci.h)
struct pci_bus {struct list_head devices;   // 设备列表struct pci_dev *self;       // 桥接设备struct resource *resource[PCI_BRIDGE_RESOURCE_NUM]; // 总线资源// ...
};
四、简单实例:PCIe 设备驱动
#include <linux/module.h>
#include <linux/pci.h>#define VENDOR_ID 0x1234
#define DEVICE_ID 0x5678static int my_probe(struct pci_dev *dev, const struct pci_device_id *id)
{int ret;void __iomem *regs;// 启用设备if ((ret = pci_enable_device(dev)))return ret;// 请求内存区域if ((ret = pci_request_regions(dev, "my_driver")))goto disable_dev;// 映射BAR0regs = pci_iomap(dev, 0, pci_resource_len(dev, 0));if (!regs) {ret = -ENOMEM;goto release_regions;}// 示例:读取设备IDu32 dev_id = ioread32(regs + 0x00);printk(KERN_INFO "Device ID: 0x%x\n", dev_id);return 0;release_regions:pci_release_regions(dev);
disable_dev:pci_disable_device(dev);return ret;
}static void my_remove(struct pci_dev *dev)
{pci_iounmap(dev, regs);pci_release_regions(dev);pci_disable_device(dev);
}static const struct pci_device_id my_ids[] = {{ PCI_DEVICE(VENDOR_ID, DEVICE_ID) },{ 0, }
};
MODULE_DEVICE_TABLE(pci, my_ids);static struct pci_driver my_driver = {.name = "my_pcie_driver",.id_table = my_ids,.probe = my_probe,.remove = my_remove,
};module_pci_driver(my_driver);MODULE_LICENSE("GPL");
五、常用工具与调试手段

工具命令

命令功能
lspci -vvv查看PCI设备详细信息
setpci -s 00:01.0 CAP_EXP+8.w读取扩展能力寄存器
cat /proc/iomem查看内存映射
dmesg -l debug查看内核调试信息

Debug 方法

  1. 内核日志级别调整:
    echo 8 > /proc/sys/kernel/printk
    
  2. 动态调试:
    echo "file pci* +p" > /sys/kernel/debug/dynamic_debug/control
    
  3. SysFS 接口:
    ls /sys/bus/pci/devices/0000:01:00.0/
    # resource0  - BAR0映射
    # config     - 原始配置空间
    # reset      - 触发设备复位
    
六、关键流程图示

设备枚举流程

BIOS/UEFILinux KernelPCI DriverACPI表传递PCI信息pci_scan_root_bus()pci_scan_child_bus()分配BDF号读取BAR并分配资源loop[扫描每条总线-]匹配id_tableprobe()执行BIOS/UEFILinux KernelPCI Driver

配置空间访问机制

sysfs
读配置
写配置
用户空间
PCI SysFS
操作类型
pci_user_read_config
pci_user_write_config
PCIe ECAM
硬件寄存器
七、高级调试技巧
  1. EDAC 检查
    edac-util -v
    
  2. PCIe 链路状态
    lspci -vvv -s 00:01.0 | grep LnkSta
    
  3. 错误注入测试
    // 内核配置
    CONFIG_PCIEAER_INJECT=y
    echo "0000:01:00.0" > /sys/kernel/debug/pci_inject/device
    echo "1" > /sys/kernel/debug/pci_inject/do_air_inject
    
八、性能优化表
优化方向方法内核API
DMA性能使用64位DMAdma_set_mask_and_coherent()
中断延迟MSI/MSI-Xpci_alloc_irq_vectors()
带宽利用率最大有效载荷大小pcie_set_readrq()
电源管理ASPM控制pci_disable_link_state()

通过以上分析,可全面掌握Linux PCIe子系统的工作原理、实现机制和开发方法。实际开发中建议结合内核文档(Documentation/PCI/)和具体硬件手册进行深入实践。

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

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

相关文章

MySQL 运算符详解:逻辑、位运算与正则表达式应用

MySQL 运算符详解&#xff1a;逻辑、位运算与正则表达式应用 在 MySQL 中&#xff0c;运算符是构建复杂查询条件的基础。除了基础的算术和比较运算符&#xff0c;逻辑运算符、位运算符以及正则表达式的灵活运用&#xff0c;能让数据筛选更加精准高效。本文将系统讲解这些运算符…

<数据集>遥感飞机识别数据集<目标检测>

数据集下载链接https://download.csdn.net/download/qq_53332949/91702190数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;3842张 标注数量(xml文件个数)&#xff1a;3842 标注数量(txt文件个数)&#xff1a;3842 标注类别数&#xff1a;20 标注类别名称&#xf…

Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南

目录Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南前言第一部分&#xff1a;安装前准备1.1 系统要求检查1.2 下载安装包1.3 验证安装包完整性第二部分&#xff1a;安装KingbaseES2.1 启动安装程序2.2 接受许可协议2.3 选择授权文件2.4 设置安装目录2.5 选择安装…

Git+Jenkins 基本使用

一、什么是 JenkinsJenkins 是一个功能强大的应用程序&#xff0c;允许持续集成和持续交付项目&#xff08;持续部署&#xff09;&#xff0c;无论用的是什么平台。这是一个免费的源代码&#xff0c;可以处理任何类型的构建或持续集成。集成 Jenkins 可以用于一些测试和部署技术…

Linux第十三讲:线程同步和互斥

Linux第十三讲&#xff1a;线程同步和互斥1.线程互斥1.1进程线程间的互斥背景概念1.2什么是锁1.2.1认识锁&#xff0c;理解锁2.线程同步2.1条件变量2.2生产和消费模型2.3基于阻塞队列(blockqueue)的生产消费模型2.3.1单生产&#xff0c;单消费的阻塞队列模拟实现2.3.2多生产&am…

SAP 简单的AMDP demo 练习使用

SAP AMDP&#xff08;ABAP Managed Database Procedure&#xff09;是SAP的一项先进技术&#xff0c;用于在SAP HANA数据库上执行高性能的数据库操作。它允许ABAP开发人员编写数据库过程&#xff0c;这些过程可以在数据库级别上执行&#xff0c;从而实现更快的数据处理和更高的…

Maven JAR Plugin 插件使用说明

Maven JAR Plugin 插件使用说明1 Maven JAR Plugin 插件地址2 Maven JAR Plugin 特点3 maven-assembly-plugin 的用法3.1 无依赖项 maven-jar-plugin 配置3.2 有依赖项 maven-jar-plugin 配置3.3 配合maven-dependency-plugin 将依赖复制到指定位置1 Maven JAR Plugin 插件地址…

QT+Yolov8 推理部署,ONNX模型 ,实例分割+目标检测

QTYolov8 实例分割、目标检测推理。QT源码。 程序准备/版本:QT creator QT6.8 编译器:MSVC2022 opencv:4.7 onnxruntime:1.16.0 cpu版本 QTyolo推理部署程序部分源码: #include "aitoolinterface.h" #include "ui_aitoolinterface.h" #include <QDebu…

【java实现一个接口多个实现类通用策略模式】

java实现同个接口多个实现类通用策略模式 项目业务中&#xff0c;有多个平台&#xff0c;多个平台直接有相同的业务&#xff0c;只有一个接口入口&#xff0c;但是 不同的平台入口&#xff0c;虽然接口相同&#xff0c;参数相同&#xff0c;但是各自的具体实现不同&#xff0c;…

leetcode-139. 单词拆分-C

暴力回溯回溯过程就是一个决策树模型&#xff0c;从所有选择中找到合适的继续&#xff0c;否则回到上一级继续。该方法思路简单&#xff0c;时间复杂度过高&#xff0c;大概1/4的用例超时。 bool backtrack(char *s, int cur, char** wordDict, int wordDictSize) {// 基线条件…

《彩色终端》诗解——ANSI 艺术解码(DeepSeek)

AIi诗解通吾灵&#xff0c;直抄原文享分玲。 笔记模板由python脚本于2025-08-18 23:35:59创建&#xff0c;本篇笔记适合喜欢诗&代码的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述。 Python官网…

抓包工具tcpdump详细指南

目录 1. 核心功能与特性 2. 关键参数速查表 3. 基础命令 3.1 协议/端口过滤 3.2 IP 地址过滤 3.3 高级逻辑组合 3.4 控制输出详细度 3.5 解析包内容 3.6 特殊包过滤 3.7 限制抓包数量 3.8 过滤特定大小包 3.9 过滤提升性能 ​​​​​​3.10 多网卡绑定 3.11 高级…

三高架构杂谈

我们的秒杀请求到了tomcat之后&#xff0c;我整个请求到了后端&#xff0c;我们怎么抗住高并发 也就是让他1s抗住10w的订单量&#xff0c;该怎么做 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>…

后端通用基础代码

后端通用基础代码 通用基础代码是指&#xff1a;“无论在任何后端项目中&#xff0c;都可以复用的代码。这种代码一般 “一辈子只用写一次” &#xff0c;了解作用之后复制粘贴即可&#xff0c;无需记忆。 目录结构如下&#xff1a;1、自定义异常 自定义错误码&#xff0c;对错…

基于51单片机WIFI心率计脉搏体温测量仪APP设计

1 系统功能介绍 本设计基于 STC89C52 单片机&#xff0c;结合 脉搏传感器、温度传感器 DS18B20、LCD1602 液晶显示器、WiFi 模块 等外设&#xff0c;构建了一个 WiFi 心率计脉搏体温测量仪 APP 系统。系统能够实现对人体心率与体温的实时采集、处理、显示和远程上传&#xff0c…

从零到一构建企业级GraphRAG系统:GraphRag.Net深度技术解析

当RAG遇上知识图谱&#xff0c;会碰撞出怎样的火花&#xff1f;本文将带你深入探索GraphRag.Net这个开源项目&#xff0c;看看如何用.NET技术栈打造一个企业级的图谱增强检索系统。 引言&#xff1a;为什么我们需要GraphRAG&#xff1f; 在AI大模型时代&#xff0c;RAG&#x…

前端Element-plus的选择器 el-select 清空内容时,后端对应的更新方式,支持更新为null

1、所属小类选择器 el-select 清空内容时&#xff0c;前端通过事件设置为空字符串clear"handleSmallCategoryClear"【所属小类选择器】只能选择&#xff0c;不能输入信息<script setup lang"ts" name"QualityFileInfoDialog"> ...... // 所…

【笔记】和各大AI大语言模型合作写项目—slirp.go

最近和各大AI大语言模型一起合作写了个小项目&#xff0c;让大家看看AI离取代人类还差多远。 开发大家都在一个共享环境下&#xff0c;连docker都不能运行&#xff0c;rootless也没有。不过好在linux环境&#xff0c;弄个proot能apt或者yum install自由&#xff0c;但是诸如pod…

国标:开展环境卫生满意度调查

随着社会的进步和人们生活水平的提高&#xff0c;&#xff08;满意度调查&#xff09;&#xff08;问卷调查&#xff09;&#xff08;第三方市场咨询公司&#xff09;对生活品质的追求以及对环境保护的重视已经成为了当下社会的主旋律。在这样的背景下&#xff0c;环境卫生问题…

【办公类-54-08】20250902 2025学年第一学期班级点名册模版(双休国定假涂成灰色、修改标题和页眉,批量导出PDF)根据新Excel模版,标题增加园区、空姓名行填充灰色

背景需求: 之前做了优化过的点名册 【办公类-54-07】20250901 2025学年第一学期班级点名册模版(双休国定假涂成灰色、修改标题和页眉,批量导出PDF)-CSDN博客文章浏览阅读984次,点赞27次,收藏29次。【办公类-54-07】20250901 202学年第一学期班级点名册模版(双休国定假…