news 2026/10/22 2:51:02

Linux硬件排障必会:lspci命令详解与PCIe总线诊断实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux硬件排障必会:lspci命令详解与PCIe总线诊断实战

一次硬件排障的经历让我彻底离不开 lspci 这条命令。当时一台工作站新装了一块显卡,开机后显示器完全没信号,第一反应是显卡坏了,第二反应是供电不够。折腾了半天,最后在系统里跑了一下 lspci,发现设备根本没有被系统枚举出来,问题根本不在驱动,而在 PCIe 总线的识别层面。从那以后,凡是碰到"硬件在 Linux 下不工作"的问题,我都会先查一遍当前主机的 PCI 总线信息,而不是急着换硬件。

lspci 的作用,简单说就是列出当前主机的所有 PCI/PCIe 设备,以及它们挂在总线拓扑的什么位置、用什么编号、加载了哪个驱动。它是 Linux 系统管理员、运维工程师、玩硬件的桌面用户都绕不开的一个基础诊断工具。这篇文章我想把 lspci 从输出格式、参数用法到实际排障思路完整梳理一遍,尽量让没怎么用过它的人也能照着操作。

1. 先搞懂PCI总线是怎么组织的:BDF编号、设备类别与设备树

1.1 为什么叫"PCI总线信息"而不是"硬件清单"

很多刚接触 Linux 的朋友会误以为 lspci 和 Windows 设备管理器一样,只是展示一张硬件列表。这个理解不算全错,但漏掉了最关键的一点:lspci 展示的是设备在 PCI 总线拓扑中的位置,而不仅仅是"有哪几个硬件"。

传统的 PCI 总线是并行共享总线,所有设备都挂在同一组线上,通过总线仲裁决定谁可以使用总线。到了 PCIe 时代,并行共享总线被串行点对点链路取代,每个设备都拥有一条独立的高速通道,不需要再仲裁。但为了兼容老软件,PCIe 在软件层面保留了 PCI 的枚举方式:仍然用总线号、设备号、功能号来定位设备,仍然通过配置空间读取设备信息。所以 lspci 这个"老工具"在 PCIe 平台上依然完全适用,它输出的结构也和传统的 PCI 总线信息一一对应。

lspci 之所以把重点放在"总线信息"上,是因为硬件排查的核心问题往往不是"这个设备存不存在",而是"这个设备有没有被正确枚举、链路有没有协商成功、驱动有没有接管"。这三个问题只有从总线视角才能回答清楚。

1.2 第一次运行 lspci,输出到底在说什么

在终端里直接执行:

lspci

输出大概长这样:

00:00.0 Host bridge: 某芯片厂商 主机桥控制器 00:01.0 PCI bridge: 某芯片厂商 PCIe Root Port 00:1f.3 Audio device: 某芯片厂商 高清晰音频控制器 01:00.0 VGA compatible controller: 某显卡厂商 显示控制器 (rev a1) 01:00.1 Audio device: 某显卡厂商 音频设备 02:00.0 Non-Volatile memory controller: 某存储厂商 NVMe SSD 控制器 03:00.0 Ethernet controller: 某网卡芯片厂商 千兆以太网控制器

每行的开头是设备的 BDF 编号,格式是总线号:设备号.功能号,英文全称是 Bus Device Function,这是 PCI 世界里定位设备最核心的坐标。

  • 总线号(Bus):在 CPU 看来,PCI 总线是一棵以 Root Complex 为根的树。第一条总线通常是 00,PCIe 根端口下的子总线从 01、02 开始顺序编号。
  • 设备号(Device):同一根总线上挂的物理设备编号,范围 0 到 31。
  • 功能号(Function):一个物理设备可以拆成多个独立功能,每个功能都有独立的配置空间。比如很多显卡会让显示控制器占用 Function 0,音频输出占用 Function 1;多口网卡也一样,四个物理口可能对应同一个设备号下的四个 Function。

然后是一个简短的设备类别描述,比如 VGA compatible controller、Ethernet controller、Non-Volatile memory controller。类别后面是厂商和设备名称,括号里的 rev 是设备硬件修订版本号。有些设备还会在末尾附带子系统信息,完整格式可以靠lspci -v看到。

1.3 用树状图和数字 ID 快速建立全局认知

当你面对一台配置复杂、设备很多的服务器时,直接看平铺列表很容易眼花。这时可以用lspci -t:

lspci -t

它会把拓扑画成树状,输出类似:

-[0000:00]-+-00.0 +-01.0-[01-02]----00.0[01:00.0] | +-01:00.1 +-03.0-[03]----00.0[03:00.0]

