Linux pcimodules命令

pcimodules 是一个用于显示PCI设备对应的内核模块信息的工具,它可以列出每个PCI设备正在使用的内核模块,帮助用户了解硬件设备与驱动程序的对应关系。

命令简介

pcimodulespciutils 软件包的一部分,它通过扫描系统的PCI设备信息,并关联到内核中已加载的模块,显示每个PCI设备所使用的驱动模块。这对于系统管理员和开发者在诊断硬件兼容性问题、驱动加载问题时非常有用。

主要功能
  • 列出所有PCI设备及其对应的内核模块
  • 显示模块使用计数
  • 帮助识别未正确加载驱动的设备
  • 辅助诊断硬件兼容性问题
  • 查看驱动模块与设备的绑定关系
注意事项
  • 需要root权限查看完整信息
  • 仅显示当前已加载的模块
  • 某些设备可能使用内核内置驱动(不显示为模块)
  • 虚拟PCI设备可能不显示模块信息
  • 输出信息取决于内核版本

安装方法

pcimodules 通常包含在 pciutils 包中,但某些发行版可能需要单独安装:

Ubuntu/Debian
sudo apt update
sudo apt install pciutils

如果已安装pciutils但pcimodules不存在,可能需要安装完整包:

sudo apt install --reinstall pciutils
CentOS/RHEL
sudo yum install pciutils

在较新版本的RHEL/CentOS中,pcimodules可能位于单独包中:

sudo yum install pciutils-pcimodules
检查是否已安装: 运行 which pcimodulespcimodules --version 2>/dev/null || echo "未安装"

语法格式

pcimodules [选项]
参数说明:
  • 选项:可选参数,用于控制输出格式
  • 如果不指定选项,将显示所有PCI设备及其对应的模块

常用参数

参数 说明
-h--help 显示帮助信息
-V--version 显示版本信息
-k--kernel 显示内核内置驱动信息
-m--modules 仅显示有模块绑定的设备
-n--no-modules 仅显示无模块绑定的设备
-v--verbose 详细输出模式,显示更多信息
-q--quiet 安静模式,只显示关键信息
-s [[域]:]总线:设备.功能 显示指定PCI设备的模块信息
-d [厂商]:[设备] 按厂商和设备ID筛选设备
-c--class 显示设备类别信息
-t--tree 以树状结构显示设备关系
输出格式说明

pcimodules 的标准输出格式为:

设备标识符   模块名称 [使用计数]

示例输出:

0000:00:00.0   amd_nb
0000:00:01.0   k10temp
0000:00:02.0   (none)
0000:00:14.0   xhci_hcd [3]
0000:00:14.2   snd_hda_intel [2]
0000:00:16.0   (none)
0000:00:16.3   mei_me [1]
0000:00:19.0   e1000e [2]
字段 说明
0000:00:00.0 PCI设备标识符(域:总线:设备.功能)
amd_nb 内核模块名称
[3] 模块使用计数(引用计数)
(none) 没有模块绑定(可能是内核内置驱动或无驱动)

使用示例

示例1:基本使用

查看所有PCI设备的模块信息:

sudo pcimodules

注意:普通用户也可以运行,但可能需要sudo才能看到完整信息。

使用普通用户权限查看:

pcimodules
示例2:筛选特定设备

查看指定PCI设备的模块信息:

sudo pcimodules -s 00:14.0

按厂商ID筛选设备:

sudo pcimodules -d 8086:

显示所有Intel(厂商ID 8086)设备的模块信息。

按厂商和设备ID筛选:

sudo pcimodules -d 10de:2204

显示厂商ID为10de(NVIDIA),设备ID为2204的设备的模块信息。

示例3:查看不同状态设备

仅显示有模块绑定的设备:

sudo pcimodules -m

仅显示无模块绑定的设备:

sudo pcimodules -n

显示详细输出:

sudo pcimodules -v

详细输出可能包括设备名称、类别等额外信息。

示例4:统计和分析

统计设备总数和模块使用情况:

sudo pcimodules | wc -l
sudo pcimodules | grep -v "(none)" | wc -l
sudo pcimodules | grep "(none)" | wc -l

按模块使用计数排序:

sudo pcimodules | grep -E "\[[0-9]+\]$" | sort -t'[' -k2 -nr

生成模块使用报告:

#!/bin/bash
echo "PCI设备模块使用报告"
echo "===================="
echo "生成时间: $(date)"
echo ""
echo "设备总数: $(sudo pcimodules | wc -l)"
echo "有模块绑定的设备: $(sudo pcimodules | grep -v "(none)" | wc -l)"
echo "无模块绑定的设备: $(sudo pcimodules | grep "(none)" | wc -l)"
echo ""
echo "模块使用统计:"
sudo pcimodules | awk '{print $2}' | grep -v "(none)" | sort | uniq -c | sort -nr
示例5:诊断和故障排除

查找未正确加载驱动的设备:

sudo pcimodules -n | while read line; do
    dev=$(echo $line | awk '{print $1}')
    echo "设备 $dev 无驱动模块:"
    lspci -s $dev -v | head -5
    echo "---"
done

检查特定类别设备的驱动情况:

# 先查找网络设备的PCI ID
lspci -d ::0200 | awk '{print $1}'

# 然后检查这些设备的模块
for dev in $(lspci -d ::0200 | awk '{print $1}'); do
    echo "设备 $dev:"
    sudo pcimodules -s $dev
done

对比两个系统的模块配置:

# 在系统A上
sudo pcimodules > /tmp/system_a_modules.txt

# 在系统B上
sudo pcimodules > /tmp/system_b_modules.txt

# 比较差异
diff /tmp/system_a_modules.txt /tmp/system_b_modules.txt
示例6:高级用法和脚本集成

