pcimodules 是 pciutils 软件包的一部分,它通过扫描系统的PCI设备信息,并关联到内核中已加载的模块,显示每个PCI设备所使用的驱动模块。这对于系统管理员和开发者在诊断硬件兼容性问题、驱动加载问题时非常有用。
pcimodules 通常包含在 pciutils 包中,但某些发行版可能需要单独安装:
sudo apt update
sudo apt install pciutils
如果已安装pciutils但pcimodules不存在,可能需要安装完整包:
sudo apt install --reinstall pciutils
sudo yum install pciutils
在较新版本的RHEL/CentOS中,pcimodules可能位于单独包中:
sudo yum install pciutils-pcimodules
which pcimodules 或 pcimodules --version 2>/dev/null || echo "未安装"
pcimodules [选项]
选项:可选参数,用于控制输出格式| 参数 | 说明 |
|---|---|
-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) |
没有模块绑定(可能是内核内置驱动或无驱动) |
查看所有PCI设备的模块信息:
sudo pcimodules
注意:普通用户也可以运行,但可能需要sudo才能看到完整信息。
使用普通用户权限查看:
pcimodules
查看指定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的设备的模块信息。
仅显示有模块绑定的设备:
sudo pcimodules -m
仅显示无模块绑定的设备:
sudo pcimodules -n
显示详细输出:
sudo pcimodules -v
详细输出可能包括设备名称、类别等额外信息。
统计设备总数和模块使用情况:
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
查找未正确加载驱动的设备:
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
自动化驱动加载检查:
#!/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)但实际工作正常:
/sys/bus/pci/devices/设备标识符/driver符号链接pcimodules -k查看内核内置驱动信息设备有驱动但功能不正常:
cat /sys/module/模块名/parameters/*dmesg | grep -i 模块名sudo modprobe -r 模块名 && sudo modprobe 模块名lspci - 列出PCI设备信息setpci - 配置PCI设备寄存器update-pciids - 更新PCI ID数据库pcitweak - PCI设备调试工具pciutils - PCI工具包集合lsmod - 显示已加载的内核模块modprobe - 加载和卸载内核模块insmod - 插入内核模块rmmod - 移除内核模块modinfo - 显示模块信息pcimodules 与 lsmod 的主要区别:
| 特性 | pcimodules |
lsmod |
|---|---|---|
| 关注点 | 设备与模块的绑定关系 | 模块本身的加载状态 |
| 输出内容 | PCI设备 -> 模块映射 | 模块名称、大小、使用计数、依赖关系 |
| 设备信息 | 包含具体设备标识符 | 不包含设备信息 |
| 使用场景 | 硬件驱动诊断、设备管理 | 模块管理、依赖分析 |
| 数据源 | /sys/bus/pci/devices/ 和 /sys/module/ | /proc/modules |
建议:
pcimoduleslsmodpcimodules 获取设备-模块映射关系pcimodules 显示的是当前运行内核的模块绑定状态(none)pcimodules版本可能有差异