这种视图能让你一眼看出设备挂在哪个根端口、桥下面带了多少设备,对判断"某块卡是不是插对了插槽"非常有用。注意-t输出的是 ASCII 树,不同发行版的 pciutils 版本画法略有差异,但逻辑一致。

lspci -nn则会在设备名后面附加方括号形式的厂商 ID 和设备 ID,比如:

lspci -nn
01:00.0 VGA compatible controller [0300]: 某显卡厂商 显示控制器 [1234:5678]

这个[0300]是 PCI 设备类别代码,01234:5678]是厂商 ID 和设备 ID。数字 ID 的价值在于它是内核、驱动和数据库匹配设备的标准依据,后面排查"系统认不出设备"的时候完全靠它。

2. 参数那么多,真正常用的就这几个:速查表与使用场景

2.1 -vvv 等于给设备做一次全面体检

lspci 最常用的几个参数其实很好记,越长的 v 代表越详细。-v是初步信息,-vv增加更多能力字段,-vvv则是把所有能力、状态、寄存器能读到的信息全倒出来。

lspci -vvv -s 01:00.0

重点看几个字段:

  • Subsystem:子系统厂商和设备 ID,很多时候同一种显卡会有不同的子型号,靠主 ID 区分不了。
  • Flags:包括 bus master、fast devsel、IRQ 等基本属性。bus master 表示设备允许发起 DMA 请求,如果这里少了它,设备大概率工作不正常。
  • Memory at:设备映射到内存地址空间的 BAR 地址和大小。BAR 是 PCI 设备与 CPU 交换数据的窗口,BAR 没有分配地址的设备肯定无法正常工作。
  • Capabilities:功耗管理、MSI 中断、PCIe 能力等。PCIe 设备的链路速度、带宽、插槽能力都在这里。
  • Kernel driver in use和Kernel modules:驱动绑定状态和系统可用的候选模块,排查驱动问题最重要的两行。

对入门用户来说,-vvv输出信息有点多,但只要掌握了"先看 Kernel driver,再看 Memory,最后看 LnkCap/LnkSta"的顺序,就不容易被淹没。

2.2 用 -s 和 -d 精准锁定目标设备

一台机器上设备几十个,每次-vvv不带筛选会把终端刷得惨不忍睹。-s参数可以直接指定 BDF 或 BDF 前缀:

lspci -vv -s 01:00

这个写法会匹配所有 bus=01、device=00 下的功能,比如 01:00.0 和 01:00.1 都会显示,适合查看一块多功能卡的所有子功能。

-d参数按厂商 ID 或设备 ID 过滤,结合-nn得到 ID 之后可以这样查:

lspci -nn -d 1234:5678

还可以只匹配厂商 ID,列出某个厂商的所有设备:

lspci -nn -d 1234:

这在排查"到底哪个设备占用了某个设备代码"的时候很高效。-s和-d可以组合,也可以和-v、-nn搭配,搭配规则基本遵循直觉。

2.3 -k 一张表看清驱动接管情况

lspci -k是日常检查驱动状态最快捷的方式:

lspci -k

在每条设备信息的末尾会显示两行:

Kernel driver in use: abc_drv Kernel modules: abc_drv

Kernel driver in use表示当前设备被哪个驱动接管,Kernel modules表示系统里有哪些候选模块可以加载。如果只有 Kernel modules 而没有 Kernel driver in use,说明驱动模块存在,但没有被硬件自动绑定,这时候需要检查设备 ID 是否在驱动支持列表里,以及 modprobe 加载顺序。

如果-k输出里出现了Kernel driver in use但设备实际不工作,问题就不在"驱动没装"上,而要看链路状态、中断冲突或者硬件本身。这个区分能节省大量排查时间。

2.4 需要 root 的一档:-x 与 -xxx

lspci -x会显示设备配置空间前 64 字节的十六进制内容,-xxx则显示全部配置空间,但必须使用 root 权限,否则内核不允许应用层直接读取完整空间。这个参数在排查设备枚举异常、BAR 分配冲突时会用到。

比如设备配置空间里的 Class Code 字段不对,OS 就会把设备认成错误的类型,表现为 lspci 类别描述很奇怪。这时用-xxx检查原始字节,再对照 PCI 规范判断是不是设备缺陷或者固件配置错误。这类场景对普通用户很少见,但如果你是做嵌入式或者驱动开发的,-xxx会是你反复使用的调试工具。

3. 实战排障:显卡不识别、设备 UNCLAIMED、PCIe 链路降级怎么查

3.1 显卡没驱动:先确认设备在不在总线上

