Skip to content

Instantly share code, notes, and snippets.

@briantully
Forked from joevt/gfxutil.sh
Created January 28, 2021 04:43
Show Gist options
  • Save briantully/65b4b878d1b7f4c1e4444b255c714d69 to your computer and use it in GitHub Desktop.
Save briantully/65b4b878d1b7f4c1e4444b255c714d69 to your computer and use it in GitHub Desktop.

Revisions

  1. @joevt joevt revised this gist Dec 31, 2020. 1 changed file with 102 additions and 4 deletions.
    106 changes: 102 additions & 4 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # joevt Dec 14, 2020
    # joevt Dec 30, 2020
    # https://forums.macrumors.com/threads/documentation-on-all-parameters-for-nvram.2239034/post-28518123

    gfxutilcmd=~/Downloads/gfxutil
    @@ -86,8 +86,10 @@ setdriverorder () {
    }

    dumpallbootvars () {
    local BootNext=$(nvramp $efiguid:BootNext 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/'Boot'\2\1 /g')
    echo "BootNext: $BootNext"
    for theboot in Current Next; do
    local BootWhat=$(nvramp $efiguid:Boot$theboot 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/'Boot'\2\1 /g')
    echo "Boot$theboot: $BootWhat"
    done
    echo

    for theType in Boot Driver; do
    @@ -102,7 +104,7 @@ dumpallbootvars () {
    IFS=$'\n'
    local lowboot=-1
    for boot in $( {
    eval $(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -u -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
    eval $(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/echo $((0x\2\1 + 1)):1;echo $((0x\2\1 - 1)):-1;/g'); echo 0:1; echo 127:-1; echo 128:1; echo $((0xFFFF)):-1
    } | sort -u -t : -k 1n,2n
    ) ; do
    #echo "checking range $boot"
    @@ -203,3 +205,99 @@ getpanic2 () {
    break
    done
    }



    testbit () {
    local isset=$1
    local fbits=$(($2))
    local fmask=$(($3))
    local fbit=$(($4))
    local fname=$5
    if [[ $isset = "printset" ]]; then
    if ((fbit & fbits)); then
    printf $fname
    if ((!(fbit & fmask))); then
    printf "(error: mask is 0)"
    fi
    printf "\n"
    fi
    elif [[ $isset = "printunset" ]]; then
    if ((!(fbit & fbits))); then
    if (((fbit & fmask))); then
    printf "not $fname"
    printf "\n"
    fi
    fi
    elif [[ $isset = "printignored" ]]; then
    if ((!(fbit & fmask))); then
    printf "ignore $fname"
    printf "\n"
    fi
    fi
    }

    binary () {
    local binary=$(echo "obase=2;ibase=10;$(($1+(1<<32)))"|bc)
    printf ${binary:1}
    }

    parseflags () {
    local fbits=$(($1))
    local fmask=$(($2))
    printf "=========================================================================\n"
    printf "features:%08X %s\n" $fbits $(binary $fbits)
    if [[ -z $2 ]]; then
    fmask=$fbits
    else
    printf " mask:%08X %s\n" $fmask $(binary $fmask)
    fi
    for isset in printset printunset printignored; do
    testbit $isset $fbits $fmask 0x00000001 SUPPORTS_CSM_LEGACY_MODE
    testbit $isset $fbits $fmask 0x00000002 SUPPORTS_CD_DRIVE_BOOT
    testbit $isset $fbits $fmask 0x00000004 SUPPORTS_TARGET_DISK_MODE
    testbit $isset $fbits $fmask 0x00000008 UNKNOWN_BIT3
    testbit $isset $fbits $fmask 0x00000010 SUPPORTS_NET_BOOT
    testbit $isset $fbits $fmask 0x00000020 SUPPORTS_SLING_SHOT
    testbit $isset $fbits $fmask 0x00000040 UNKNOWN_BIT6
    testbit $isset $fbits $fmask 0x00000080 UNKNOWN_BIT7
    testbit $isset $fbits $fmask 0x00000100 SUPPORTS_WIRELESS
    testbit $isset $fbits $fmask 0x00000200 UNKNOWN_BIT9
    testbit $isset $fbits $fmask 0x00000400 PLATFORM_SECURITY_POLICY_01
    testbit $isset $fbits $fmask 0x00000800 PLATFORM_SECURITY_POLICY_02
    testbit $isset $fbits $fmask 0x00001000 SUPPORTS_TRB
    testbit $isset $fbits $fmask 0x00002000 UNKNOWN_BIT13
    testbit $isset $fbits $fmask 0x00004000 SUPPORTS_HIGH_SPEED_USB
    testbit $isset $fbits $fmask 0x00008000 UNKNOWN_BIT15
    testbit $isset $fbits $fmask 0x00010000 UNKNOWN_BIT16
    testbit $isset $fbits $fmask 0x00020000 DISABLE_USB_SUBSTITUTE_WORKAROUND
    testbit $isset $fbits $fmask 0x00040000 UNKNOWN_BIT18
    testbit $isset $fbits $fmask 0x00080000 SUPPORTS_APFS
    testbit $isset $fbits $fmask 0x00100000 SUPPORTS_APFS_EXTRA
    testbit $isset $fbits $fmask 0x00200000 UNKNOWN_BIT21
    testbit $isset $fbits $fmask 0x00400000 SUPPORTS_TRBX
    testbit $isset $fbits $fmask 0x00800000 UNKNOWN_BIT23
    testbit $isset $fbits $fmask 0x01000000 SUPPORTS_PLATFORM_SECURITY_POLICY
    testbit $isset $fbits $fmask 0x02000000 SUPPORTS_EXTENDED_FEATURES
    testbit $isset $fbits $fmask 0x04000000 UNKNOWN_BIT26
    testbit $isset $fbits $fmask 0x08000000 UNKNOWN_BIT27
    testbit $isset $fbits $fmask 0x10000000 DISABLE_MBA_S4_WORKAROUND
    testbit $isset $fbits $fmask 0x20000000 SUPPORTS_UEFI_WINDOWS_BOOT
    testbit $isset $fbits $fmask 0x40000000 UNKNOWN_BIT30
    testbit $isset $fbits $fmask 0x80000000 DISABLE_BOOTSCRIPT_WORKAROUND
    done
    }

    showfirmwarefeatures () {

    local ExtendedFirmwareFeatures=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ExtendedFirmwareFeatures 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/')
    local ExtendedFirmwareFeaturesMask=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ExtendedFirmwareFeaturesMask 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/')

    if [[ -n $ExtendedFirmwareFeatures ]]; then
    parseflags $ExtendedFirmwareFeatures $ExtendedFirmwareFeaturesMask
    else
    local FirmwareFeatures=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:FirmwareFeatures 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/') \
    local FirmwareFeaturesMask=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:FirmwareFeaturesMask 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/')
    parseflags $FirmwareFeatures $FirmwareFeaturesMask
    fi
    }
  2. @joevt joevt revised this gist Dec 14, 2020. 1 changed file with 11 additions and 6 deletions.
    17 changes: 11 additions & 6 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    # joevt Nov 22, 2020
    # joevt Dec 14, 2020
    # https://forums.macrumors.com/threads/documentation-on-all-parameters-for-nvram.2239034/post-28518123

    gfxutilcmd=~/Downloads/gfxutil

    @@ -85,12 +86,12 @@ setdriverorder () {
    }

    dumpallbootvars () {
    local BootNext=$(nvramp $efiguid:BootNext 2> /dev/null | xxd -p -c 99999 | sed -E 's/(..)(..)/'Boot'\2\1 /g')
    local BootNext=$(nvramp $efiguid:BootNext 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/'Boot'\2\1 /g')
    echo "BootNext: $BootNext"
    echo

    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')
    local BootOrder=$(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/'${theType}'\2\1 /g')
    echo "${theType}Order: $BootOrder"
    IFS=$' '
    for theboot in $(echo $BootOrder); do
    @@ -101,19 +102,23 @@ dumpallbootvars () {
    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
    eval $(nvramp $efiguid:${theType}Order 2> /dev/null | xxd -u -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%:*}))
    local first=1
    while ((1)); do
    #echo " checking boot:$boot inc:$inc lowboot:$lowboot"
    thebootvar=${theType}$(printf "%04x" $boot)
    thebootvar=${theType}$(printf "%04X" $boot)
    [[ $BootOrder != *"$thebootvar"* ]] || break
    ((boot > lowboot)) || break
    ((inc > 0)) && ((lowboot = boot))
    echo "Searching: $thebootvar"
    if ((first)); then
    echo "Searching: $thebootvar"
    first=0
    fi
    bootvar $thebootvar 2> /dev/null || break
    ((boot+=inc))
    done
  3. @joevt joevt revised this gist Nov 22, 2020. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # joevt Oct 24, 2020
    # joevt Nov 22, 2020

    gfxutilcmd=~/Downloads/gfxutil

    @@ -85,6 +85,10 @@ setdriverorder () {
    }

    dumpallbootvars () {
    local BootNext=$(nvramp $efiguid:BootNext 2> /dev/null | xxd -p -c 99999 | sed -E 's/(..)(..)/'Boot'\2\1 /g')
    echo "BootNext: $BootNext"
    echo

    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"
    @@ -193,4 +197,4 @@ getpanic2 () {
    ((i++))
    break
    done
    }
    }
  4. @joevt joevt revised this gist Oct 25, 2020. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # joevt Sep 27, 2020
    # joevt Oct 24, 2020

    gfxutilcmd=~/Downloads/gfxutil

    @@ -86,7 +86,7 @@ setdriverorder () {

    dumpallbootvars () {
    for theType in Boot Driver; do
    local BootOrder=$(nvramp $efiguid:${theType}Order | xxd -p -c 99999 | sed -E 's/(..)(..)/'${theType}'\2\1 /g')
    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
    @@ -97,7 +97,7 @@ dumpallbootvars () {
    IFS=$'\n'
    local lowboot=-1
    for boot in $( {
    eval $(nvramp $efiguid:${theType}Order | 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
    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"
    @@ -193,4 +193,4 @@ getpanic2 () {
    ((i++))
    break
    done
    }
    }
  5. @joevt joevt revised this gist Sep 27, 2020. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # joevt Sep 26, 2020
    # joevt Sep 27, 2020

    gfxutilcmd=~/Downloads/gfxutil

    @@ -40,7 +40,7 @@ bootvar () {
    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"; echo -n '"'
    echo -n ', "'; gfxutil "$theFilePathList" | cat; echo -n '"'
    }
    [[ -n $theOptionalData ]] && echo -n ", "'"'"$theOptionalDatastring"'"'
    echo
    @@ -126,7 +126,7 @@ dumpallioregefipaths () {
    if ( /^([ |]*)\+\-o (.+) </ ) { $indent = (length $1) / 2; $name = $2; $thepath =~ s|^((/[^/]*){$indent}).*|$1/$name| }
    if ( /^[ |]*"([^"]+)" = <(.*7fff0400.*)>/i ) { print $thepath . "/" . $1 . " = <" . $2 . ">\n" }
    }
    ' | sed -E '/device-properties/d;/(.*) = <(.*)>/s//echo -n "\1 = "; gfxutil \2; echo/'
    ' | sed -E '/device-properties/d;/(.*) = <(.*)>/s//echo -n "\1 = "; gfxutil \2 | cat; echo/'
    )"
    }

  6. @joevt joevt created this gist Sep 27, 2020.
    196 changes: 196 additions & 0 deletions gfxutil.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,196 @@
    # joevt Sep 26, 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"; 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 | 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 | 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 (.+) </ ) { $indent = (length $1) / 2; $name = $2; $thepath =~ s|^((/[^/]*){$indent}).*|$1/$name| }
    if ( /^[ |]*"([^"]+)" = <(.*7fff0400.*)>/i ) { print $thepath . "/" . $1 . " = <" . $2 . ">\n" }
    }
    ' | sed -E '/device-properties/d;/(.*) = <(.*)>/s//echo -n "\1 = "; gfxutil \2; 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/.*<//;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
    }