深入分析 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
英文地址,請注明出處:http://en.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學年第一學期班級點名冊模版(雙休國定假…