Skip to content

Instantly share code, notes, and snippets.

@startergo
Forked from joevt/dumpvols.sh
Created March 30, 2021 03:35
Show Gist options
  • Save startergo/1beb845c800345cf1c320363363a1e54 to your computer and use it in GitHub Desktop.
Save startergo/1beb845c800345cf1c320363363a1e54 to your computer and use it in GitHub Desktop.
A script to help with diagnosing legacy BIOS boot issues on Macs
#!/bin/bash
#
# Get Partition Info from all disks
#
# Written by joevt updated Dec 29. 2020
# Patches marked "rgh" July, 2010, to dump information beyond the
# four bios partitions
#
# sudo ./dumpvols.sh > dumpvols_result.txt 2>&1
#
# Based on johnsock's AHCI Master Boot Record Patch.
#
# This script is freely distributable.
#
if [ ! "$USER" = "root" ]; then
echo WARNING: This script must be run as root.
exit
fi
MBRHASHES=\
"Windows_XP=d88d4f2dbc2c662db7d7d60ebf9e3e00 "\
"Windows_Vista=12c9d7ff4914c88a7f9eadf9211b861b "\
"Windows_7=118eb70c44cb69284e5d8aa93096831e "\
"None_all_zeros=4ebc676ce4896613a3a9df6e2a1c77ae "\
""\
"MSDOS_or_FreeDOS_on_FreeDOS=93dd2ee87a995e36cbab0c2d5c2f041a "\
""\
"Windows_XP_On_BootCamp2_with_AHCI_patch=c3fb54174bc479899d4ef6e45308dc18 "\
"Windows_XP_On_BootCamp2=cb4dabdd862da0508083b05814e198b8 "\
"Windows_Vista_on_XP_with_AHCI_patch=4979e1b9d70738759280f6962c2ad298 "\
"Windows_7_on_XP=7db43c1425e9ff3077dd62b776a50419 "\
"Windows_7_with_AHCI_patch=a243d3475531b0f6f0d7199043c2eb5c "\
"Windows_7_on_XP_with_AHCI_patch=24977c27865adec9ac8298f1a8d214bf "\
""\
"Apple_Partition_Map_Block0_Driver_Descriptor_Map_390721968_blocks_and_Tiger_OS_9_drivers=087f35e49a39d52a46e3a94882869f51 "\
""
#All VBR hashes use all the bytes starting from offset 0x60. It may be better to use a different range for each type of VBR...
# GRUB2 hash was incorrectly named GRUB #rgh
# added GRUB hash from observation of kununtu 9.04 #rgh
# added Windows 8
VBRHASHES=\
"None_all_zeros=acf496fff71230daa6985a701f83ce49 "\
"NTFS_No_Loader=3be27456483746abb85cd614381dac5e "\
"NTFS_Windows_XP_NTLDR=dd1728a59343b9fa9458d80657f68771 "\
"NTFS_Windows_Vista_BOOTMGR=d1c278b56eeea9536d0eb5898fe6a0b5 "\
"NTFS_Windows_8_BOOTMGR=771df8b803f96296854316d3d5918812 "\
"GRUB_from_Ubuntu=332469fa146db809f58d6392e2e0bdce "\
"GRUB2_from_Ubuntu=9c249066e1eb9c842d8acdfe6d23a2e3 "\
"FAT32_FRDOS4.1=98050815221ee147066f99f806c23203 "\
"FAT32_FRDOS4.1_or_MSWIN4.1_BOOTMGR=aec608de8ac709d91e6f3340b643ab4d "\
"FAT32_NTFS_NTLDR=d9c3d66e975d2b3b122353951a598b32 "\
"FAT12_BSD_4.4_BOOTMGR=4cc92970d5a3350bc72d2b975e28b915 "\
"FAT16_Non_system_disk=2a3d0f51ad246f115aa7d37891788857 "\
"FAT32_Non_system_disk_or_EFI=34f2d1f3c3ecce5c00cae8f0b82c922b "\
"HFS_boot_block_0=28f5bc1563fbaedeb8dabbd4ef9eb4c2 "\
""
FindHash () {
# $1: name of hashed contents
# $2: list of known hashes
# $3: the hash to search for
DIDFIND=0
for CURHASH in $2; do
THEHASH=$(expr "$CURHASH" : '[^=]*=\(.*\)')
THEOS=$(expr "$CURHASH" : '^\([^=]*\)=')
if [ "$3" = "$THEHASH" ]; then
DIDFIND=1
break
fi
done
echo ""
if [ $DIDFIND = 1 ]; then
echo "$1: $THEOS"
else
echo "$1: Unrecognized (hash=$3)"
fi
}
disklist="$(diskutil list)"
echo "$disklist"
echo
diskutil apfs list
DRIVELIST=$(sed -n -E "/^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*\*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//\1_\2/p;/^[ ]*0: [ ]{0,26} .* \*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//whole_\1/p" <<< "$disklist")
for PARTDRIVE in $DRIVELIST;
do
DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)')
PTYPE=$(expr "$PARTDRIVE" : '\(.*\)_[^_]*')
echo "==============================================================================="
diskutiloutput="$(sed -nE '/\/dev\/'$DRIVE' /,/^$/ p' <<< "${disklist}")"
echo "$diskutiloutput"
echo "---------------------------------------------"
diskinfo="$(diskutil info $DRIVE)"
echo "$diskinfo"
echo
BLOCKSIZE=$(sed -nE '/^ *Device Block Size: +([0-9]+).*/s//\1/p' <<< "$diskinfo")
if [[ -z $BLOCKSIZE ]]; then
BLOCKSIZE=512
fi
DEVLIST=$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s[0-9]+)$/s//\1/p")
for THEDEV in $DEVLIST; do
echo "---------------------------------------------"
diskutil info $THEDEV
done
if [ "$PTYPE" = "Apple_partition_scheme" ]; then
pdisk -r -l "/dev/$DRIVE"
pdisk -r -l -f "/dev/$DRIVE"
# use the same bytes as MBR hash even though Block0 contents are totally different
HASH=$(dd if="/dev/$DRIVE" bs=1 count=446 2> /dev/null | xxd -p -l 440 | md5)
FindHash "Block0 contents" "$MBRHASHES" "$HASH"
dd if="/dev/$DRIVE" bs=1 count=512 2> /dev/null | xxd -c 16
elif [ "$PTYPE" = "GUID_partition_scheme" -o "$PTYPE" = "FDisk_partition_scheme" ]; then
gptoutput="$(gpt -r show $DRIVE 2>&1)"
gptoutput2="$(gpt -r show -l $DRIVE 2>&1)"
fdiskoutput="$(fdisk /dev/r$DRIVE)"
echo "$gptoutput"
echo "$gptoutput2"
echo "$fdiskoutput"
HASH=$(dd if="/dev/$DRIVE" bs=1 count=446 2> /dev/null | xxd -p -l 440 | md5)
FindHash "MBR contents" "$MBRHASHES" "$HASH"
dd if="/dev/$DRIVE" bs=1 count=512 2> /dev/null | xxd -c 16
if [ "$PTYPE" = "FDisk_partition_scheme" ]; then
PARTLIST=$(echo "$fdiskoutput" | sed -n -E "/^[ \*]+([0-9])\: .*\[[ ]*([0-9]+) \-[ ]+([1-9][0-9]*)\].*$/s//\1_\2_\3/p")
PARTTYPE="MBR"
else
HASH=$(dd if="/dev/$DRIVE" bs=1 skip=$((BLOCKSIZE + 96)) count=416 2> /dev/null | xxd -p -l 440 | md5)
FindHash "GPT Header @ 1: GPT Header contents" "$VBRHASHES" "$HASH"
dd if="/dev/$DRIVE" bs=1 skip=$BLOCKSIZE count=$BLOCKSIZE 2> /dev/null | xxd -c 16
PARTLIST=$(echo "$gptoutput" | sed -n -E "/^[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+GPT part \-.*$/s//\3_\1_\2/p")
PARTTYPE="GPT"
fi
for THEPART in $PARTLIST; do
PNUM=$(expr "$THEPART" : '\([0-9]*\)_')
PSTART=$(expr "$THEPART" : '[0-9]*_\([0-9]*\)_[0-9]*')
PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)')
HASH=$(dd if="/dev/$DRIVE" bs=1 skip=$((PSTART * BLOCKSIZE + 96)) count=416 2> /dev/null | xxd -p -l 440 | md5)
FindHash "$PARTTYPE $PNUM @ $PSTART: VBR contents" "$VBRHASHES" "$HASH"
dd if="/dev/$DRIVE" bs=1 skip=$((PSTART * BLOCKSIZE)) count=$BLOCKSIZE 2> /dev/null | xxd -c 16
done
elif [ "$PTYPE" = "whole" ]; then
HASH=$(dd if="/dev/$DRIVE" bs=1 count=416 2> /dev/null | xxd -p -l 440 | md5)
FindHash "0 @ 0: VBR contents" "$VBRHASHES" "$HASH"
dd if="/dev/$DRIVE" bs=512 count=1 2> /dev/null | xxd -c 16
else
echo "Unknown partition scheme"
fi
done
echo "==============================================================================="
ioreg -rw 0 -c IOMedia | sed -n -E "/^[ \|]*\+\-o (.*) <class IOMedia[^a-zA-Z]/,/^[ \|]+ }$/p" | sed -n -E "/^[ \|]*\+\-o (.*)/s//\1/p;/^[ \|]* \| (.*)/s//\1/p;"
echo "==============================================================================="
bless --verbose --getboot
echo "==============================================================================="
bless --verbose --info
echo "==============================================================================="
ioreg -rw 0 -n AppleEFINVRAM | sed -n -E "/^[ \|]+[ ]+(\".*)$/s//\1/p;"
echo "==============================================================================="
@startergo
Copy link
Author

startergo commented Mar 30, 2021

  • Download
cd ~/Downloads
curl -L https://gist.github.com/joevt/a99e3af71343d8242e0078ab4af39b6c/raw -o dumpvols.sh
xattr dumpvols.sh 2> /dev/null | grep com.apple.quarantine && xattr -d com.apple.quarantine dumpvols.sh
chmod +x dumpvols.sh
  • Run
sudo ./dumpvols.sh > dumpvols_1.txt 2>&1
  • Notes
    Run the command before and after making partition changes. Use a different file name each time. This way you can compare the files to see what changed and to make sure the changes are correct.

This script does not list boot files. Do that manually for each partition you think should be bootable. The boot code in a VBR (also known as PBR) should show what file it's looking to boot. For Windows 7 and later, it should be BOOTMGR. That file should exist in the root directory with a Boot folder containing a BCD folder containing a BCD file. The BCD file contains a menu of items to be bootable and boot options. Use EasyBCD.exe to edit the BCD of any partition. The files may be invisible in macOS - type Command-Shift-Period to show invisible files in the Finder.

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