注:本文为“”相关文章合辑。
略作重排,机翻未校。
如有内容异常,请看原文。
Demystifying the Powerful lspci Command on Linux
揭开 Linux 中强大的 lspci 命令的神秘面纱
November 5, 2023
The lspci
utility is one of the most invaluable tools in a Linux user’s troubleshooting toolkit. At some point, we’ve all typed lspci
and parsed the output to examine hardware info. But hidden under its simple surface are capabilities that can empower Linux experts and budding enthusiasts alike.
lspci
工具是 Linux 用户故障排除工具箱中最有价值的工具之一。我们都在某个时候输入过 lspci
并解析输出以检查硬件信息。但在其简单的表面之下,隐藏着一些能够为 Linux 专家和初学者提供强大功能的能力。
In this comprehensive guide, we’ll unpack everything the venerable lspci
command can do. You’ll learn about PCI basics, understand the different output formats, see how to process and filter the results, and apply lspci
to real-world scenarios. Follow along to master this versatile utility!
在这份全面的指南中,我们将深入探讨 lspci
命令的所有功能。你将学习 PCI 基础知识,了解不同的输出格式,学习如何处理和过滤结果,并将 lspci
应用于实际场景。跟随我们一起掌握这个多功能的工具!
A Brief History of PCI and PCIe
PCI 和 PCIe 的简要历史
To understand lspci
, we must first understand PCI – the Peripheral Component Interconnect standard. PCI provides the interface that allows various hardware devices to be connected and communicate with the CPU and memory.
要理解 lspci
,我们首先需要了解 PCI——即外设组件互连标准。PCI 提供了一种接口,允许各种硬件设备连接并与 CPU 和内存进行通信。
The original PCI standard was introduced in the early 1990s by Intel as a replacement for older expansion buses like ISA and MCA. At the time, it offered major advantages:
最初的 PCI 标准由英特尔在 20 世纪 90 年代初引入,以取代旧的扩展总线(如 ISA 和 MCA)。当时,它带来了几项重大优势:
- Plug and Play – Devices could be automatically configured at boot.
即插即用——设备可以在启动时自动配置。 - Performance – PCI provided higher maximum bandwidth vs previous standards.
性能——与之前的标凈相比,PCI 提供了更高的最大带宽。 - Flexibility – Mixing different kinds of devices on one bus became easier.
灵活性——在一个总线上混用不同类型设备变得更加容易。
PCI gained widespread industry adoption during the 1990s and remained the go-to standard for years. It enabled everything from graphics cards to USB controllers to be installed and accessed using a consistent method.
PCI 在 20 世纪 90 年代获得了广泛的行业采用,并在多年间一直是首选标准。它使得从显卡到 USB 控制器的各种设备都可以通过一致的方法进行安装和访问。
By the early 2000s, work was underway on PCI Express (PCIe). It delivered major upgrades while maintaining backwards compatibility:
到 2000 年代初,PCI Express(PCIe)的研发工作已经开始。它在保持向后兼容性的同时带来了重大升级:
- Higher bandwidth – PCIe moved to high-speed serial links rather than PCI’s shared parallel bus.
更高的带宽——PCIe 采用了高速串行链路,而不是 PCI 的共享并行总线。 - Scalability – Speed can be scaled by adding more lanes to a PCIe slot.
可扩展性——通过增加 PCIe 插槽的通道数量可以提升速度。 - Hot swappability – Devices can be plugged and unplugged while powered.
热插拔能力——设备可以在通电状态下插拔。
Today PCI Express, currently on revision 5.0, provides the interconnect fabric for most modern computer systems. But hundreds of millions of legacy PCI devices are still in use. This is where lspci
comes in!
如今,PCI Express 已经发展到 5.0 版本,为大多数现代计算机系统提供了互连架构。但仍有数亿台旧的 PCI 设备在使用。这就是 lspci
的用武之地!
Introducing the lspci Command
介绍 lspci 命令
The name lspci clues us into its purpose. It lsts details about pci devices on the system. Running a simple lspci
prints out a summary of PCI info:
lspci 的名称揭示了它的用途。它会列出系统上 pci 设备的详细信息。运行一个简单的 lspci
命令可以打印出 PCI 信息的概要:
$ lspci
00:00.0 Host bridge: Intel Corporation Xeon E31220 (rev 13)
00:01.0 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 1 (rev b5)
00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04)
01:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 710] (rev a1)
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
This output reveals key hardware details at a glance. We can see the CPU model, chipset, USB controller, graphics card, network interface card, and more.
此输出一目了然地揭示了关键硬件细节。我们可以看到 CPU 型号、芯片组、USB 控制器、显卡、网卡等信息。
The default lspci output contains 5 main fields per device:
默认的 lspci 输出包含每个设备的 5 个主要字段:
- Slot – The PCI slot in
bus:device.function
notation
插槽——PCI 插槽的表示方式为bus:device.function
。 - Class – Type of device like VGA or network controller
类别——设备类型,例如 VGA 或网络控制器。 - Vendor – Company that made the device
供应商——制造该设备的公司。 - Device – Specific model name or ID
设备——具体型号名称或 ID。 - Revision – Version of this device model
版本——此设备型号的版本。
With no other options, lspci simply provides a quick summary of the PCI hardware makeup. But that’s just scratching the surface of what it can do! Let’s dig deeper.
如果不使用其他选项,lspci 只会提供一个关于 PCI 硬件组成的快速概览。但这只是它功能的冰山一角!让我们深入探索。
Early Hardware Detection Without lspci
没有 lspci 时的早期硬件检测
In the early Linux days before lspci existed, detecting PCI hardware often involved directly probing the PCI configuration spaces. This was challenging and very low-level work.
在 lspci
出现之前的早期 Linux 时代,检测 PCI 硬件通常需要直接探测 PCI 配置空间。这是一项极具挑战性且非常底层的工作。
Some helpful tools appeared in the mid to late 90s to abstract away the details. These included:
在 20 世纪 90 年代中期到晚期,一些有助于简化这些细节的工具出现了。它们包括:
- scanpci – Scanned PCI buses and printed a text summary similar to modern lspci.
scanpci——扫描 PCI 总线并打印出类似现代lspci
的文本摘要。 - listpci – An ncurses interface showing a tree-view of PCI devices.
listpci——一个带有 ncurses 界面的工具,以树形视图显示 PCI 设备。 - phb – Provided a GUI for exploring the PCI bus with some basic device info.
phb——提供了一个用于探索 PCI 总线的图形界面,并显示一些基本的设备信息。
Eventually pciutils emerged, collecting various utilities to handle PCI tasks. The lspci command it provided quickly became the standard for querying PCI hardware on Linux.
最终,pciutils 出现了,它整合了多种用于处理 PCI 任务的工具。它提供的 lspci 命令很快成为了在 Linux 上查询 PCI 硬件的标准工具。
Getting Verbose With lspci -v and -vv
使用 lspci -v 和 -vv 获取详细信息
While plain lspci offers a quick overview, the -v
flag provides much more detail about each device:
虽然简单的 lspci
只提供一个快速概览,但 -v
选项可以提供关于每个设备的更多详细信息:
$ lspci -v
01:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 710] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Micro-Star International Co., Ltd. [MSI] GK208B [GeForce GT 710]
Flags: bus master, fast devsel, latency 0, IRQ 16, NUMA node 0
Memory at fb000000 (32-bit, non-prefetchable) [size=16M]
Memory at e8000000 (64-bit, prefetchable) [size=128M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at e000 [size=128]
[virtual] Expansion ROM at 000c0000 [disabled] [size=128K]
Capabilities: <access denied>
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Now we can see detailed information like:
现在我们可以看到以下详细信息:
- IRQ and NUMA node
中断请求(IRQ)和非统一内存访问(NUMA)节点。 - Memory addresses and sizes
内存地址和大小。 - I/O port range
输入/输出端口范围。 - Capabilities and expansion ROM
功能和扩展 ROM。 - Importantly, the kernel driver in use!
重要的是,正在使用的内核驱动程序!
Using -vv
will produce an even more verbose output with additional details about the device.
使用 -vv
会生成更详细的输出,包含更多关于设备的信息。
Matching Devices to Kernel Drivers
将设备与内核驱动程序匹配
Speaking of drivers, one great use for lspci
is verifying which kernel driver is handling a device. The -k
option is perfect for this:
说到驱动程序,lspci
的一个很好的用途是验证哪个内核驱动程序正在管理某个设备。-k
选项非常适合此用途:
$ lspci -k
01:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 710] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] GK208B [GeForce GT 710]
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Here we can confirm the Nvidia GPU is using the nvidia
driver as expected. If the driver is incorrect or missing, that’s a clue to issues like:
在这里,我们可以确认 Nvidia GPU 正在使用预期的 nvidia
驱动程序。如果驱动程序不正确或缺失,这可能是以下问题的线索:
- Loading the wrong kernel module
加载了错误的内核模块。 - Driver lacking support for that hardware
驱动程序不支持该硬件。 - Drive driver not loaded/installed at all
驱动程序未加载/安装。
Checking lspci -k
output alongside lsmod
lists of loaded modules can help identify and resolve such problems.
将 lspci -k
的输出与 lsmod
列出的已加载模块一起检查,可以帮助识别和解决这些问题。
Decoding PCI Device IDs
解码 PCI 设备 ID
The vendor and device ID combo reveals the exact hardware model. For widely known vendors like Nvidia, Intel, AMD etc. we can often guess the model from the name.
供应商 ID 和设备 ID 的组合可以揭示确切的硬件型号。对于像 Nvidia、Intel、AMD 等广为人知的供应商,我们通常可以从名称中猜测出型号。
But for lesser known device makers, looking up the IDs can uncover the specific chipset or card model. Online resources like PCILookup can be invaluable for ID decoding.
但对于不太知名的设备制造商,查找这些 ID 可以揭示特定的芯片组或卡型号。像 PCILookup 这样的在线资源对于解码 ID 非常有价值。
For example, here is part of an lspci
output:
例如,这是 lspci
输出的一部分:
03:00.0 Network controller: Device 1a56:1535
Feeding the vendor ID 1a56
and device ID 1535
into PCILookup reveals this is a Qualcomm Atheros QCA6174 802.11ac wireless card.
将供应商 ID 1a56
和设备 ID 1535
输入到 PCILookup 中,可以发现这是一张 Qualcomm Atheros QCA6174 802.11ac 无线网卡。
Having the exact model is useful when researching hardware-specific issues or drivers.
知道确切的型号对于研究硬件特定问题或驱动程序非常有用。
Parsing and Processing lspci Output
解析和处理 lspci
输出
While simply reading lspci
output gives an overview, for programmatic use we often want to parse and filter the results.
虽然直接阅读 lspci
的输出可以提供一个概览,但在编程使用中,我们通常需要解析和过滤结果。
Piping to grep
is handy for finding devices by name, driver, vendor etc:
将输出通过管道传递给 grep
可以方便地按名称、驱动程序、供应商等查找设备:
$ lspci | grep -i ethernet
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
Utilities like sed
, awk
, cut
and others help extract specific fields:
像 sed
、awk
、cut
等工具可以帮助提取特定字段:
$ lspci | cut -d" " -f 3 | sort | uniq
AMD
Intel Corporation
NVIDIA Corporation
Qualcomm Atheros
Realtek Semiconductor Co., Ltd.
Or formatting as JSON/CSV for importing into databases and other programs:
或者将其格式化为 JSON/CSV,以便导入到数据库和其他程序中:
$ lspci -mm -k | jq
[
{
"slot": "00:00.0",
"class": "Host bridge",
"vendor": "Intel Corporation",
"device": "Xeon E31220",
"svendor": "Intel Corporation",
"sdevice": "Xeon E31220",
"phy_slot": "0",
"revision": "13",
"driver": "rte_kni"
},
{
"slot": "00:01.0",
"class": "PCI bridge",
"vendor": "Intel Corporation",
"device": "6 Series/C200 Series Chipset Family PCI Express Root Port 1",
"svendor": "Intel Corporation",
"sdevice": "6 Series/C200 Series Chipset Family PCI Express Root Port 1",
"phy_slot": "0",
"revision": "b5",
"driver": "pcieport"
}
]
These processing and filtering examples only scratch the surface of what’s possible. The output can be fed into everything from regular expressions to machine learning!
这些处理和过滤示例只是冰山一角。输出可以用于正则表达式、机器学习等各种场景!
Real-World Troubleshooting with lspci
使用 lspci 进行实际故障排除
Where lspci
really shines is identifying hardware issues in real-world troubleshooting scenarios:
lspci
在实际故障排除场景中真正发光发热的地方是识别硬件问题:
- Flaky device errors – Pinpoint exactly which PCI device is malfunctioning based on logs or symptoms.
设备故障——根据日志或症状精确定位哪个 PCI 设备出现故障。 - Driver conflicts – Spot different drivers mistakenly bound to the same device, or driver mismatch issues.
驱动程序冲突——发现错误地绑定到同一设备的不同驱动程序,或驱动程序不匹配问题。 - Passthrough problems – Virtualization tools rely on correct PCI IDs to bind devices.
lspci
helps verify passthrough is working.
透传问题——虚拟化工具依赖正确的 PCI ID 来绑定设备。lspci
可以帮助验证透传是否正常工作。 - Newly added PCIe cards – Quickly check new expansion cards are detected and using the right driver.
新添加的 PCIe 卡——快速检查新扩展卡是否被检测到并使用了正确的驱动程序。 - Enumerate hardware – Catalog all devices in a system, useful for documentation and inventory.
枚举硬件——列出系统中的所有设备,这对于文档编写和库存管理非常有用。
These are just a few examples – creative sysadmins can apply lspci
to debug all kinds of PCI related issues!
这些只是几个例子——富有创造力的系统管理员可以将 lspci
应用于调试各种与 PCI 相关的问题!
Tuning lspci Output for Desktops vs. Servers
根据桌面和服务器调整 lspci 输出
lspci
usage differs slightly depending on the system role…
lspci
的使用方式会根据系统的角色略有不同……
For desktop and laptop troubleshooting, important options include:
对于 桌面和笔记本电脑 的故障排除,重要的选项包括:
-v
/-vv
for getting driver and IRQ info about devices
-v
/-vv
用于获取设备的驱动程序和 IRQ 信息。-k
to identify problematic driver mismatches
-k
用于识别有问题的驱动程序不匹配。-nn
to show internal device names
-nn
用于显示内部设备名称。
On servers, key use cases are:
在 服务器 上,关键用例包括:
-t
for tree-view, helpful for PCIe topology issues
-t
用于树形视图,有助于解决 PCIe 拓扑问题。-s
to show slot info on systems with multiple bridges
-s
用于在具有多个桥接的系统中显示插槽信息。-vvv
when maximum detail is needed debugging exotic errors
-vvv
用于在调试罕见错误时需要最大详细信息。
And on embedded hardware like routers, -xxx
can sometimes reveal secrets not shown at lower verbosity levels!
而在 嵌入式 硬件(如路由器)上,-xxx
有时可以在较低详细级别下揭示未显示的秘密!
Consuming lspci Programmatically
以编程方式使用 lspci
While we normally run lspci
manually to examine output, it can also be consumed by scripts and programs.
虽然我们通常手动运行 lspci
来检查输出,但它也可以被脚本和程序使用。
Some examples:
一些例子包括:
- Bash scripts that parse
lspci
output to automate tasks like inventory.
解析lspci
输出以自动执行库存任务的 Bash 脚本。 - C programs that call
lspci
vialibpci
to pull hardware details into an app.
通过libpci
调用lspci
将硬件详细信息拉入应用程序的 C 程序。 - Python fetching JSON/CSV output as input to ML classification/identification.
将 JSON/CSV 输出作为机器学习分类/识别输入的 Python。 - Web apps and tools invoking
lspci
on the backend to feed interfaces and APIs.
在后端调用lspci
为界面和 API 提供数据的 Web 应用程序和工具。 - Gathering metrics – changes in
lspci
output triggered alerts about hardware issues.
收集指标——lspci
输出的变化触发了关于硬件问题的警报。 - PCI device driver modules relying on
lspci
IDs for initialization.
依赖lspci
ID 进行初始化的 PCI 设备驱动程序模块。
The simple text-based output makes lspci
easy to leverage as a building block in all kinds of applications.
简单的基于文本的输出使得 lspci
可以轻松地作为各种应用程序的构建块。
Alternatives to lspci
lspci 的替代品
While lspci
is the go-to for PCI info on Linux, there are alternatives with different capabilities:
虽然 lspci
是 Linux 上获取 PCI 信息的首选工具,但也有一些具有不同功能的替代品:
- dmidecode – DMI/SMBIOS data from the BIOS about system hardware.
dmidecode——来自 BIOS 的系统硬件 DMI/SMBIOS 数据。 - hwinfo – Similar to lspci but with additional details from other sources.
hwinfo——类似于lspci
,但来自其他来源的额外详细信息。 - inxi – User-friendly output combining multiple system info tools.
inxi——用户友好的输出,结合了多个系统信息工具。 - HardInfo – GTK/Qt app that nicely visualizes hardware data.
HardInfo——一个 GTK/Qt 应用程序,可以很好地可视化硬件数据。 - sysfs – Raw PCI device details under /sys, useful for development.
sysfs——/sys 下的原始 PCI 设备详细信息,对于开发非常有用。
Each has pros and cons – lspci
is hard to beat for quick, concise PCI insights from the command line.
每种工具都有其优缺点——在命令行中快速、简洁地获取 PCI 信息方面,lspci
难以被击败。
Conclusion
总结
We’ve only scratched the surface of lspci
– there’s much more to discover! Here are some key takeaways:
我们只是触及了 lspci
的皮毛——还有更多内容有待发现!以下是一些要点:
- Check
lspci
to quickly summarize PCI devices on any Linux system.
使用lspci
快速总结任何 Linux 系统上的 PCI 设备。 - Use
-v
,-vv
,-k
for progressively more driver and hardware details.
使用-v
、-vv
、-k
获取越来越多的驱动程序和硬件详细信息。 - Identify the exact model from vendor/device IDs when names are unclear.
当名称不清楚时,通过供应商/设备 ID 确定确切型号。 - Filter, process and consume output programmatically.
以编程方式过滤、处理和消费输出。 - Apply
lspci
creatively to pinpoint failing/misconfigured hardware.
创造性地使用lspci
来精确定位失败/配置错误的硬件。 - Adjust verbosity and tree levels depending on desktop vs. server role.
根据桌面和服务器的角色调整详细程度和树形级别。 - Leverage as a building block for scripts, apps and tools.
将其作为脚本、应用程序和工具的构建块。
I hope you’ve discovered that lspci
is far more powerful than a simple device lister. Master it, and you hold the keys to unlocking the mysteries of practically any Linux machine’s PCI hardware secrets!
希望你已经发现,lspci
远远不止是一个简单的设备列表工具。掌握它,你就能揭开几乎所有 Linux 机器 PCI 硬件秘密的神秘面纱!
Demystifying PCI in Linux: An In-Depth Technical Guide
揭开 Linux 中 PCI 的神秘面纱:一份深入的技术指南
November 14, 2023
As Linux continues its dominance in the data center and cloud computing, having a deep understanding of how core technologies like PCI work under the hood is more important than ever. This comprehensive reference guide aims to fully demystify PCI and how it’s utilized on Linux systems. Whether you’re a systems engineer, kernel hacker, or simply interested in some nitty-gritty technical details – read on for an indispensable resource on all things PCI in Linux!
随着 Linux 在数据中心和云计算中的持续主导地位,深入了解像 PCI 这样的核心技术的工作原理变得比以往任何时候都更加重要。这份全面的参考指南旨在彻底揭开 PCI 以及它在 Linux 系统上的使用方式的神秘面纱。无论你是系统工程师、内核黑客,还是仅仅对一些技术细节感兴趣——继续阅读,获取关于 Linux 中 PCI 的所有内容的不可或缺的资源!
Introduction to PCI
PCI 简介
PCI, which stands for Peripheral Component Interconnect, is a standard local bus interface specification that was originally developed in the early 90s by Intel. It provides a way for peripherals and expansion cards to be connected to a computer’s motherboard and CPU. Initially, it replaced older standards like ISA and EISA with a higher-performance bus architecture.
PCI 代表外设组件互连,是一种标准的本地总线接口规范,最初由英特尔在 20 世纪 90 年代初开发。它提供了一种将外设和扩展卡连接到计算机主板和 CPU 的方式。最初,它取代了 ISA 和 EISA 等旧标准,采用了一种更高性能的总线架构。
Over the years, PCI has evolved and been extended multiple times. The PCI Local Bus specification has gone through revisions 2.0, 2.1, 2.2, and 2.3. Then PCI Express (PCIe) was introduced in 2003 as a major update that switched to high-speed serial links rather than a shared parallel bus. Today PCI Express is by far the most common version of PCI used in modern computer systems.
多年来,PCI 经历了多次演变和扩展。PCI 本地总线规范经历了 2.0、2.1、2.2 和 2.3 版本的修订。2003 年,PCI Express(PCIe)作为一种重大更新被引入,它采用了高速串行链路,而不是共享的并行总线。如今,PCI Express 是现代计算机系统中最常用的 PCI 版本。
PCI and PCI Express have proven to be hugely successful technologies that have stood the test of time. They continue to provide the fundamental interconnect that allows components like graphics cards, network adapters, SSDs, sound cards, and countless other peripherals to be plugged into contemporary PCs and servers. Having a solid grasp of how PCI works and how to use it effectively is an essential skill for any intermediate or advanced Linux user.
PCI 和 PCI Express 已被证明是极为成功的、经得起时间考验的技术。它们继续提供了基本的互连功能,使得显卡、网卡、固态硬盘、声卡以及无数其他外设能够插入到现代的 PC 和服务器中。对于任何中级或高级 Linux 用户来说,牢固掌握 PCI 的工作原理以及如何有效使用它是必备的技能。
PCI Bus Architecture and Characteristics
PCI 总线架构和特性
At the heart of every PCI system is the root complex. This is a chip or set of chips that bridges the primary PCI bus to the CPU and memory subsystem. In a typical PC, the root complex is integrated into the main system chipset along with the memory controller hub (MCH or “northbridge”). The root complex implements the host bridge that initiates PCI memory and I/O cycles.
每个 PCI 系统的核心是根复合体。这是一个芯片或一组芯片,它将主 PCI 总线桥接到 CPU 和内存子系统。在典型的 PC 中,根复合体与内存控制器中心(MCH 或“北桥”)一起集成到主系统芯片组中。根复合体实现了主机桥,它启动 PCI 内存和 I/O 周期。
Physically, this primary PCI host bus has a parallel data bus that is 32 or 64 bits wide. 32-bit PCI slots have connections for data lines AD[31:0], address/control lines, power, and ground. Maximum clock speeds for PCI are generally 33 or 66 MHz, with 32-bit 33 MHz PCI being the original standard configuration.
从物理上讲,这个主 PCI 主机总线有一个 32 位或 64 位宽的并行数据总线。32 位 PCI 插槽连接了数据线 AD[31:0]、地址/控制线、电源和地线。PCI 的最大时钟速度通常为 33 MHz 或 66 MHz,最初的 PCI 标准配置为 32 位 33 MHz。
Voltage levels used on PCI buses are 5V or 3.3V signaling. Bus transactions involve an address phase followed by one or more data phases where command, byte enables, addresses, and data get transferred between components. With shared parallel buses, PCI uses CSMA/CD style arbitration to prevent collisions between devices trying to use the bus simultaneously.
PCI 总线使用的电压等级为 5V 或 3.3V 信号。总线事务包括一个地址阶段,随后是一个或多个数据阶段,在这些阶段中,命令、字节使能、地址和数据在组件之间传输。在共享的并行总线中,PCI 使用类似于 CSMA/CD 的仲裁方式,以防止同时使用总线的设备之间发生冲突。
In addition to the main PCI bus connected to the root complex, PCI supports bridging to secondary and subordinate buses via PCI-to-PCI bridge chips. This allows the bus topology to be expanded with multiple PCI buses connected in a tree structure. Up to 256 buses can be addressed with PCI’s 8-bit bus number scheme. Bridges isolate electrical loads between buses while routing transactions between the hierarchical domains.
除了连接到根复合体的主 PCI 总线外,PCI 还支持通过 PCI 到 PCI 桥接芯片连接到次级和从属总线。这使得总线拓扑可以通过多个 PCI 总线以树形结构进行扩展。PCI 的 8 位总线编号方案可以寻址多达 256 个总线。桥接器在总线之间隔离电气负载,同时在层次域之间路由事务。
PCI Memory and I/O Address Spaces
PCI 内存和 I/O 地址空间
PCI uses two separate address spaces – a memory space and an I/O space. The memory address space (for prefetchable regions like video memory) ranges from 0000_0000 to FFFF_FFFF. The I/O space (for legacy hardware registers, non-prefetchable regions) ranges from 0000_0000 to FFFF_FFFF as well.
PCI 使用两个独立的地址空间——一个内存空间和一个 I/O 空间。内存地址空间(用于可预取区域,如视频内存)的范围是从 0000_0000 到 FFFF_FFFF。I/O 空间(用于遗留硬件寄存器、不可预取区域)的范围也是从 0000_0000 到 FFFF_FFFF。
PCI memory cycles involve a single address phase followed by 1-4 data phases. PCI I/O cycles have separate address and data phases, with the direction of each data phase determined by read/write indicators.
PCI 内存周期包括一个地址阶段,随后是 1 到 4 个数据阶段。PCI I/O 周期具有独立的地址和数据阶段,每个数据阶段的方向由读/写指示器决定。
Each PCI device can request to be assigned a contiguous block of addresses in these ~4GB memory and I/O spaces. Addresses are dynamically assigned by plug-and-play ACPI firmware as devices are enumerated at boot time. This contrasts with older ISA slots which had to be manually configured with jumpers or DIP switches.
每个 PCI 设备可以请求在这些约 4GB 的内存和 I/O 空间中分配一个连续的地址块。在启动时枚举设备时,地址由即插即用的 ACPI 固件动态分配。这与旧的 ISA 插槽形成对比,ISA 插槽需要手动使用跳线或 DIP 开关进行配置。
PCI Bus Addressing and Identifiers
PCI 总线寻址和标识符
Each PCI slot or device is assigned a hierarchical identifier consisting of a bus number, device number, and function number:
每个 PCI 插槽或设备都被分配了一个层次化的标识符,包括总线号、设备号和功能号:
Bus Number (8 bits = 0-255)
Device Number (5 bits = 0-31)
Function Number (3 bits = 0-7)
This allows individual PCI devices to be uniquely addressed across a system that could have hundreds of slots/buses. For example, “06:00.1” identifies PCI device 1, function 0 living on bus 6 of the system.
这使得单个 PCI 设备可以在一个可能拥有数百个插槽/总线的系统中被唯一地寻址。例如,“06:00.1” 识别系统中第 6 号总线上的第 1 号设备,第 0 号功能。
The topology of the full PCI tree can be discovered by starting at the root complex at bus 0 and traversing all downstream buses and devices. Each PCI-to-PCI bridge device is queried to see what buses it connects and enumerate what’s behind it.
通过从第 0 号总线的根复合体开始,并遍历所有下游总线和设备,可以发现整个 PCI 树的拓扑结构。每个 PCI 到 PCI 桥接设备都会被查询,以查看它连接了哪些总线,并枚举其背后的内容。
On 64-bit PCI systems, an additional 8-bit domain number may be added in front of the bus number to allow even larger PCI fabrics with up to 65536 busses to be addressed.
在 64 位 PCI 系统中,可以在总线号前面添加一个额外的 8 位域号,以便寻址多达 65536 个总线的更大 PCI 网络。
Key Types of PCI Devices
PCI 设备的主要类型
There are two broad classes of devices that can plug into PCI slots and consume PCI resources:
可以插入 PCI 插槽并使用 PCI 资源的设备分为两大类:
Endpoint Devices
终端设备
These are most typical PCI peripherals like:
这些是最常见的 PCI 外围设备:
- Ethernet NICs
以太网网卡 - GPUs and Video Capture Cards
图形处理单元和视频采集卡 - Storage Controllers (RAID, NVMe)
存储控制器(RAID、NVMe) - Audio Cards and DSPs
声卡和数字信号处理器 - Custom FPGA/ASIC Accelerators
自定义 FPGA/ASIC 加速器
They connect to the PCI bus as leaf nodes to send/receive data and offload work from the CPU. Each endpoint only consumes 1 ID with a single function.
它们作为叶节点连接到 PCI 总线,用于发送/接收数据,并从 CPU 卸载工作。每个终端设备仅使用一个 ID 和单一功能。
PCI Bridge Devices
PCI 桥接设备
These chips interconnect PCI buses, like:
这些芯片用于连接 PCI 总线,例如:
- PCI-to-PCI Bridges
PCI 到 PCI 桥接 - Switches
交换机 - Retimers
重定时器 - Root Ports
根端口
Bridges enable PCI fabrics to be expanded with many buses. They contain two PCI interfaces – primary and secondary – and route transactions between them.
桥接器使得 PCI 网络可以通过许多总线进行扩展。它们包含两个 PCI 接口——主接口和次接口——并在它们之间路由事务。
PCI Configuration Space
PCI 配置空间
A key element of any PCI device is its 256-byte read/write configuration space. This contains control and status registers for the device along with vital information like its capabilities and assigned resources.
PCI 设备的一个关键要素是其 256 字节的读/写配置空间。它包含设备的控制和状态寄存器,以及其功能和分配资源等重要信息。
There are two types of PCI configuration space layouts: Type 0 for Endpoint devices, and Type 1 for Bridge devices.
PCI 配置空间有两种布局类型:终端设备使用 Type 0,桥接设备使用 Type 1。
Type 0 Configuration Space (Endpoints)
Type 0 配置空间(终端设备)
Endpoint config space layout
端点配置空间布局
Type 0 is the simplest configuration space used by the majority of PCI endpoints like NICs and GPUs. Some key registers include:
Type 0 是大多数 PCI 终端设备(如网卡和显卡)使用的最简单的配置空间。一些关键寄存器包括:
- Vendor ID – 16-bit vendor identification code
供应商 ID——16 位供应商识别码 - Device ID – 16-bit device identification code
设备 ID——16 位设备识别码 - Class Code – Specifies what type of PCI device this is
类别代码——指定这是哪种类型的 PCI 设备 - Header Type – Identifies config space layout type
头文件类型——识别配置空间布局类型 - BARs 0-5 – Base address registers that define the device’s memory regions
BARs 0-5——定义设备内存区域的基本地址寄存器 - Interrupt Line/Pin – Specifies IRQ line used by device
中断线/引脚——指定设备使用的 IRQ 线
There are also capability pointers for power management, MSI, PCIe and more.
还有用于电源管理、MSI、PCIe 等的功能指针。
Type 1 Configuration Space (Bridges)
Type 1 配置空间(桥接设备)
Bridge config space layout
桥接配置空间布局
Type 1 config space is used by PCI bridge devices. In addition to common registers, it also contains:
Type 1 配置空间用于 PCI 桥接设备。除了常见的寄存器外,它还包含:
- Primary/Secondary Bus Number – Identifies buses on each side of bridge
主/次总线号——识别桥接两侧的总线 - Subordinate Bus Number – Highest downstream bus number
从属总线号——最高的下游总线号 - Secondary Latency Timer – Impacts performance during bursts
次级延迟计时器——在突发期间影响性能 - I/O Limit/Base – I/O window for routing downstream
I/O 限制/基准——用于下游路由的 I/O 窗口 - Memory Limit/Base – Memory window for routing downstream
内存限制/基准——用于下游路由的内存窗口 - Prefetchable Limit/Base – For prefetchable memory behind bridge
可预取限制/基准——用于桥接后的可预取内存
So in summary, Type 1 includes routing parameters that Type 0 endpoints don’t need to worry about.
总之,Type 1 包含 Type 0 终端设备不需要关心的路由参数。
PCI Capabilities and Extensions
PCI 功能和扩展
The original PCI spec has been extended over the years with many capabilities and features. These are communicated through linked capability structures in configuration space.
多年来,原始的 PCI 规范已经通过许多功能和特性进行了扩展。这些功能通过配置空间中的链接功能结构进行通信。
Common PCI capabilities include:
常见的 PCI 功能包括:
- Power Management – For changing device power states (D0-D3)
电源管理——用于改变设备的电源状态(D0-D3) - PCI Express – For Gen 1, 2, 3, 4 PCIe link features
PCI Express——用于 PCIe 链路功能的 Gen 1、2、3、4 - MSI/MSI-X – For message signaled interrupts
MSI/MSI-X——用于消息信号中断 - Virtual Channel – For Quality of Service (QoS) support
虚拟通道——用于服务质量(QoS)支持 - SR-IOV – For single root IO virtualization
SR-IOV——用于单根 I/O 虚拟化
Software can walk the capability list to detect supported features. For example, the MSI capability structure specifies the available interrupt vectors.
软件可以遍历功能列表以检测支持的功能。例如,MSI 功能结构指定了可用的中断向量。
PCI Bus Enumeration
PCI 总线枚举
During system boot, PCI bus enumeration takes place which discovers and initializes all PCI devices. This crucial process involves:
在系统启动期间,会进行 PCI 总线枚举,以发现并初始化所有 PCI 设备。这个关键过程包括:
- System BIOS scans all PCI buses and assigns each device a unique address.
系统 BIOS 扫描所有 PCI 总线,并为每个设备分配一个唯一地址。 - BIOS reads configuration headers to identify devices.
BIOS 读取配置头文件以识别设备。 - Memory and I/O address ranges are assigned to BARs.
内存和 I/O 地址范围分配给 BAR。 - Interrupt lines are routed to devices based on pin requests.
根据引脚请求,将中断线路由到设备。 - Driver and OS take over, re-probing all devices and resources.
驱动程序和操作系统接管,重新探测所有设备和资源。
On modern systems, enumeration responsibilities are split between legacy BIOS, UEFI, and advanced firmware like ACPI. The Linux kernel then claims devices and manages them throughout runtime.
在现代系统中,枚举责任由传统的 BIOS、UEFI 和高级固件(如 ACPI)分担。然后 Linux 内核接管设备,并在整个运行时管理它们。
But all these pieces of firmware and software must work together to perform the same vital discovery and allocation tasks. With PCIe, link training also takes place to establish communication between devices. Proper enumeration is key for any PCI peripherals to become usable!
但所有这些固件和软件必须协同工作,以执行相同的关键发现和分配任务。对于 PCIe,还会进行链路训练,以建立设备之间的通信。正确的枚举是使任何 PCI 外围设备可用的关键!
Linux PCI Core Infrastructure
Linux PCI 核心基础设施
The Linux kernel contains a sophisticated and robust “PCI core” subsystem for managing PCI devices on all types of platforms. It handles critical tasks like:
Linux 内核包含一个复杂而强大的“PCI 核心”子系统,用于在各种平台上管理 PCI 设备。它处理诸如以下的关键任务:
- Initializing the root PCI controller
初始化根 PCI 控制器 - Implementing PCI sysfs layout
实现 PCI sysfs 布局 - Scanning and identifying devices
扫描和识别设备 - Assigning interrupts and IO/memory regions
分配中断和 I/O/内存区域 - Supporting hotplug events and power management
支持热插拔事件和电源管理 - Exposing PCI capabilities to drivers
向驱动程序公开 PCI 功能
At the heart of this core code livesthe pci_bus structure which represents the tree of PCI buses. It coordinates with low-level platform firmware and host bridge drivers to populate this structure with all PCI devices in the system.
核心代码的核心是 pci_bus 结构,它代表了 PCI 总线的树形结构。它与低层平台固件和主机桥驱动程序协调,将系统中的所有 PCI 设备填充到此结构中。
The PCI core also manages essential functionality like PCI hotplug support, power management transitions, SR-IOV virtualization, Enhanced Error Handling (EEH), and advanced controller features. It aims to provide a standard interface so PCI drivers can focus on controlling devices rather than babysitting PCI itself.
PCI 核心还管理诸如 PCI 热插拔支持、电源管理转换、SR-IOV 虚拟化、增强错误处理(EEH)和高级控制器功能等重要功能。它旨在提供一个标准接口,以便 PCI 驱动程序可以专注于控制设备,而不是管理 PCI 本身。
lspci and setpci Utilities
lspci 和 setpci 工具
There are two extremely handy command line utilities for inspecting and interacting with PCI devices on a Linux system:
有两个非常方便的命令行工具,用于在 Linux 系统上检查和交互 PCI 设备:
lspci
This tool prints information about all PCI buses and devices in a system. Various options can customize the output:
此工具打印系统中所有 PCI 总线和设备的信息。各种选项可以自定义输出:
lspci -t Show PCI tree view
lspci -vv Be verbose and show full details
lspci -s 00:14.0 Show only specific device
lspci -n Show numeric IDs not names
lspci -x Hex dump config space registers
lspci retrieves data primarily from sysfs, so it can report info even for PCI devices that lack drivers currently loaded.
lspci 主要从 sysfs 获取数据,因此即使对于当前缺少驱动程序的 PCI 设备,它也可以报告信息。
setpci
setpci can directly read and write to configuration space registers. For example:
setpci 可以直接读取和写入配置空间寄存器。例如:
setpci -s 01:00.0 COMMAND=00 Disable MEM/IO space
setpci -s 04:00.0CacheLineSize=08 Eight Dword cache line
This allows tweaking settings like latency timers, cache line size, and power management capabilities.
这允许调整诸如延迟计时器、缓存行大小和电源管理能力等设置。
Together lspci and setpci are invaluable for low-level PCI debugging and configuration.
一起,lspci 和 setpci 对于低级 PCI 调试和配置非常有价值。
Accessing PCI Memory with Sysfs Files
使用 Sysfs 文件访问 PCI 内存
A key aspect of PCI devices is that they can expose multiple memory regions (via BARs) into a system’s physical address space. On Linux, sysfs virtual files located at /sys/bus/pci/devices//resource and /sys/bus/pci/devices//resourceN provide an interface to access these memory regions.
PCI 设备的一个关键方面是它们可以通过 BAR(基地址寄存器)将多个内存区域暴露到系统的物理地址空间中。在 Linux 中,位于 /sys/bus/pci/devices//resource 和 /sys/bus/pci/devices//resourceN 的 sysfs 虚拟文件提供了访问这些内存区域的接口。
For example, consider a PCI device with a 4KB memory BAR mapped to its resource0. This would show up in sysfs as:
例如,考虑一个具有 4KB 内存 BAR 映射到其 resource0 的 PCI 设备。这将在 sysfs 中显示为:
/sys/bus/pci/devices/0000:04:00.0/resource0
To read or write this BAR memory region from userspace:
从用户空间读取或写入此 BAR 内存区域:
- Open the resource0 file
打开 resource0 文件 - Use mmap() to map the BAR into application’s virtual address space
使用 mmap() 将 BAR 映射到应用程序的虚拟地址空间 - Read or write the mapped virtual memory as needed
根据需要读取或写入映射的虚拟内存 - Unmap memory when done
完成后取消映射内存
Here is sample code to write a DWORD to the device BAR:
以下是一个将 DWORD 写入设备 BAR 的示例代码:
#include <sys/mman.h>
int fd = open("/sys/bus/pci/devices/0000:00:19.0/resource0", O_RDWR);
void *ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
*(volatile uint32_t *)(ptr + 0x100) = 0x1a2b3c4d; // Write to offset 0x100
munmap(ptr, 4096);
close(fd);
This interface provides userspace with direct access to map and use any PCI memory regions, without needing custom drivers.
此接口为用户空间提供了直接访问映射和使用任何 PCI 内存区域的能力,无需自定义驱动程序。
Debugging PCI Issues in Linux
在 Linux 中调试 PCI 问题
There are a variety of techniques available for debugging pesky PCI-related issues in Linux:
在 Linux 中,有多种技术可用于调试令人头疼的 PCI 相关问题:
-
lspci -vvv – Display full details on devices
lspci -vvv——显示设备的详细信息Often the first step is using a verbose lspci to compare expected vs actual device setup.
通常,第一步是使用详细的 lspci 来比较预期与实际的设备设置。 -
Check dmesg – Scan for PCI errors
查看 dmesg——扫描 PCI 错误Kernel log messages frequently contain clues about PCI failures or glitches.
内核日志消息通常包含有关 PCI 失败或故障的线索。 -
Examine sysfs – Verify PCI resources
查看 sysfs——验证 PCI 资源Sysfs exports registers, IRQs, BARs that can be cross-checked.
Sysfs 导出了可以交叉检查的寄存器、IRQ 和 BAR。 -
Try PCI remove/rescan – To reinitialize devices
尝试 PCI 移除/重新扫描——重新初始化设备Removing and rescanning PCI devices will force re-enumeration which may clear up errant state.
移除并重新扫描 PCI 设备将强制重新枚举,这可能会清除错误状态。 -
Test hardware pass-through – Isolate issues
测试硬件透传——隔离问题Passing devices through directly to VMs can help identify problems originating in system firmware/kernel.
将设备直接透传到虚拟机可以帮助识别源自系统固件/内核的问题。 -
Update kernel and firmware – To resolve bugs
更新内核和固件——解决错误Outdated BIOS, UEFI, ACPI, and kernel code often introduce PCI quirks.
过时的 BIOS、UEFI、ACPI 和内核代码常常引入 PCI 特殊情况。
While frustrating, methodically eliminating variables with low-level tools often resolves the most stubborn PCI bugs.
尽管令人沮丧,但使用低级工具有条不紊地排除变量通常可以解决最顽固的 PCI 错误。
Conclusion
总结
Hopefully this guide provided you with a solid foundation on everything PCI in the Linux world. We looked at the PCI bus itself, memory and I/O spaces, configuration headers, bus enumeration, Linux’s PCI core, lspci/setpci tools, BAR addressing, and debugging techniques.
希望这份指南为你提供了关于 Linux 中 PCI 的所有内容的坚实基础。我们研究了 PCI 总线本身、内存和 I/O 空间、配置头文件、总线枚举、Linux 的 PCI 核心、lspci/setpci 工具、BAR 地址和调试技术。
PCI remains the tried-and-true workhorse that connects peripherals at the heart of every Linux system. So take your Linux skills to the next level by grabbing this information for a deeper mastery of PCI internals! Please drop me a note if you have any other questions on this topic.
PCI 仍然是连接每个 Linux 系统核心外设的经过验证的主力。所以,通过获取这些信息将你的 Linux 技能提升到下一个水平,以更深入地掌握 PCI 内部!如果你对这个主题有其他问题,请告诉我。
Mastering PCI Utilities on Linux
精通 Linux 中的 PCI 工具
December 27, 2023
As your Linux system expert friend, let me walk you through how to leverage some powerful tools for managing PCI devices. If you ever need to debug hardware, analyze performance issues, or identify drivers – these commands will be indispensable!
作为你的 Linux 系统专家朋友,让我带你了解如何使用一些强大的工具来管理 PCI 设备。如果你需要调试硬件、分析性能问题或识别驱动程序——这些命令将是不可或缺的!
So if you ever find yourself wondering “how do I check the PCI devices on this Linux machine” – this is the guide for you! Let’s get to it.
所以,如果你想知道“如何检查这台 Linux 机器上的 PCI 设备”——这就是你需要的指南!让我们开始吧。
Demystifying PCI Terminology
揭开 PCI 术语的神秘面纱
Before we break out the tools, I want to quickly demystify some common PCI terminology. Consider this your 2 minute PCI crash course!
在我们开始使用工具之前,我想快速揭开一些常见 PCI 术语的神秘面纱。把它当作你的 PCI 速成课程吧!
PCI Slots: The physical connector on the motherboard that devices plug into. Standard motherboards typically have anywhere from 2-7 PCI express slots. They come in different physical sizes.
PCI 插槽:设备插入主板的物理连接器。标准主板通常有 2 到 7 个 PCI Express 插槽。它们有不同的物理尺寸。
PCIe Lanes: The underlying data lanes that make up a PCI slot. Different slots can have different bandwidth – x1, x4, x8, x16 are common. The latest PCIe 4.0 spec supports up to x16 lanes (128Gbps!).
PCIe 通道:构成 PCI 插槽的底层数据通道。不同插槽可以有不同的带宽——x1、x4、x8、x16 是常见的。最新的 PCIe 4.0 规范支持多达 x16 通道(128Gbps)!
PCI Speed: As you may guessed, slots also differ in speed. Current generation slots normally operate at PCIe 3.0 or PCIe 4.0. This determines total transfer bandwidth.
PCI 速度:正如你可能猜到的,插槽的速度也各不相同。当前一代插槽通常运行在 PCIe 3.0 或 PCIe 4.0。这决定了总传输带宽。
Given how essential PCIe expansion is for graphics, storage and networking, both lane count and speeds continue to increase. By 2025, expect to see the PCIe 6.0 specification hitting the mainstream – enabling 256GBps transfer rates!
鉴于 PCIe 扩展对于图形、存储和网络的重要性,通道数量和速度都在不断增加。到 2025 年,预计 PCIe 6.0 规范将进入主流,实现 256GBps 的传输速率!
With speeds getting exponentially faster, tools for analyzing these buses become even more critical.
随着速度呈指数级增长,用于分析这些总线的工具变得更加重要。
Understanding these key terminology pieces will help contextualize some of the analysis our utilities provide. Now let’s dive into the tools!
了解这些关键术语将有助于理解我们的工具提供的一些分析。现在,让我们深入了解这些工具!
Listing Devices with lspci
使用 lspci 列出设备
The lspci
command is your gateway into viewing details on all PCI and PCIe devices in a Linux system. Run without arguments, it provides a quick summary:
lspci
命令是查看 Linux 系统中所有 PCI 和 PCIe 设备详细信息的入口。在不带参数的情况下运行,它会提供一个快速摘要:
$ lspci
00:00.0 Host bridge: Intel Corporation Tiger Lake Host Bridge/DRAM Registers (rev 11)
00:02.0 VGA compatible controller: Intel Corporation TigerLake GT2 [Iris Xe Graphics] (rev 11)
00:04.0 Signal processing controller: Intel Corporation Tiger Lake Processor Thermal Subsystem (rev 11)
00:12.0 Signal processing controller: Intel Corporation Device 02f9
00:14.0 USB controller: Intel Corporation Ice Lake-LP USB 3.1 xHCI Host Controller
00:14.2 RAM memory: Intel Corporation Ice Lake-LP Shared SRAM
00:15.0 Serial bus controller [0c80]: Intel Corporation Ice Lake-LP Serial IO I2C Controller #0
00:1b.0 PCI bridge: Intel Corporation Device 15d3 (rev 11)
01:00.0 3D controller: NVIDIA Corporation TU116M [GeForce GTX 1660 Ti Mobile]
This shows all devices attached to a PCI slot along with vendor ID, chip name, BDF address, and some additional identifiers.
这显示了连接到 PCI 插槽的所有设备,以及供应商 ID、芯片名称、BDF 地址和一些其他标识符。
By default only devices with kernel drivers attached will be shown. We’ll cover how to show all devices later on.
默认情况下,只会显示已连接内核驱动程序的设备。我们稍后将介绍如何显示 所有 设备。
Let’s explore some useful options for getting more insight!
让我们探索一些有用的选项,以获取更多见解!
Enabling Verbose Output
启用详细输出
To dump absolutely everything lspci can extract about your PCI devices, use the -vv
option:
要列出 lspci
可以提取的关于你的 PCI 设备的所有信息,请使用 -vv
选项:
$ lspci -vv -s 00:02.0
00:02.0 VGA compatible controller: Intel Corporation TigerLake GT2 [Iris Xe Graphics] (rev 11) (prog-if 00 [VGA controller])
Subsystem: Dell XPS 13 9310
Physical Slot: 2
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 139
Region 0: Memory at 80000000 (64-bit, non-prefetchable) [size=16M]
Region 2: Memory at a0000000 (64-bit, prefetchable) [size=256M]
Region 4: I/O ports at 4000 [size=64]
Expansion ROM at 000c0000 [virtual] [disabled] [size=128K]
Capabilities: [40] Express Root Complex Integrated Endpoint, MSI 00
Device Page Type EFI Unprogrammed
Bridge: normal decode, BAR matches device
Link Control Register: BAR is 64-bit prefetchable mem on bus 0
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable- Count=1/1 Maskable- 64bit+
Address: fee003c8 Data: 0000
Capabilities: [a0] Express Endpoint, MSI 00
Device Page Type EFI Unprogrammed
Bridge: normal decode, SecBus=00, SubBus=00, PriBus=00
Device ID 00 -> Onboard Device -> Device 9999 on bus 255 device 9999 func 0
Link Control Register: CC- C1E2+ C1E1+ ASPMOptComp+
Link Status Register: C1E2- C1E1-
Slot Capabilities: AttnBtn- PwrCtrl- AttnInd- PwrInd- HotPlug+ Surprise+
Slot Number: 0x00
Slot Power Limit: 0.000W
Device Capabilities: MaxPayload 256 bytes, PhantFunc 0, Extended-Tag+
Device Control: Correctable- Non-Fatal- Fatal- ExtTag+ ExtTagCtl- PhantFunc- AuxPwr- NoSnoop+ FLReset- Interrupt-
Device Status: TransPnd-
Link Capabilities: L0sL1- L1- ClockPM- Surprise- LBClkAcc+ LnR0EqComp- *MRL de-emphasis supported
Link Control: ASCL1- CLKREQ- CUDA- LTR1=0us
Link Status: CLKREQ0- CLKREQ1- LTR- LBCL0s Ent L1
Root Complex Link Capabilities: CTC- CFC- ASPMOptComp-
Root Complex Link Status: CTC- CFC-/
Woah! -vv
provides extremely verbose output including info on capabilities, interrupts, links, cache lines and more. This can be invaluable when trying to pinpoint tricky PCI root cause problems.
哇哦!-vv
提供了极其详细的输出,包括关于功能、中断、链路、缓存行等的信息。在尝试精确定位棘手的 PCI 根因问题时,这可能非常有价值。
You’ll also notice the BDF address is shown again confirming details on the exact device.
你还会注意到,BDF 地址再次显示,确认了关于确切设备的详细信息。
Listing Kernel Drivers
列出内核驱动程序
In most cases, you won’t actually care about the PCI device itself – but rather the driver controlling it!
在大多数情况下,你实际上并不关心 PCI 设备本身,而是控制它的驱动程序!
The -k
argument adds kernel driver details:
-k
参数添加内核驱动程序的详细信息:
$ lspci -k
00:02.0 VGA compatible controller: Intel Corporation TigerLake GT2 [Iris Xe Graphics] (rev 11)
Subsystem: Dell XPS 13 9310
Kernel driver in use: i915
01:00.0 3D controller: NVIDIA Corporation TU116M [GeForce GTX 1660 Ti Mobile]
Subsystem: Micro-Star International Co., Ltd. [MSI] TU116M [GeForce GTX 1660 Ti Mobile]
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
This shows the i915 module driving the integrated Intel GPU, while the dedicated NVIDIA card is leveraging several modules for 3D rendering and display.
这显示了 i915 模块正在驱动集成的 Intel GPU,而专用的 NVIDIA 显卡则利用多个模块进行 3D 渲染和显示。
-kk will also show alternate drivers available but not loaded. This helps identify if you have a suboptimal or incorrect driver attached.
-kk 还会显示可用但未加载的 备用 驱动程序。这有助于识别是否连接了次优或错误的驱动程序。
Machine Readable & Tree Output
机器可读和树形输出
For scripting PCI analysis, -vm
outputs clean machine-readable format:
对于脚本化的 PCI 分析,-vm
输出干净的机器可读格式:
$ lspci -vm
00:00.0 0600: 8086:4b55 (rev 11)
00:02.0 0300: 8086:9a49 (rev 11)
00:04.0 11d3: 8086:4da6
00:12.0 0806: 8086:02f9
00:14.0 0c03: 8086:43ed
00:14.2 0200: 8086:43ef
And -t
shows the hierarchy in tree format:
而 -t
以树形格式显示层次结构:
-[0000:00]-+-00.0 8086:4b55
+-02.0 8086:9a49
+-04.0 8086:4da6
+-12.0 8086:02f9
+-14.0 8086:43ed
+-14.2 8086:43ef
This visualizes how bridges, devices and functions connect together – invaluable for debugging tricky topology issues!
这可视化了桥接、设备和功能如何连接在一起——对于调试棘手的拓扑问题非常有价值!
PCI Device Classes
PCI 设备类别
lspci has well over 100 different PCI device class codes used to identify cards.
lspci 有超过 100 种不同的 PCI 设备类别代码,用于识别卡。
Some common classes you may see:
一些常见的类别包括:
Code | Device |
---|---|
0300 | VGA/3D Graphics Card |
0200 | Network/Ethernet Card |
0500 | RAM/Storage Controller |
0700 | Serial Bus Controller |
Run lspci -nn
to always include the class + vendor/device codes which helps decipher card types.
运行 lspci -nn
始终包括类别 + 供应商/设备代码,这有助于识别卡的类型。
There are many more classes, but this covers some common ones I see regularly.
还有许多其他类别,但这些是我经常看到的一些常见类别。
Configuring Devices with setpci
使用 setpci 配置设备
Alright, now that you’re a pro at analyzing PCI devices, how about we change some settings?
好了,既然你已经精通分析 PCI 设备,那么我们来 更改 一些设置吧?
Meet setpci
– it provides read/write access to the underlying PCI config space registers.
认识一下 setpci
——它提供了对底层 PCI 配置空间寄存器的读/写访问。
This takes some care – randomly poking PCI config registers can easily crash a system! But when done properly, it unlocks some helpful tuning capabilities.
这需要小心——随意篡改 PCI 配置寄存器可能会轻易导致系统崩溃!但当正确完成时,它会解锁一些有用的调整功能。
Let’s explore some safe and common use cases.
让我们探索一些安全且常见的用例。
Enabling Bus Mastering
启用总线主控
One very common tweak is enabling bus mastering which allows a PCI device to access system memory directly for DMA transfers. This helps storage and net devices reduce CPU overhead.
一个非常常见的调整是启用总线主控,这允许 PCI 设备直接访问系统内存以进行 DMA 传输。这有助于存储和网络设备减少 CPU 开销。
Here’s how to enable it:
这是启用它的方法:
$ setpci -s 01:00.0 COMMAND=IONOIO+MEM+MASTER+SPECIAL+MWRICEN+MWIEN
This updates command word at offset 4 to appropriate value using predefined macros.
这使用预定义的宏将偏移量 4 处的命令字更新为适当的值。
We can verify the change was applied:
我们可以验证更改是否已应用:
$ setpci -s 01:00.0 4.w
0006 (bus master + IO + memory bits set correctly)
And that’s it! Our NVIDIA GPU now has bus mastering enabled.
就这样!我们的 NVIDIA GPU 现在已启用总线主控。
Reading Device Registers
读取设备寄存器
setpci makes reading registers easy too. Let’s check the card’s vendor ID:
setpci 也使得读取寄存器变得容易。让我们检查一下卡的供应商 ID:
$ setpci -s 01:00.0 0.w
10de (NVIDIA corporation)
And the device ID:
以及设备 ID:
$ setpci -s 01:00.0 2.w
2184 (GeForce GTX 1660 Ti)
Nice! We successfully read back the expected PCI IDs and verified this further.
太好了!我们成功读取了预期的 PCI ID 并进一步验证了这一点。
Note: Offsets 0-255 map to the standard config space header. Vendors can then implement custom registers in 256-4095 range specific to that device.
注意:偏移量 0-255 映射到标准配置空间头部。然后供应商可以在 256-4095 范围内实现特定于该设备的自定义寄存器。
Dumping Full Config Contents
转储完整配置内容
To dump everything, there’s the handy built-in iterates from 0-255 printing contents in hex/ascii:
为了转储所有内容,有一个方便的内置工具可以从 0-255 迭代,并以十六进制/ASCII 格式打印内容:
$ setpci -dumpreg -s 01:00.0
00: 10de 2184 0610 10de 8615 00 00 03 00 00 00 00
10: 08 00 00 d0 00 00 00 00 f1 01 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 43 10 9a 19
...
This can even be useful for reverse engineering unpublished PCI devices!
这甚至可以用于逆向工程未公开的 PCI 设备!
Restoring Original State
恢复原始状态
Before tweaking, I recommend saving original state so you can restore cleanly after testing:
在进行调整之前,我建议保存原始状态,以便在测试后可以干净地恢复:
$ setpci -read1 01:00.0 > gpu.regs
$ setpci -load1 01:00.0 < gpu.regs
This saves and then restores the PCI config space contents in two easy commands.
这两个简单的命令可以保存并恢复 PCI 配置空间的内容。
Tweaking & Troubleshooting PCI Devices
调整和故障排除 PCI 设备
Now that you have some good fundamentals on both listing and configuring, I wanted to share some handy tweaks and troubleshooting tips.
既然你已经掌握了列出和配置的基础知识,我想分享一些有用的调整和故障排除技巧。
Forcing a Driver Rebind
强制驱动程序重新绑定
If dealing with an unstable/crashing driver, force reloading it with:
如果遇到不稳定的/崩溃的驱动程序,可以强制重新加载它:
$ echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
$ echo 1 > /sys/bus/pci/rescan
This will detach the kernel driver and rescans all devices forcing a rebind.
这将分离内核驱动程序并重新扫描所有设备,强制重新绑定。
Changing Device Power State
更改设备电源状态
Devices may enter unstable power states. To force reset:
设备可能会进入不稳定的电源状态。要强制重置:
$ echo on > /sys/bus/pci/devices/0000\:00\:01.0/power/control
$ echo on > /sys/bus/pci/devices/0000\:00\:01.0/power/autosuspend_delay_ms
This brings device out of any low power state. Tweak autosuspend values as needed.
这将设备从任何低功耗状态中唤醒。根据需要调整自动挂起值。
Identifying IRQ Conflicts
识别 IRQ 冲突
Interrupts are still a source of conflicts today. Check for collisions:
中断仍然是当今冲突的来源。检查冲突:
$ cat /proc/interrupts | egrep -i "pci|irq"
CPU0
16: 241130 PCI-MSI 327680-edge xhci_hcd
17: 0 PCI-MSI 512000-edge 0000:00:14.0
65: 1 PCI-MSI 368768-edge 0000:00:1f.4
66: 0 PCI-MSI 360448-edge 0000:00:15.1
67: 384 PCI-MSI 32768-edge 0000:01:00.0
68: 0 PCI-MSI 360464-edge 0000:00:15.2
This shows the NVIDIA GPU driver using IRQ 67 without conflicts.
这显示 NVIDIA GPU 驱动程序正在使用 IRQ 67,没有冲突。
If finding collisions, try reseating devices or BIOS tuning to rearrange.
如果发现冲突,尝试重新插拔设备或调整 BIOS 以重新排列。
And those are just a taste of some useful tweaks available by leveraging these tools!
这些只是利用这些工具可用的一些有用的调整的示例!
PCI Utils Usage Tips
PCI 工具使用提示
Let me wrap up by highlighting some handy examples for common tasks:
让我总结一下,为常见任务提供一些有用的示例:
Find Driver Controlling Device
查找控制设备的驱动程序
lspci -ks 01:00.0
Enable Bus Mastering
启用总线主控
setpci -s 01:00.0 4.w=06
Check Link Speed/Width
检查链路速度/宽度
lspci -vv -s 00:02.0 | grep LnkCap
Verify IRQ
验证 IRQ
lspci -vv -s 01:00.0 | grep IRQ
Change Power Management
更改电源管理
setpci -s 01:00.0 4.b=e0
I hope this guide has demystified working with PCI devices in Linux for you!
希望这份指南为你揭开了 Linux 中 PCI 设备的神秘面纱!
Whether trying to debug issues, identify drivers, tweak settings or unlock performance – these utils offer incredible low-level control.
无论你是要调试问题、识别驱动程序、调整设置还是提升性能——这些工具都提供了令人难以置信的低级控制。
Let me know if you have any other PCI questions! Happy to provide more tips.
如果你还有其他关于 PCI 的问题,请告诉我!我很乐意提供更多建议。
Summary
总结
Key points:
要点:
- lspci – List pci devices and details
lspci——列出 PCI 设备及其详细信息 - setpci – Configure registers
setpci——配置寄存器 - Combine verbose, kernel options for insights
结合 详细、内核选项 获取见解 - Enable bus mastering for storage/net
为存储/网络启用 总线主控 - Check for IRQ conflicts
检查 IRQ 冲突 - Change power states to reset issues
更改 电源状态 以重置问题
Now you have the key PCI analysis tools in your toolbox!
现在,你的工具箱里有了关键的 PCI 分析工具!
via:
-
Demystifying the Powerful lspci Command on Linux
https://thelinuxcode.com/lspci_command/ -
Demystifying PCI in Linux: An In-Depth Technical Guide
https://thelinuxcode.com/pci-linux/ -
Mastering PCI Utilities on Linux
https://thelinuxcode.com/pci-utilities-in-linux/