我开头提到的那台工作站,后来就是用 lspci 理清思路的。当时用lspci -nn | grep -i vga查询,结果完全是空的,连之前核显的输出都看不到。这就说明问题不是驱动,而是设备压根没被 CPU 枚举到,可能的范围包括物理接触不良、插槽供电不足、BIOS 里的 PCIe 端口被禁用,甚至显卡本身损坏。后来重新插拔一次,并确认供电线接好,再执行lspci -nn,设备出现了:

01:00.0 VGA compatible controller [0300]: 某显卡厂商 显示控制器 [1234:5678]

这一步的关键结论是:lspci 能看到设备,说明 PCIe 链路枚举成功,驱动加载、显示输出这些更高层的工作才有了基础。所以判断显卡问题,第一步永远是跑一遍 lspci,而不是直接换驱动。

如果设备在 lspci 里存在,但lspci -k没有显示Kernel driver in use,并且Kernel modules里是空的,那多半是系统里就没装驱动模块,要去装闭源驱动或者编译内核模块。如果 Kernel modules 非空但没有接管,可以先强制 modprobe 对应模块再观察内核日志,通常能找到不支持当前设备 ID 的报错。

3.2 设备显示 UNCLAIMED 或 Unknown device 的定位思路

在部分场景下,lspci输出的类别或厂商名会出现UNCLAIMED或Unknown device。这两种情况含义不同。

UNCLAIMED出现在lspci -v的输出里,意思是系统里没有驱动认领这个设备。这种情况不一定是坏事,比如某些 IOMMU 直通场景下,设备被 VFIO-PCI 接管,lspci 会认为没有被普通驱动 claimed。如果你准备把设备直接通给虚拟机,UNCLAIMED反而是预期的状态。

Unknown device则是 pci.ids 数据库里查不到设备 ID,导致无法显示名字,只能显示Class XX: ... [vendor:device]这样的形式。这种情况其实不代表设备异常,只是本地数据库不认识它。处理方法是更新数据库:

update-pciids

这个命令需要联网,它从公共 PCI ID 数据库下载最新列表到/usr/share/misc/pci.ids。更新后再跑lspci -nn,设备名通常就能正常显示了。如果更新数据库后仍然 unknown,那就要怀疑设备枚举本身有问题,或者设备使用了极度罕见的 ID,结合实际硬件信息判断。

3.3 PCIe 链路协商降到 x1 的定位

PCIe 设备有一个比较容易忽略的问题:硬件本身正常,但链路协商速度或宽度退化。比如一块 PCIe x4 带宽的 NVMe SSD,实际工作速度却和 x1 差不多。单看设备能不能用很难发现,但跑分能感觉出来。

这时lspci -vv就能给出关键证据。查对应设备的输出,找到 PCIe 能力部分:

LnkCap: Port #1, Speed 8GT/s, Width x4, ASPM not supported LnkSta: Speed 2.5GT/s, Width x1

LnkCap是链路的能力上限,表示物理链路最多支持 8GT/s 速度、x4 宽度;LnkSta是当前实际协商状态,只有 2.5GT/s、x1,说明设备降级运行了。

看到这种落差,优先排查物理接触问题:显卡、SSD 或网卡重新拔插,检查转接卡和延长线的质量,确认插槽本身没有积灰或损坏。对于台式机,很多 PCIe 链路降级就是金手指氧化或者没插到底造成的。虚拟机环境则可能是虚拟设备本身设计就是 x1,不需要过多担心。

3.4 重新扫描总线与热重插

如果 lspci 里没有设备,但你确定硬件已经插好,可以尝试让内核重新扫描 PCI 总线:

echo 1 > /sys/bus/pci/rescan

这个操作需要 root 权限,执行后内核会重新枚举所有 PCI 总线,新插入的设备有机会被发现。对于支持热插拔的 PCIe 设备,也可以单设备移除再重新扫描:

echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove echo 1 > /sys/bus/pci/rescan

注意remove会把设备从内核中摘掉,工作状态下执行会直接导致设备短暂离线。这个操作只适合在确认设备可以被安全移除时使用。如果是物理接触不良导致的枚举失败,单纯重新扫描可能无效,因为链路物理层就不通。

4. 把 lspci 和内核日志、sysfs 串起来:一次完整的排障闭环

4.1 sysfs 里的 PCI 设备目录与 lspci 一一对应

lspci 获取的信息大多来自内核通过 sysfs 暴露的接口,真正在底层干活的是/sys/bus/pci/下的设备目录。你可以在终端里执行:

