Skip to content

Instantly share code, notes, and snippets.

@joevt
Last active October 9, 2023 16:15
Show Gist options
  • Save joevt/477fe842d16095c2bfd839e2ab4794ff to your computer and use it in GitHub Desktop.
Save joevt/477fe842d16095c2bfd839e2ab4794ff to your computer and use it in GitHub Desktop.
macOS nvram boot variables, device properties, EFI device paths
#!/bin/bash
# joevt Jun 13, 2023
# https://forums.macrumors.com/threads/documentation-on-all-parameters-for-nvram.2239034/post-28518123
gfxutilrepository="/Volumes/Work/Programming/EFIProjects/gfxutil/joevt-gfxutil"
for gfxutilcmd in \
~/Downloads/gfxutil/gfxutil \
~/Downloads/gfxutil \
"$gfxutilrepository/build/Release/gfxutil" \
"$gfxutilrepository/build/Debug/gfxutil" \
"$gfxutilrepository/DerivedData/gfxutil/Build/Products/Debug/gfxutil" \
"" \
; do
if [[ -f $gfxutilcmd ]] && file $gfxutilcmd | grep -q "$(uname -m)"; then
break
fi
done
if [[ ! -f "$gfxutilcmd" ]]; then
echo "# Download and build gfxutil from https://github.com/joevt/gfxutil , then update the path of gfxutil defined in gfxutil.sh"
fi
alias gfxutil='"$gfxutilcmd"'
directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
usedirectbless=0
if [[ -d /System/Library/PrivateFrameworks/APFS.framework/Versions/A ]]; then
if [[ ! -f "$directblesscmd" ]]; then
echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in gfxutil.sh"
else
usedirectbless=1
fi
fi
if ((usedirectbless)); then
directbless=$directblesscmd
alias directbless='"$directbless"'
else
directbless=bless
alias directbless=bless
fi
pipestatus=( ) # to clear an error in ShellCheck
patmatch () {
# substitute for [[ =~ ]] for Mac OS X 10.4
perl -0777 -ne '<>; exit !( $_ =~ /'"$1"'/ )'
}
nvramp () {
local thename="$1"
local thedata="" # must declare local separately for $? to get the error
thedata="$(nvram "$thename")"
local theerr=$?
# we want to use variables in the printf format string
printf "$(sed -E '/^'"$thename"'./s///;s/\\/\\\\/g;s/%([0-9a-f]{2})/\\x\1/g;s/%/%%/g' <<< "$thedata")"
return $theerr
}
efiguid=8BE4DF61-93CA-11D2-AA0D-00E098032B8C
ocguid=4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102
dumponebootvar () {
local pathonly=0
if [[ $1 == '-p' ]]; then
pathonly=1
shift
fi
local thebootvar="$1"
local thebytes="$2"
# typedef struct _EFI_LOAD_OPTION
local theerr=""
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=""
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=""
theOptionalDatastring=$(xxd -p -r <<< "${theOptionalData}" | iconv -f UTF-16LE -t UTF-8 | tr '\0' '\n' | sed -n -E '1p' | tr -d '\n')
if (( pathonly )); then
echo "$theFilePathList"
else
printf "%s %s \"%s\"" "$thebootvar" "$theAttributes" "$theDescription"
local parts=0
while [[ -n $theFilePathList ]]; do
(( parts++ ))
local thepath=""
local pathbytes=""
thepath=$(gfxutil "$theFilePathList")
theerr=$?
if (( theerr )); then
(( parts == 1 )) && printf " "
printf "\"%s\"" "$theFilePathList"
theFilePathList=""
theerr=0
else
(( parts == 1 )) && printf " "
printf "\"%s\"" "$thepath"
pathbytes=$(gfxutil "$thepath")
if patmatch "$pathbytes" <<< "$theFilePathList"; then
theFilePathList=${theFilePathList:${#pathbytes}}
else
printf " # Device path %s does not match %s" "$pathbytes" "$theFilePathList"
theFilePathList=""
fi
fi
done
[[ -n $theOptionalData ]] && printf " \"%s\"" "$theOptionalDatastring"
echo
[[ -n $theOptionalData ]] && {
printf "%s\n" "$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"
}
bootvar () {
local pathonly=""
for ((;;)); do
if [[ $1 == '-p' ]]; then
pathonly="-p"
shift
else
break
fi
done
local thebootvar="$1"
local theguid=$efiguid
if patmatch '^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}:' <<< "$thebootvar"; then
theguid=${thebootvar:0:36}
thebootvar=${thebootvar:37}
fi
local thebytes=""
thebytes="$(nvramp "$theguid:$thebootvar" | xxd -p -c 99999; echo "${pipestatus[1]}${PIPESTATUS[0]}")"
local theerr=""
theerr=$(sed -n \$p <<< "$thebytes")
if (( ! theerr )); then
thebytes=$(sed \$d <<< "$thebytes")
eval 'dumponebootvar '"$pathonly"' "'"$thebootvar"'" '"$thebytes"
theerr=$?
fi
return "$theerr"
}
setnvramhex () {
sudo nvram "$1=$(sed -E 's/(..)/%\1/g' <<< "${2}")"
}
setbootvar () {
local thebootvar=$1
local theAttributes=$2
local theDescription=$3
local theFilePathList=$4
local theOptionalData=$5
local theAttributesBytes=""
theAttributesBytes=$(printf "%08x" "$theAttributes")
local theDescriptionBytes=""
theDescriptionBytes=$(printf "%s\0" "$theDescription" | iconv -f UTF-8 -t UTF-16LE | xxd -p -c 999999)
local theFilePathListBytes=""
local thepat='^([a-z0-9]{2})*7fff0400$'
if patmatch "$thepat" <<< "$theFilePathList"; then
theFilePathListBytes="$theFilePathList"
elif [[ -e $theFilePathList ]]; then
theFilePathListBytes=$(getefipath "$theFilePathList")
else
theFilePathListBytes=$(gfxutil "$theFilePathList")
fi
local theFilePathListLength=$((${#theFilePathListBytes} / 2))
local theFilePathListLengthBytes=0
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}"
local theguid=$efiguid
if patmatch '^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}:' <<< "$thebootvar"; then
theguid=${thebootvar:0:36}
thebootvar=${thebootvar:38}
fi
setnvramhex "${theguid}:${thebootvar}" "${thebytes}"
}
setbootorder () {
IFS=''
local theguid=$efiguid
local thestring="$*"
sudo nvram "${theguid}: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 theguid in $efiguid; do
local theboot=""
for theboot in Current Next; do
local BootWhat=""
BootWhat=$(nvramp "$theguid:Boot$theboot" 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/Boot\2\1/g')
echo "Boot$theboot: $BootWhat"
done
local Timeout=""
Timeout=$((0x$(nvramp "$theguid:Timeout" 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/\2\1/g')))
echo "Timeout: ${Timeout}s"
echo
local needlinefeed=0
local theType=""
for theType in Boot Driver; do
local BootOrder=""
BootOrder=$(nvramp "$theguid:${theType}Order" 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/'"${theType}"'\2\1 /g;/ $/s///')
echo "${theType}Order: $BootOrder"
IFS=$' '
for theboot in $(printf "%s" "$BootOrder"); do
bootvar "${theguid}:${theboot}" 2> /dev/null
done
#echo "Search loop"
IFS=$'\n'
local lowboot=-1
local boot=""
for boot in $( {
eval "$(nvramp "$theguid:${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"
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)
[[ $BootOrder != *"$thebootvar"* ]] || break
((boot > lowboot)) || break
((inc > 0)) && ((lowboot = boot))
if ((first)); then
if ((needlinefeed)); then
printf ", "
else
printf "#Searching: "
fi
printf "%s" "$thebootvar($inc)"
needlinefeed=1
first=0
fi
local bootinfo=""
bootinfo="$(bootvar "${theguid}:${thebootvar}" 2> /dev/null)"
local theerr=$?
if ((theerr)); then
break
fi
if ((needlinefeed)); then
echo
needlinefeed=0
fi
printf "%s\n" "$bootinfo"
((boot+=inc))
done
((inc < 0)) && ((lowboot = boot))
done
if ((needlinefeed)); then
echo
needlinefeed=0
fi
echo
done
done
}
getefipath () {
# Takes a path to a file or directory or volume and outputs the EFI device path in hex.
# Note: Overwrites BootNext
local thefile="$1"
local theguid=$efiguid
# First, get current boot vars
local BootOrderValue=""
BootOrderValue=$(nvramp $theguid:BootOrder 2> /dev/null | xxd -u -p -c 99999)
local BootOrder=""
BootOrder=$(sed -E 's/(..)(..)/Boot\2\1 /g;/ $/s///' <<< "$BootOrderValue")
eval "$(sed -E 's/(..)(..)/local Boot\2\1=''$''(nvramp '"$theguid"':Boot\2\1 2> \/dev\/null | xxd -u -p -c 99999) ; /g' <<< "$BootOrderValue")"
# We won't try to preserve BootNext - that would require preserving efi-boot-next-data
#local BootNextValue=""
#local BootNextName=""
#BootNextValue=$(nvramp $theguid:BootNext 2> /dev/null | xxd -u -p -c 99999)
#BootNextName="Boot${BootNextValue:2:2}${BootNextValue:0:2}"
# Use bless to convert file path to EFI device path - this affects BootNext and one of the boot vars
if ( sudo "$directbless" --mount "$thefile" --file "$thefile" --nextonly --setBoot ); then
local thebootvar=""
thebootvar=$(nvramp $theguid:BootNext 2> /dev/null | xxd -u -p -c 99999 | sed -E 's/(..)(..)/Boot\2\1/g')
local thepath=""
thepath=$(bootvar -p "${theguid}:${thebootvar}" 2> /dev/null)
local theerr=$?
if (( theerr == 0 )); then
# if one of the existing boot vars was affected, then restore it
if patmatch "$thebootvar" <<< "$BootOrder"; then
setnvramhex "$theguid:$thebootvar" "$(eval 'echo $'"${thebootvar}")"
fi
# output the result
printf "%s" "$thepath"
else
echo "# BootNext:$thebootvar not set" 1>&2
return 1
fi
# cleanup BootNext
sudo nvram -d $theguid:BootNext
sudo nvram -d efi-boot-next-data
else
echo '# This bless command failed:' 1>&2
echo '# sudo "'"$directbless"'" --mount "'"$thefile"'" --file "'"$thefile"'" --nextonly --setBoot' 1>&2
return 1
fi
return 0
}
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//printf "%s = " "\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
}
convertnvramstring () {
local thevar="$1"
local thevar="$2"
# we want to use variables in the printf format string
printf "$(printf "%s" "$theval" | sed -E '/^'"$thevar"'./s///;s/\\/\\\\/g;s/%/\\x/g')"
}
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
convertnvramstring "$thevar" "$theval"
((i++))
done
}
setaaplpathprops () {
local thefile="$1"
local theproperties=""
theproperties=$(xxd -p -c 99999 "$1")
local thevar=0
while ((1)); do
local thepart=${theproperties:$thevar*768*2:768*2}
local thename=""
thename="4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:AAPL,PathProperties"$(printf "%04X" thevar)
if [[ -n $thepart ]]; then
sudo nvram "${thename}=$(sed -E 's/(..)/%\1/g' <<< "${thepart}")"
elif nvram "${thename}" > /dev/null 2>&1; then
sudo nvram -d "$thename"
else
break
fi
((thevar++))
done
}
getpanic () {
# Get panic log 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
convertnvramstring "$thevar" "$theval"
((i++))
done
}
getpanic2 () {
# panic log 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
convertnvramstring "$thevar" "$theval"
((i++))
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 "%s" "$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 %s" "$fname"
printf "\n"
fi
fi
elif [[ $isset = "printignored" ]]; then
if ((!(fbit & fmask))); then
printf "ignore %s" "$fname"
printf "\n"
fi
fi
}
GetNum64 () {
local thenum="$1"
printf "%s" $(( (0x${thenum:0:1} << 60) | 0x${thenum:1} ))
}
binary () {
local thenum="$1" # input decimal number
local numbits="$2"
local binary=""
binary=$(bc <<< "obase=2;ibase=10;$thenum")
printf "%${numbits}s" "${binary}" | tr ' ' '0'
}
parseflags () {
local fbits=$(($1))
local fmask=$(($2))
local numbits=$(($3))
local numhex=$(((numbits + 3) / 4))
printf "=========================================================================\n"
if ((numbits > 32)); then
echo ExtendedFirmwareFeatures
else
echo FirmwareFeatures
fi
printf "features:%0${numhex}X %s\n" $fbits "$(binary $fbits $numbits)"
if [[ -z $2 ]]; then
fmask=$fbits
else
printf " mask:%0${numhex}X %s\n" $fmask "$(binary "$(printf "%u" $fmask)" $numbits)"
fi
local isset=""
for isset in printset printunset printignored; do
#https://github.com/acidanthera/OpenCorePkg/blob/master/Include/Apple/IndustryStandard/AppleFeatures.h
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
testbit $isset $fbits $fmask 0x800000000 SUPPORTS_LARGE_BASESYSTEM
done
}
showfirmwarefeatures () {
local ExtendedFirmwareFeatures=""
ExtendedFirmwareFeatures=$(GetNum64 "$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ExtendedFirmwareFeatures 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//\1/')")
local ExtendedFirmwareFeaturesMask=""
ExtendedFirmwareFeaturesMask=$(GetNum64 "$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:ExtendedFirmwareFeaturesMask 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//\1/')")
if [[ -n $ExtendedFirmwareFeatures ]]; then
parseflags "$ExtendedFirmwareFeatures" "$ExtendedFirmwareFeaturesMask" 36
fi
local FirmwareFeatures=""
FirmwareFeatures=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:FirmwareFeatures 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/')
local FirmwareFeaturesMask=""
FirmwareFeaturesMask=$(nvramp 4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14:FirmwareFeaturesMask 2> /dev/null | xxd -g 8 -e | sed -E '/^[^:]+: +([^ ]+).*/s//0x\1/')
if [[ -n $FirmwareFeatures ]]; then
parseflags "$FirmwareFeatures" "$FirmwareFeaturesMask" 32
fi
}
@joevt
Copy link
Author

joevt commented Sep 27, 2020

Download

curl -L "https://github.com/acidanthera/gfxutil/releases/download/1.80b/gfxutil-1.80b-DEBUG.zip" -o ~/Downloads/gfxutil.zip
unzip ~/Downloads/gfxutil.zip -d ~/Downloads
curl -L https://gist.github.com/joevt/477fe842d16095c2bfd839e2ab4794ff/raw -o ~/Downloads/gfxutil.sh

Install (temporarily)

source ~/Downloads/gfxutil.sh

Set some EFI drivers
This is an example. If you have EFI drivers to load, they will be different than these. If you don't want to load EFI drivers, then don't do this.

setbootvar Driver0080 1 "apfs.efi"            /Volumes/EFI*/*_bay2/../drivers/apfs.efi
setbootvar Driver0081 1 "FakeUEFI2.efi"       /Volumes/EFI*/*_bay2/../drivers/FakeUEFI2.efi
setbootvar Driver0082 1 "nv_gop_GF10x"        /Volumes/EFI*/*_bay2/../efis/nv_gop_GF10x.efi
setbootvar Driver0083 1 "ReloadPCIRom.efi"    /Volumes/EFI*/*_bay2/../drivers/ReloadPCIRom.efi
setbootvar Driver0084 1 "UgaOnGop.efi"        /Volumes/EFI*/*_bay2/../drivers/UgaOnGop.efi
setbootvar Driver0085 1 "CrScreenshotDxe.efi" /Volumes/EFI*/*_bay2/../drivers/CrScreenshotDxe.efi
setdriverorder Driver0080 Driver0081 Driver0082 Driver0083 Driver0084 Driver0085

List the Boot#### and Driver#### variables

dumpallbootvars
dumpallioregefipaths

@joevt
Copy link
Author

joevt commented Jan 29, 2021

Update 1:

  • Can now pass volume or directory or file path to setbootvar. See examples in first comment.

Jun 5, 2021:

  • getefipath now ensures that the boot order variables are not modified (but BootNext is still deleted).

Aug 22, 2021:

  • Sometimes a bootvar has multiple UEFI device paths so we'll try to list them all.
  • Use printf because echo might do weird stuff with some back-slashes (e.g. \b is backspace).

Oct 11, 2021:

  • Add SUPPORTS_LARGE_BASESYSTEM firmware features flag.
  • Check if gfxutil was downloaded to a folder.
  • Correctly output features and feature masks that are greater than 32 bit.
  • Output both features and extended features.

Dec 24, 2021:

  • Add some Mac OS X 10.4 compatibility.
  • Fix directbless check.
  • If gfxutil can't get a device path then at least dump the hex for the bootvar.

Mar 5, 2023:

  • bootvar and setbootvar can work with Boot#### variables from a specific guid instead of just the default EFI guid. For example, Open Core has its own copy of Boot#### variables which you can get using $ocguid
  • Use workaround GetNum64 to parse 64-bit unsigned numbers so that showfirmwarefeatures shows all 64 bits of the ExtendedFirmwareFeatures mask instead of just 60 bits. Don't use the shell to parse thenum in the binary method; let bc handle the unparsed value since it won't complain about overflow.

Jun 12, 2023:

  • dumponebootvar parses a hex string as a bootvar.

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