#!/usr/bin/bash # 收集pcie信息 parse_regions() { lspci -vv -s "$1" | awk '/Region [0-9]+:/' } get_pcie_topo() { lspci -vt } show_acs() { lspci -vvs "$1" | grep ACS } show_link_status() { local info=$(lspci -vv -s "$1") declare -A lnk=( [cur_speed]=$(grep -ioP 'LnkSta:\s+Speed\s\K[\d.]+' <<< "$info") [max_speed]=$(grep -ioP 'LnkCap:\s+Speed\s\K[\d.]+' <<< "$info") [cur_width]=$(grep -ioP 'LnkSta.*Width\sx\K\d+' <<< "$info") [max_width]=$(grep -ioP 'LnkCap.*Width\sx\K\d+' <<< "$info") ) echo "当前状态 : x${lnk[cur_width]} @ ${lnk[cur_speed]}GT/s " } show_busmaster() { lspci -vv -s "$1" | grep BusMaster | awk '{print $4}' } collect_pcie_logs() { log "收集PCIe系统信息" lspci -D -d :$DEVICE_ID | while read -r dev; do id=${dev:0:12} name=${dev:12} echo echo "$(hline)" echo "设备 ${id}" echo "型号 : ${name}" echo "$(hline)" echo echo "BAR 内存映射:" parse_regions "$id" | sed 's/^/ /' echo echo "PCIe 链路状态:" show_link_status "$id" | sed 's/^/ /' echo echo "PCIe ACS设置" show_acs "$id" | sed 's/^/ /' echo echo "BusMaster设置" show_busmaster "$id" | sed 's/^/ /' done } get_pcie_info() { log "收集PCIe系统信息" collect_pcie_logs > $OUTPUT_DIR/pcie_info.log get_pcie_topo > $OUTPUT_DIR/pcie_vt.log 2>&1 lspci -vvv > $OUTPUT_DIR/pcie_more.log 2>&1 log "PCIe 信息收集完毕" } analyze_regions() { local address echo "$1" # 提取Region关键参数 address=$(echo "$1" | awk '/Memory at/ {print $5}') # 判定逻辑实现 if [[ "$address" == "unassigned" ]]; then echo "[ERROR] Bar地址未分配,需要检查卡的状态(物理连接或供电异常)" echo "建议操作:执行'lspci -vvv'确认设备识别状态}" return 1 elif [[ `echo $address | wc -c` -gt 12 ]]; then echo "[WARNING] Bar地址超出44bit(当前地址:0x${address})" echo "解决方案:调整BIOS的MMIO High Base < 16T}" return 2 fi if [[ "$address" == "" ]]; then echo "[ERROR] 获取不到bar地址" echo "修复建议:检查/proc/cmdline是否包含'pcie=realloc'配置" grep -q "pcie=realloc" /proc/cmdline || echo " 当前配置:$(cat /proc/cmdline)" return 3 fi echo "PCIe 状态正常" return 0 } pcie_check() { if [ ! -f "$1" ]; then echo "file not exists" >&2 exit 1 fi echo "Region 0地址测试" grep "Region 0" $1 | while read -r line; do analyze_regions "$line" done echo "Region 5 地址测试" grep "Region 5" $1 | while read -r line; do analyze_regions "$line" done }