ls /sys/bus/pci/devices/0000:01:00.0/

能看到vendor、device、class、irq、enable、driver、config等条目。其中数字文件对应配置空间和资源信息,lspci 读取的核心数据就来自这里。driver是一个符号链接,指向当前绑定的驱动目录,lspci -k显示Kernel driver in use的时候,本质就是检查这个链接的指向。

了解 sysfs 的存在,更大的意义在于你可以在 lspci 之外自己做更精细的控制。比如查看设备是否被禁用:

cat /sys/bus/pci/devices/0000:01:00.0/enable

输出 0 表示设备处于禁用状态,输出 1 表示已启用。当 lspci 显示设备正常但功能异常时,这个文件的状态能提供额外线索。

4.2 dmesg 中与 PCI 相关的关键字段怎么看

lspci 告诉你"现在是什么状态",dmesg 能告诉你"这个状态是怎么变成的"。排查 PCI 问题时,把两个工具配合使用效果最好。

常用命令:

dmesg | grep -i pci dmesg | grep -i 1234:5678

第一轮先用 grep 过滤 pci 关键字,第二轮用设备 ID 过滤,能看到内核在枚举设备时的完整日志。比如:

pci 0000:01:00.0: [1234:5678] type 00 class 0x030000 pci 0000:01:00.0: BAR 1: assigned [mem 0x...-0x... 64bit] pci 0000:01:00.0: enabling device (0000 -> 0002)

设备 ID 出现且 BAR 成功分配,说明枚举成功。如果看到BAR 0: no space for resource,说明地址空间分配失败,可能是 BIOS 配置或 IOMMU 设置导致资源不足。如果看到pcieport ... AER: Multiple Corrected error received,说明链路传输出现大量可纠正错误,就需要回到链路协商的问题上,检查插槽接触和信号质量。

4.3 一次网卡随机丢包的排查流程复盘

用 lspci 和 dmesg 配合,有个很典型的场景是"网卡随机丢包"。我有一次遇到一台服务器上报千兆网卡时通时断,运维同事第一反应是换网线。

实际的排查链条是这样的:先用lspci -vvv -s 03:00.0查看网卡链路协商状态,发现 LnkCap 显示 x8,但 LnkSta 只有 x1,这说明物理链路已经降级了。降级到 x1 的 PCIe 链路带宽根本不够千兆网卡跑满,随机丢包就是连锁反应。如果这时候换网线,问题当然解决不了。

继续用dmesg查日志,能看到 AER 报错反复出现,进一步确认链路问题。清理插槽、重新安装网卡显卡后,lspci -vvv显示 LnkSta 恢复到了 x8,丢包现象消失。整个过程里,lspci 承担了"链路状态定位"的角色,dmesg 提供了辅助证据,两者一配合,问题很快就锁定了。

4.4 PCI ID 数据库过旧导致的"设备不认识"

新硬件在老系统上经常出现 lspci 输出[1234:5678]却没有名字的情况。改起来很简单,先更新 pci.ids 数据库。Debian/Ubuntu 系、RedHat 系都可以执行update-pciids,如果没装这个命令,检查是不是缺 pciutils 配套工具,直接安装即可。

有时数据库更新后仍有大量 unknown,也可以选择只更新数据库的一部分,或者手动编辑/usr/share/misc/pci.ids添加条目。不过一般不建议手动编辑,数据库更新代价很小。这个字段还牵涉到一个细节:如果你在 Bug 上报或者驱动讨论帖里贴 lspci 输出,最好用lspci -nn,确保对方能从数字 ID 定位设备,而不是依赖对方本地数据库里有对应名称。

5. 几个容易踩的坑和我的使用习惯

5.1 以为"lspci 看不到"就等于"硬件坏了"

这个坑我反复踩过,也看别人踩过。lspci 看不到设备时,最先要排除的是桥接设备被禁用或整条链路处于关闭状态。很多主板 BIOS 里可以单独禁用一个 PCIe 插槽,或者因为设置了错误的 ASPM 策略导致设备链路进入不可恢复的断电状态。

在断言硬件损坏之前,可以按这个顺序排查:查看 BIOS 设置、检查物理插槽、确认供电、尝试换一个插槽、用echo 1 > /sys/bus/pci/rescan重新扫描。大部分"lspci 里消失"的设备最后都是接触或设置问题,真正的硬件损坏反而占少数。

5.2 虚拟机、容器和嵌入式环境的差异

