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