自动化驱动加载检查:

#!/bin/bash
# 检查所有PCI设备是否都有正确的驱动加载

echo "开始PCI设备驱动检查..."
FAILED=0

while read -r line; do
    DEVICE=$(echo "$line" | awk '{print $1}')
    MODULE=$(echo "$line" | awk '{print $2}')

    if [ "$MODULE" = "(none)" ]; then
        # 检查是否为重要设备
        CLASS=$(lspci -s "$DEVICE" -n | awk '{print $3}' | cut -d: -f1)

        # 如果是网络设备(02)、存储设备(01)、显示设备(03)且无驱动
        if [[ "$CLASS" =~ ^(01|02|03)$ ]]; then
            echo "警告:重要设备 $DEVICE 无驱动模块"
            lspci -s "$DEVICE" -v | head -3
            FAILED=1
        fi
    fi
done < <(sudo pcimodules)

if [ $FAILED -eq 0 ]; then
    echo "检查完成:所有重要设备驱动正常"
else
    echo "检查完成:发现未加载驱动的重要设备"
    exit 1
fi

创建模块依赖关系图:

#!/bin/bash
# 生成模块依赖关系的简单报告

echo "digraph module_deps {" > modules.dot
echo "  node [shape=box];" >> modules.dot

# 收集所有模块及其使用设备
sudo pcimodules | grep -v "(none)" | while read line; do
    DEVICE=$(echo "$line" | awk '{print $1}')
    MODULE=$(echo "$line" | awk '{print $2}' | sed 's/\[.*\]//')

    # 获取设备描述
    DESC=$(lspci -s "$DEVICE" | cut -d: -f3- | sed 's/^[ \t]*//')

    echo "  \"$MODULE\" -> \"$DEVICE\";" >> modules.dot
    echo "  \"$DEVICE\" [label=\"$DEVICE\\n$DESC\"];" >> modules.dot
done

echo "}" >> modules.dot

echo "已生成 modules.dot 文件,可以使用 Graphviz 可视化"

实用技巧

快速诊断
  • 使用pcimodules -n快速找到无驱动的设备
  • 结合lspci -v查看设备详细信息
  • 使用dmesg | grep -i pci查看PCI相关内核消息
  • 比较不同内核版本的模块绑定情况
系统管理
  • 在系统镜像制作时验证驱动完整性
  • 在硬件变更后检查驱动加载情况
  • 在驱动更新后验证模块绑定
  • 监控模块使用计数变化
脚本编写技巧

在脚本中解析pcimodules输出:

#!/bin/bash
# 将pcimodules输出解析为结构化数据

declare -A device_module_map
declare -A module_usage_count

while read -r line; do
    if [[ -n "$line" ]]; then
        device=$(echo "$line" | awk '{print $1}')
        module=$(echo "$line" | awk '{print $2}')

        # 提取使用计数
        if [[ "$module" =~ ^(.*)\[([0-9]+)\]$ ]]; then
            module_name="${BASH_REMATCH[1]}"
            usage_count="${BASH_REMATCH[2]}"
            device_module_map["$device"]="$module_name"
            module_usage_count["$module_name"]=$(( ${module_usage_count["$module_name"]:-0} + 1 ))
        else
            device_module_map["$device"]="$module"
        fi
    fi
done < <(sudo pcimodules)

# 输出结果
echo "设备总数: ${#device_module_map[@]}"
echo "使用的模块数量: ${#module_usage_count[@]}"
echo ""
echo "模块使用统计:"
for module in "${!module_usage_count[@]}"; do
    echo "  $module: ${module_usage_count[$module]} 个设备"
done
常见问题处理

设备显示为(none)但实际工作正常:

  1. 可能是内核内置驱动(编译到内核中而非模块)
  2. 检查/sys/bus/pci/devices/设备标识符/driver符号链接
  3. 使用pcimodules -k查看内核内置驱动信息

设备有驱动但功能不正常:

  1. 检查模块参数:cat /sys/module/模块名/parameters/*
  2. 查看内核日志:dmesg | grep -i 模块名
  3. 尝试重新加载模块:sudo modprobe -r 模块名 && sudo modprobe 模块名
PCI相关命令
  • lspci - 列出PCI设备信息
  • setpci - 配置PCI设备寄存器
  • update-pciids - 更新PCI ID数据库
  • pcitweak - PCI设备调试工具
  • pciutils - PCI工具包集合
模块相关命令
  • lsmod - 显示已加载的内核模块
  • modprobe - 加载和卸载内核模块
  • insmod - 插入内核模块
  • rmmod - 移除内核模块
  • modinfo - 显示模块信息
命令比较

pcimoduleslsmod 的主要区别:

特性 pcimodules lsmod
关注点 设备与模块的绑定关系 模块本身的加载状态
输出内容 PCI设备 -> 模块映射 模块名称、大小、使用计数、依赖关系
设备信息 包含具体设备标识符 不包含设备信息
使用场景 硬件驱动诊断、设备管理 模块管理、依赖分析
数据源 /sys/bus/pci/devices/ 和 /sys/module/ /proc/modules

建议:

  • 查看设备驱动绑定情况使用 pcimodules
  • 查看系统加载的所有模块使用 lsmod
  • 诊断硬件问题时结合使用两者
  • 在脚本中使用 pcimodules 获取设备-模块映射关系
注意事项
  • pcimodules 显示的是当前运行内核的模块绑定状态
  • 内核内置驱动不会显示为模块,可能显示为(none)
  • 某些设备可能被多个模块支持,但只显示当前绑定的模块
  • 虚拟PCI设备(如虚拟化环境中的设备)可能显示不同的模块信息
  • 模块使用计数可能因设备热插拔而变化
  • 不同发行版中的pcimodules版本可能有差异