在虚拟机里执行 lspci,输出的是虚拟化平台模拟出来的设备,很多都是特殊类型设备或虚拟 PCIe 根端口,和物理机上的表现不同。比如某些虚拟化环境会显示Red Hat, Inc. Virtio network device或QEMU Virtual Machine,这类输出不能用来判断物理硬件健康度,只能判断虚拟设备有没有被客户机内核枚举到。

容器环境更特殊:如果镜像没装 pciutils,执行lspci会直接提示命令不存在,先通过对应包管理器安装即可。嵌入式 ARM 设备上,PCIe 控制器可能只有一个根端口,设备枚举顺序和 x86 机器差异很大,lspci 显示的总线号、厂商名都不能用 x86 的习惯去套。

5.3 保存现场:一份可复现的 lspci 报告

我给别人的建议是,每次排查硬件问题,第一件事就是保存现场:

lspci -vvv > lspci_vvv_$(date +%Y%m%d_%H%M%S).txt lspci -nn > lspci_nn_$(date +%Y%m%d_%H%M%S).txt

这组命令会生成带时间戳的完整报告,排查前后各存一份,对比起来非常方便。尤其是那种"问题随机出现"的情况,等故障复现时再记录就来不及了。完整报告里包含了链路协商、BAR 映射、中断、驱动加载等所有细节,即使自己一时看不懂,后续把报告贴给内核驱动开发者求助,对方也不需要远程操作就能定位到大多数问题。

5.4 习惯性交叉验证:dmidecode、udevadm 与 lstopo

lspci 虽然强大,但也不是万能。它显示的是 PCI/PCIe 总线视图,而处理器、内存条信息要看dmidecode,拓扑级别的 NUMA 布局用lstopo更直观,设备在 udev 里生成的名称和后缀可以用udevadm info查询。

我的习惯是先跑 lspci 把总线层面的问题排除掉,再用 dmidecode 验证固件层面的信息,最后用 sysfs 做精细化调整。这样组合,绝大多数 Linux 硬件问题都能收敛到很小的排查范围。在追求系统稳定性和可维护性这件事上,多一条命令交叉验证,永远比少一条可靠。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 2:50:21

FPGA实现双路FM语音接收机:数字通信系统实战指南

简介:本资源是2019年全国大学生电子设计竞赛G题‘双路语音调频接收机’的FPGA全功能实现方案,面向电子类、通信类专业本科生及FPGA初学者,解决高频信号接收、双通道语音解调与硬件协同设计等典型赛题难点。压缩包共87个文件,涵盖2…

作者头像 李华
网站建设 2026/10/22 2:50:15

生产制造业产品成本核算软件实操指南:从算法选择到报表落地

简介:这是一套面向生产制造业的成本核算软件安装包,适合中小企业的财务、成本会计及ERP实施人员使用,用于解决直接材料、直接人工与制造费用的归集分摊和成本报表分析。压缩包共六百四十一个文件,大小六十三点三一兆字节&#xff…

作者头像 李华
网站建设 2026/10/22 2:50:11

制造业产品成本核算软件:从BOM建模到月末结转的完整指南

简介:一套面向生产制造业的成本核算软件安装包,以rar压缩包形式交付,主要服务于成本会计、财务主管、生产计划及ERP实施人员,用于解决直接材料、直接人工和制造费用的归集、分摊与核算问题。软件内置物料需求计划(MRP&…

作者头像 李华
网站建设 2026/10/22 2:50:11

ThinkPHP+Vue智能停车场管理系统:从车位分配到计费闭环

1. 项目概述与需求拆解1.1 这个系统到底要做什么停车场管理这个事儿,看起来简单,真做起来涉及的细节其实不少。很多小型停车场还在用最原始的方式:门口保安拿个本子登记车牌,车主离场时翻本子算时间、算费用。这种方式在车辆少的时…

作者头像 李华
网站建设 2026/10/22 2:50:10

提示词工程实战指南:从核心原理到高阶调优技巧

不知道你还记不记得第一次用大模型时的状态:满屏的字看得懂,但让它写一份你真正想要的东西,它却总是“答非所问”或者“一本正经地胡说八道”。很多人把这个归结为“AI笨”,但真实原因往往是你没有把它当做一个“能力很强但必须把…

作者头像 李华
网站建设 2026/10/22 2:50:10

PVN3D模型ONNX Runtime部署:C++自定义算子从导出到联调全解析

做3D视觉模型部署的工程师,尤其是碰过点云位姿估计的,一定对“模型能跑通和模型能上线”之间的差距深有体会。PVN3D作为经典的RGB-D 6D位姿估计模型,训练端用PyTorch跑起来很顺畅,一旦要把它搬到ONNX Runtime上做C服务推理&#x…

作者头像 李华