最准、最省事的方法是用ethtool -i查接口对应的pci地址,输出中bus-info字段即标准pci bdf地址;若输出为空,说明接口未加载驱动或非pci设备。

直接用 ethtool -i 查接口对应的 PCI 地址
这是最准、最省事的方法,前提是网卡已加载驱动且接口名已知(比如 enp3s0 或 eth0)。ethtool -i 输出里的 bus-info 字段就是标准 PCI BDF 地址。
常见错误是只跑 ethtool eth0 而漏掉 -i 参数,结果看不到 bus-info;或者没加 sudo(某些驱动下普通用户也能看到,但不保证)。
- 先确认接口名:
ip -br link | grep -v "lo$" - 再查 PCI 地址:
ethtool -i enp3s0 | grep bus-info→ 输出类似bus-info: 0000:03:00.0 - 如果输出为空,说明该接口可能没驱动(比如被
vfio-pci占用),或根本不是 PCI 设备(如 USB 网卡、虚拟机 virtio-net)
用 lspci 反向匹配网卡设备 ID
当你只知道硬件型号(比如 Realtek RTL8168),但不确定它对应哪个接口时,得靠 lspci -nn 提取设备 ID,再和内核识别的模块对上号。
普通用户执行 lspci 常常只看到 Network controller [0280] 这种泛称,连厂商都显示为 Device a0d3 —— 这是因为没权限读完整配置空间。
- 必须加
sudo:sudo lspci -nn | grep -i ethernet - 输出里找形如
[10ec:8168]的字段:前四位是厂商 ID(10ec = Realtek),后四位是设备 ID(8168 = RTL8168) - 再用
sudo lspci -k -s 03:00.0看这个地址是否绑定了Kernel driver in use: r8169,就能确认驱动状态
从 /sys/class/net/ 符号链接提取 PCI 地址
这是纯文件系统路径法,不依赖命令行工具,适合脚本或容器环境(只要挂载了 sysfs)。路径稳定、无权限要求,但格式要手动截取。
注意:readlink /sys/class/net/enp3s0/device 返回的是类似 ../../../0000:03:00.0 的相对路径,末尾才是真正的 BDF,前面的 ../../../ 是冗余前缀。
- 安全提取方式:
basename $(readlink /sys/class/net/enp3s0/device) - 如果返回空,说明该接口没有 PCI device 目录 → 很可能不是物理 PCI 网卡(例如 bond、vlan、wireguard 接口)
- 该方法在 initramfs 或 minimal rootfs 下依然有效,比依赖
lspci或ethtool更底层可靠
lspci 不显示驱动名?大概率缺 sudo 权限
很多人跑 lspci | grep Ethernet 能看到设备行,但死活找不到 Kernel driver in use: —— 这不是 bug,是内核故意限制。PCI 配置空间里驱动绑定状态字段默认只对 root 开放。
现象包括:设备显示为 [device]、BAR 地址全空、Kernel modules: 行缺失。此时 lspci -v 和 lspci -k 必须带 sudo 才能生效。
- 轻量查驱动:
sudo lspci -k | sed -n '/^03:00.0/,/^$/p'(替换03:00.0为目标地址) - 批量查所有网卡驱动:
sudo lspci -k | awk '/^[0-9a-f]+:[0-9a-f]+\.[0-9a-f]+/ { dev=$1 } /Kernel driver in use:/ { print dev, $4 }' - 如果系统禁用了
/proc/bus/pci(如较新 Ubuntu),即使加sudo也可能报错,此时只能退回到sysfs方法
vfio-pci 绑定、或出现在 lspci -t 树里但没挂驱动、或 bus-info 显示正常却 ping 不通 —— 这些时候,PCI 地址只是起点,不是结论。











