Script for EDAC Diagnosis

Here is a bash script that I wrote to grab the important information using dmidecode. The problem with “Having to invert the logic” as Sebastian mentioned in his comment on my previous post on “How To Diagnose Memory Errors on AMD x86_64 using EDAC”┬áis handled by using the switch -b.

Sorry that there are no comments. I was just playing around when I wrote this and never cleaned it up.

#!/bin/bash

if [[ $# = 1 && $1 = "-b" ]];then
  bug=1
else
  bug=0
fi

# Get some details on the mobo (dmidecode -t 1)

function Decode_1
{
 local _1=$(dmidecode -t 1 )
 echo "- MOTHERBOARD on $(hostname) -"
 ifs=${IFS}; IFS=$'\n'
 for i in $_1;do
   local parm=${i#$'\t'} # Remove the leading tab character
   case ${parm} in
     Manufacturer*) echo ${parm} ;;
     Product\ Name*) echo ${parm} ;;
   esac
 done
 echo
 IFS=${ifs}
}

# Get some details on the physical RAM type and capacity (dmidecode -t 16) and
# the address ranges by calling Decode_19 for each 'System Memory' handle.

function Decode_16
{
 local _16=$(dmidecode -t 16)
 ifs=${IFS}; IFS=$'\n'
 for i in $_16;do
   local parm=${i#$'\t'} # Remove the leading tab character
   case ${parm} in
     Handle*) local Handle=${parm%%,*}; Handle=${Handle##* } ;;
     Use*) local Use=${parm} ;;
     Error\ Correction*) local Error="${parm}" ;;
     Maximum*) local Maximum="${parm}" ;;
     Number*) local Number="${parm}"
       [[ "${Use#*: }" == 'System Memory' ]] || continue
       echo "- RAM TYPE and CAPACITY -"
       echo "Handle: ${Handle}"
       echo "${Use}"
       echo "${Error}"
       echo "${Maximum}"
       echo "${Number} (Maximum number of DIMMS)"
       Decode_19 ${Handle}
       echo
       ;;
   esac
 done
 IFS=${ifs}
}

# Get some details on the RAM addresses (dmidecode -t 19) for a particular
# physical memory array with handle $1

function Decode_19
{
 local handle=$1
 [[ -n "${_19}" ]] || _19=$(dmidecode -t 19)
 ifs=${IFS}; IFS=$'\n'
 for i in $_19;do
   local parm=${i#$'\t'} # Remove the leading tab character
   case ${parm} in
     Handle\ *) local Handle=${parm%%,*}; Handle=${Handle##* } ;;
     Physical*) local Physical=${parm##*: } ;;
     Starting*) local Starting="${parm}" ;;
     Ending*) local Ending="${parm}" ;;
     Range*) local Range="${parm}" ;;
     Partition*) local Partition="${parm}"
       [[ "${Physical}" == "${handle}" ]] || continue
       echo "${Starting}"
       echo "${Ending}"
       echo "${Range} (Currently installed)"
       echo "${Partition}"
       Decode_17 ${Physical}
       ;;
   esac
 done
 IFS=${ifs}
}

# Get the handle and location for each DIMM currently in the box with physical
# array handle $1 (dmidecode -t 17) and get the DIMM address range by calling
# the function Decode_21.

function Decode_17
{
 local handle=$1
 [[ -n "${_17}" ]] || _17=$(dmidecode -t 17)
 echo; echo "- DIMM DETAILS and ADDRESS RANGE -"
 ifs=${IFS}; IFS=$'\n'
 for i in $_17;do
   local parm=${i#$'\t'} # Remove the leading tab character
   case ${parm} in
     Handle*) local Handle=${parm%%,*}; Handle=${Handle##* } ;;
     Array*) local Array=${parm##*: } ;;
     Size:*) local Size=${parm##*: } ;;
     Locator:*) Locator=${parm##*: } ;;
     Bank*) local Bank=${parm##*: } ;;
     Speed*) local Speed=${parm##*: } ;;
     Rank*) local Rank=${parm##*: }
       [[ "${Array}" == "${handle}" && "${Size}" != "No Module Installed" ]] || continue
       if [[ $bug = 1 ]]; then
         Handle=$(printf "%#4.4X" $((${Handle}+0x2)))
         Handle=${Handle/X/x}
       fi
       printf "Handles: %s,%s %s %s %s " \
       "${handle}" "${Handle}" "$Size" "$Locator" "${Bank}"
       Decode_20 ${Handle}
       ;;
   esac
 done
 IFS=${ifs}
}

# Get the address range for the DIMM with handle $1 (dmidecode -t 20).

function Decode_20
{
 [[ -n "${_20}" ]] || _20=$(dmidecode -t 20 )
 local ifs=${IFS}; IFS=$'\n'
 local handle=$1
 for i in $_20;do
   local parm=${i#$'\t'} # Remove the leading tab character
   case ${parm} in
     Starting*) local Starting=${parm##*: } ;;
     Ending*) local Ending=${parm##*: } ;;
     Range*) local Size=${parm##* } ;;
     Physical*) local Physical=${parm##*: }
       [[ "${Physical}" == "${handle}" ]] || continue
       printf "%s %s\n" "${Starting}" "${Ending}"
       ;;
   esac
 done
 IFS=${ifs}
}

# Main script

Decode_1
Decode_16

Leave a Reply

Your email address will not be published. Required fields are marked *