# joevt Oct 24, 2020 gfxutilcmd=~/Downloads/gfxutil alias gfxutil="'$gfxutilcmd'" nvramp () { local thename="$1" local thedata="" # must declare local separately for $? to get the error thedata="$(nvram $thename)" local theerr=$? printf "$(sed -E '/^'$thename'./s///;s/\\/\\\\/g;s/%/\\x/g' <<< "$thedata")" return $theerr } efiguid=8BE4DF61-93CA-11D2-AA0D-00E098032B8C bootvar () { local thebootvar=$1 local thebytes="$(nvramp $efiguid:"$thebootvar" | xxd -p -c 99999; echo ${pipestatus[1]}${PIPESTATUS[0]})" # typedef struct _EFI_LOAD_OPTION local theerr=$(sed -n \$p <<< "$thebytes") if (( !$theerr )); then thebytes=$(sed \$d <<< "$thebytes") local theAttributes=$((0x${thebytes:6:2}${thebytes:4:2}${thebytes:2:2}${thebytes:0:2})) # 0x00000001 LOAD_OPTION_ACTIVE # 0x00000002 LOAD_OPTION_FORCE_RECONNECT # 0x00000008 LOAD_OPTION_HIDDEN # 0x00001F00 LOAD_OPTION_CATEGORY # 0x00000000 LOAD_OPTION_CATEGORY_BOOT # 0x00000100 LOAD_OPTION_CATEGORY_APP local theFilePathListLength=$((0x${thebytes:10:2}${thebytes:8:2})) local theDescription=$(xxd -p -r <<< "${thebytes:12}" | iconv -f UTF-16LE -t UTF-8 | tr '\0' '\n' | sed -n -E '1p' | tr -d '\n') local theoffset=$(( 6 + (${#theDescription}+1) * 2 )) local theFilePathList=${thebytes:$theoffset * 2:$theFilePathListLength*2} ((theoffset += theFilePathListLength)) local theOptionalData=${thebytes:$theoffset * 2} local theOptionalDatastring=$(xxd -p -r <<< "${theOptionalData}" | iconv -f UTF-16LE -t UTF-8 | tr '\0' '\n' | sed -n -E '1p' | tr -d '\n') echo -n "$thebootvar: $theAttributes, "'"'"$theDescription"'"' [[ -n $theFilePathList ]] && { echo -n ', "'; gfxutil "$theFilePathList" | cat; echo -n '"' } [[ -n $theOptionalData ]] && echo -n ", "'"'"$theOptionalDatastring"'"' echo [[ -n $theOptionalData ]] && { echo $theOptionalData | xxd -p -r | xxd -o $theoffset -g $((${#theOptionalData}/2)) -c $((${#theOptionalData}/2)) | perl -pe "s/^([0-9A-Fa-f]+: )([0-9A-Fa-f]+) (.*)/ \1\2\n \1\3/" } fi return $theerr } setbootvar () { local thebootvar=$1 local theAttributes=$2 local theDescription=$3 local theFilePathList=$4 local theOptionalData=$5 local theAttributesBytes=$(printf "%08x" "$theAttributes") local theFilePathListBytes=$(gfxutil "$theFilePathList") local theDescriptionBytes=$(printf "${theDescription}\0" | iconv -f UTF-8 -t UTF-16LE | xxd -p -c 999999) local theFilePathListLength=$((${#theFilePathListBytes} / 2)) local theFilePathListLengthBytes=$(printf "%04x" $theFilePathListLength) local thebytes="${theAttributesBytes:6:2}${theAttributesBytes:4:2}${theAttributesBytes:2:2}${theAttributesBytes:0:2}"\ "${theFilePathListLengthBytes:2:2}${theFilePathListLengthBytes:0:2}"\ "${theDescriptionBytes}"\ "${theFilePathListBytes}"\ "${theOptionalData}" sudo nvram "${efiguid}:${thebootvar}=$(sed -E 's/(..)/%\1/g' <<< ${thebytes})" } setbootorder () { IFS='' local thestring="$*" sudo nvram "${efiguid}:BootOrder=$(sed -E "s/[Bb]oot//g;s/(..)(..)/%\2%\1/g" <<< $thestring)" } setdriverorder () { IFS='' local thestring="$*" sudo nvram "${efiguid}:DriverOrder=$(sed -E "s/[Dd]river//g;s/(..)(..)/%\2%\1/g" <<< $thestring)" } dumpallbootvars () { for theType in Boot Driver; do local BootOrder=$(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -p -c 99999 | sed -E 's/(..)(..)/'${theType}'\2\1 /g') echo "${theType}Order: $BootOrder" IFS=$' ' for theboot in $(echo $BootOrder); do bootvar $theboot 2> /dev/null done #echo "Search loop" IFS=$'\n' local lowboot=-1 for boot in $( { eval $(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -p -c 99999 | sed -E 's/(..)(..)/echo $((0x\2\1 + 1)):1;echo $((0x\2\1 - 1)):-1;/g'); echo 0:1; echo 128:1; echo $((0xffff)):-1 } | sort -u -t : -k 1n,2n ) ; do #echo "checking range $boot" local inc="${boot#*:}" local boot=$((${boot%:*})) while ((1)); do #echo " checking boot:$boot inc:$inc lowboot:$lowboot" thebootvar=${theType}$(printf "%04x" $boot) [[ $BootOrder != *"$thebootvar"* ]] || break ((boot > lowboot)) || break ((inc > 0)) && ((lowboot = boot)) echo "Searching: $thebootvar" bootvar $thebootvar 2> /dev/null || break ((boot+=inc)) done ((inc < 0)) && ((lowboot = boot)) done echo done } dumpallioregefipaths () { eval "$( (ioreg -lw0 -p IODeviceTree; ioreg -lw0) | perl -e ' $thepath=""; while (<>) { if ( /^([ |]*)\+\-o (.+) /i ) { print $thepath . "/" . $1 . " = <" . $2 . ">\n" } } ' | sed -E '/device-properties/d;/(.*) = <(.*)>/s//echo -n "\1 = "; gfxutil \2 | cat; echo/' )" } ioregp () { ioreg -n "$2" -w0 -p "$1" -k "$3" | sed -nE 's/^[ |]+"'"$3"'" = <(.*)>/\1/p' | xxd -p -r } getdeviceprops () { ioreg -rw0 -p IODeviceTree -n efi | grep device-properties | sed 's/.*.*//;' | xxd -p -r } getaaplpathprops () { # Get device properties from nvram AAPL,PathProperties0000,0001,etc. # (max 768 per nvram var) i=0 while (( 1 )); do thevar="4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:AAPL,PathProperties$(printf "%04X" $i)" theval="$(nvram "$thevar" 2> /dev/null)" [[ -z $theval ]] && break printf "$(echo -n "$theval" | sed -E '/^'$thevar'./s///;s/\\/\\\\/g;s/%/\\x/g')" ((i++)) done } setaaplpathprops () { local thefile="$1" local theproperties=$(xxd -p -c 99999 "$1") local thevar=0 while ((1)); do local thepart=${theproperties:$thevar*768*2:768*2} local thename="4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:AAPL,PathProperties"$(printf "%04X" thevar) if [[ -n $thepart ]]; then sudo nvram "${thename}=$(sed -E 's/(..)/%\1/g' <<< ${thepart})" else nvram "${thename}" > /dev/null 2>&1 && sudo nvram -d "$thename" || break fi ((thevar++)) done } getpanic () { # Get device properties from nvram AAPL,PanicInfo000K,000M,etc. # (max 768 per nvram var) i=0 while (( 1 )); do thevar="AAPL,PanicInfo000$(printf "%02x" $((0x$(printf 'K' | xxd -p) + i)) | xxd -p -r)" theval="$(nvram "$thevar" 2> /dev/null)" [[ -z $theval ]] && break printf "$(echo -n "$theval" | sed -E '/^'$thevar'./s///;s/\\/\\\\/g;s/%/\\x/g')" ((i++)) done } getpanic2 () { # Get device properties from nvram aapl,panic-info # (max 768 per nvram var) i=0 while (( 1 )); do thevar="aapl,panic-info" theval="$(nvram "$thevar" 2> /dev/null)" [[ -z $theval ]] && break printf "$(echo -n "$theval" | sed -E '/^'$thevar'./s///;s/\\/\\\\/g;s/%/\\x/g')" ((i++)) break done }