Skip to content

Instantly share code, notes, and snippets.

@startergo
Forked from joevt/gfxutil.sh
Last active January 8, 2021 17:40
Show Gist options
  • Save startergo/427f8ec93c79dca6a6b0c9448561c6e4 to your computer and use it in GitHub Desktop.
Save startergo/427f8ec93c79dca6a6b0c9448561c6e4 to your computer and use it in GitHub Desktop.
macOS nvram boot variables, device properties, EFI device paths
# joevt Nov 22, 2020
# https://forums.macrumors.com/threads/documentation-on-all-parameters-for-nvram.2239034/post-28518123
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 () {
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"
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 (.+) </ ) { $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 | 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/.*<//;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
}
@startergo
Copy link
Author

startergo commented Dec 19, 2020

  • download:
 curl -L https://gist.github.com/joevt/6d7a0ede45106345a39bdfa0ac10ffd6/raw -o ~/Downloads/DiskUtil.sh
 curl -L https://gist.github.com/joevt/477fe842d16095c2bfd839e2ab4794ff/raw -o ~/Downloads/gfxutil.sh
  • Install temporarily:
source ~/Downloads/DiskUtil.sh
source ~/Downloads/gfxutil.sh
  • grep Boot0080 path to establish the drivers path:
mountEFIpartitions
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../efis/nv_gop_GF10x.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../drivers/CrScreenshotDxe.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../drivers/ReloadPCIRom.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../drivers/FakeUEFI2.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../drivers/UgaOnGop.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../drivers/apfs.efi --setboot ; dumpallbootvars | grep Boot0080:
sudo bless --mount /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../ --file /Volumes/EFI*/EFI_Windows8and10_MercuryElectra3G_bay2/../EFI/BOOT/bootx64.efi --setboot

Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\efis\nv_gop_GF10x.efi"
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\CrScreenshotDxe.efi"
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\ReloadPCIRom.efi"
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\FakeUEFI2.efi"
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\UgaOnGop.efi"
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\apfs.efi"

  • setbootvar drivers order according to the previously established Boot0080 path:
setbootvar Driver0080 1 "apfs.efi"            "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\apfs.efi"
setbootvar Driver0081 1 "FakeUEFI2.efi"       "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\FakeUEFI2.efi"
setbootvar Driver0082 1 "nv_gop_GF10x"        "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\efis\nv_gop_GF10x.efi"
setbootvar Driver0083 1 "ReloadPCIRom.efi"    "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\ReloadPCIRom.efi"
setbootvar Driver0084 1 "UgaOnGop.efi"        "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\UgaOnGop.efi"
setbootvar Driver0085 1 "CrScreenshotDxe.efi" "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\CrScreenshotDxe.efi"

  • dumpallbootvars to verify the proper blessing:
dumpallbootvars

BootOrder: Boot0080 
Boot0080: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\EFI\BOOT\bootx64.efi"
Searching: Boot0000
Searching: Boot007f
Searching: Boot0081
Boot0081: 1, "Mac OS X", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x0,0x0)/HD(10,GPT,977D4C1D-54CA-4594-B9F6-FCABF87AC36C,0x4B405D88,0x174876E8)/VenMedia(BE74FCF7-0B7C-49F3-9147-01F4042E6842,7E98A08505BD8940A1199C16AA7CD67D)/\10D5CE8C-43FE-43F2-8089-DAEDF6485644\System\Library\CoreServices\boot.efi"
Searching: Boot0082
Boot0082: 1, "BootPicker", "MemoryMapped(0xB,0xFFE00000,0xFFF7FFFF)/FvFile(E1628C66-2A2D-4DC5-BD41-B20F3538AAF7)"
Searching: Boot0083
Boot0083: 1, "SetupBrowserDxe", "MemoryMapped(0xB,0xFFE00000,0xFFF7FFFF)/FvFile(EBF342FE-B1D3-4EF8-957C-8048606FF670)"
Searching: Boot0084
Searching: Bootffff

DriverOrder: Driver0080 Driver0081 Driver0082 Driver0084 Driver0085 
Driver0080: 1, "apfs.efi", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\apfs.efi"
Driver0081: 1, "FakeUEFI2.efi", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\FakeUEFI2.efi"
Driver0082: 1, "nv_gop_GF10x", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\efis\nv_gop_GF10x.efi"
Driver0084: 1, "UgaOnGop.efi", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\UgaOnGop.efi"
Driver0085: 1, "CrScreenshotDxe.efi", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\CrScreenshotDxe.efi"
Searching: Driver0000
Searching: Driver007f
Searching: Driver0083
Driver0083: 1, "ReloadPCIRom.efi", "PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)/HD(1,GPT,97CD1709-FE99-4E1F-BF41-75D379A46CC4,0x28,0x64000)/\drivers\ReloadPCIRom.efi"
Searching: Driver0086
Searching: Driverffff

  • NVRAM to base64:
    nvramp csr-active-config | base64

  • without the gfxutil.sh script, you can do it with this:

printf $(nvram csr-active-config | sed -E '/^csr-active-config./s///;s/\\/\\\\/g;s/%/\\x/g') | base64
  • String conversion from a UEFI format:
thestring="w%00%00%00"
printf $(perl -pE 's/^.*?\t//;s/\\/\\\\/g;s/%/\\x/g' <<< "$thestring") | xxd -p -c 1 | sed '1!G;s/\n//;h;$!d'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment