echo "Check Previous Chameleon: Will there be problems?"␊ |
echo "***********************************************"␊ |
␊ |
# Checks the selected volume is present and the disk is partitioned␊ |
# Now also check for another existing Chameleon installation on the same disk.␊ |
# Checks for another existing Chameleon installation on the same disk␊ |
# and tries to make sure the user doesn't end up with an un-bootable␊ |
# system due to having installed Chameleon previously elsewhere.␊ |
␊ |
# Called from the Standard/postinstall and EFI/postinstall scripts␊ |
# /Volumes/EFI should already be mounted before this is called.␊ |
␊ |
# Receives targetDisk: for example, /dev/disk3.␊ |
# Receives targetDeviceRaw: for example, /dev/rdisk3s1.␊ |
# Receives targetDevice: Stores device number, for example /dev/disk2s1.␊ |
|
fi␊ |
␊ |
␊ |
# Check for existing Chameleon installations on a different␊ |
# partition of the same target disk.␊ |
#echo "DEBUG: Checking for existing Chameleon installations on ${targetDisk#/dev/}..."␊ |
# ===============================================␊ |
# Prepare some vars␊ |
# ===============================================␊ |
sliceNumber=$( echo ${targetDeviceRaw#*disk*s} )␊ |
␊ |
sliceNumber=$( echo ${targetDeviceRaw#*disk*s} )␊ |
# strip slice from end␊ |
targetDiskRawNoSlice=$( echo ${targetDeviceRaw%$sliceNumber} )␊ |
␊ |
|
# How many actual partitions are there?␊ |
numSlices=$(( $( diskutil list | grep $( echo ${targetDisk#/dev/} ) | sed -n '$=' ) -2 ))␊ |
␊ |
# Only check the disk for Chameleon installations if there is more than one partition.␊ |
␊ |
# ===============================================␊ |
# Checking the disk for existing Chameleon installations␊ |
# if there is more than one partition on the disk.␊ |
# ===============================================␊ |
if [ $numSlices -gt 1 ]; then ␊ |
␉␉␊ |
␉"$scriptDir"InstallLog.sh "${installerVolume}" "LineBreak"␊ |
␉"$scriptDir"InstallLog.sh "${installerVolume}" "Checking for previous chameleon installations on ${targetDisk#/dev/}"␊ |
␊ |
␉# Check the disk's MBR for existing stage 0 boot code (code from CheckDiskMicrocode.sh script)␊ |
␉stage0type=$( dd 2>/dev/null if="$targetDisk" count=3 bs=1 skip=105 | xxd | awk '{print $2$3}' )␊ |
␉if [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
␉␉stage0type=2␊ |
␉elif [ "${stage0type}" == "0b807c" ]; then␊ |
␉␉stage0type=1␊ |
␉fi␊ |
␉␊ |
␉#Scan all partitions for Chameleon code␊ |
␉for (( i=1; i <= $numSlices; i++ ));␊ |
␉do␊ |
␉␉stageExistence=0␊ |
␉␉stage0FirstBootable=0␊ |
␉␉previousExistence="NONE"␊ |
␉␉if [ $stage0type == 1 ] || [ $stage0type == 2 ]; then␊ |
␉␉␉stagesFound=1␊ |
␉␉else␊ |
␉␉␉stagesFound=0␊ |
␉␉fi␊ |
␉␉stage1Existence="NONE"␊ |
␉␉stage2Existence=0␊ |
␉␉targetDiskRaw=$targetDiskRawNoSlice$i␊ |
␊ |
␉␉# Check for existing stage 0 boot file (same code as CheckDiskMicrocode.sh script)␊ |
␉␉stage0type=$( dd 2>/dev/null if="$targetDisk" count=3 bs=1 skip=105 | xxd | awk '{print $2$3}' )␊ |
␉␉if [ "${stage0type}" == "0b807c" ] || [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
␉␉␉#echo "DEBUG: boot0 found on $targetDisk"␊ |
␉␉␉(( stageExistence++ ))␊ |
␉␉␉␊ |
␉␉␉# While here, check just for either existing boot0hfs, boot0md or boot0md (dmazar's boot0workV2)␊ |
␉␉␉if [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
␉␉␉␉stage0FirstBootable=1␊ |
␉␉␉fi␊ |
␉␉fi␊ |
␉␉␉␊ |
␉␉␉␉␉␊ |
␉␉# Check for existence of a bootable partition boot sector containing either boot1h or boot1f32␊ |
␉␉boot1Search=$( dd 2>/dev/null if="$targetDiskRaw" count=1 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
␉␉if [ "${boot1Search:0:16}" == "fa31c08ed0bcf0ff" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
␉␉␉#echo "DEBUG: boot1h found on "$targetDiskRaw␊ |
␉␉␉(( stageExistence++ ))␊ |
␉␉␉previousExistence="boot1"␊ |
␉␉␉(( stagesFound++ ))␊ |
␉␉␉stage1Existence="boot1h"␊ |
␉␉elif [ "${boot1Search:0:4}" == "e962" ] && [ "${boot1Search:180:12}" == "424f4f542020" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
␉␉␉#echo "DEBUG: boot1f32 found on "$targetDiskRaw␊ |
␉␉␉(( stageExistence++ ))␊ |
␉␉␉previousExistence="boot1f32"␊ |
␉␉␉(( stagesFound++ ))␊ |
␉␉␉stage1Existence="boot1f32"␊ |
␉␉fi␊ |
␉␉␊ |
␉␉# Check for existing stage 2 boot file also␊ |
␉␉# NOTE: This will fail to find /boot on /Volumes/EFI as it won't be mounted!␊ |
␉␉# Check for existing stage 2 boot file.␊ |
␉␉# Include checking the EFI system partition if it exists and is mounted.␊ |
␉␉if [ -e "$( df | grep ${targetDisk}s${i} | awk '{ print $6 }' )"/boot ]; then␊ |
␉␉␉#echo "DEBUG: boot found on $targetDiskRaw"␊ |
␉␉␉(( stageExistence++ ))␊ |
␉␉␉(( stagesFound++ ))␊ |
␉␉␉stage2Existence=1␊ |
␉␉fi␊ |
␉␉␊ |
␉␉#if [ $stageExistence == 3 ] && [ $i -ne $sliceNumber ]; then␊ |
␉␉␉#echo "DEBUG: STOP: There is already an existing Chameleon installation on $targetDiskRaw"␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "STOP: There is already an existing Chameleon installation on $targetDiskRaw."␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: This is allowed and does work as long as you aren't dual booting Windows"␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: from the same disk and are happy to control which partition is used by"␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: flagging the required partition active. General use doesn't require two"␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: Chameleon installs on the same disk, though might be done by advanced users."␊ |
␉␉␉#"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: If you still want to do this then proceed by installing Chameleon manually."␊ |
␉␉␉#exit 1␊ |
␉␉#fi␊ |
␉␉␉␊ |
␉␉if [ $stageExistence -ge 2 ] && [ "$previousExistence" != "NONE" ] && [ $i -ne $sliceNumber ]; then␊ |
␉␉␉␉␉␊ |
␉␉if [ $stagesFound -ge 2 ] && [ "$stage1Existence" != "NONE" ] && [ $i -ne $sliceNumber ]; then␊ |
␉␉␉# There is previous Chameleon stage 1 code on a partition boot sector,␊ |
␉␉␉# and either a complete or incomplete installation (ie. boot0 or boot are missing).␊ |
␉␉␉if [ $stageExistence == 3 ]; then␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "WARN: There is already an existing Chameleon installation on $targetDiskRaw."␊ |
␉␉␉else␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: $previousExistence already exists at ${targetDisk}s${i}"␊ |
␉␉␉␊ |
␉␉␉if [ $stagesFound == 3 ] && [ $i -lt $sliceNumber ]; then␊ |
␉␉␉␉# Exisitng installation found which will still be default.␊ |
␉␉␉␉message="************************** TAKE NOTE *****************************␊ |
**** There is an existing Chameleon installation on $targetDiskRaw␊ |
**** and that installation will still be the default loader as it's␊ |
**** on an earlier partition. If you want this new installation on␊ |
**** $installerVolume to be default then you will need to remove the␊ |
**** boot file from $targetDiskRaw and re-run this installer.␊ |
**************************************************************"␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
␉␉␉fi␊ |
␉␉␉if [ $stagesFound == 3 ] && [ $i -gt $sliceNumber ]; then␊ |
␉␉␉␉# Exisitng installation found which will no longer be default.␊ |
␉␉␉␉message="NOTE: There is an existing Chameleon installation on $targetDiskRaw␊ |
NOTE: but this installation on $targetDevice will be the default loader␊ |
NOTE: because you're installing to an earlier partition on the disk."␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
␉␉␉fi␊ |
␉␉␉␊ |
␉␉␉# This could prove problematic and result in either a b1f:error or boot0:error ␊ |
␉␉␉# if the following conditions are true:␊ |
␉␉␉␊ |
␉␉␉# User could see a b1f:error or boot0:error if the following conditions are true:␊ |
␉␉␉# A) Boot0hfs, Boot0md or Boot0md (dmazar's Boot0workV2) is being used.␊ |
␉␉␉# B) The previous stage 1 code is on a lower partiton than the one being installed to now.␊ |
␉␉␉# C) boot is missing from that partition.␊ |
␊ |
␉␉␉if [ $stagesFound == 2 ] && [ $stage2Existence == 0 ]; then␊ |
␉␉␉␉# Exisitng boot0 and boot1 only found - missing boot␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: Found $stage1Existence installed to ${targetDisk}s${i}"␊ |
␉␉␉␉␉␉␉␊ |
␉␉␉␉# stage0type=2 is used to know if 'A' is true.␊ |
␉␉␉␉if [ $stage0type == 2 ]; then␊ |
␉␉␉␉␉# i = current slice we're checking, slicenumber = slice trying to install to.␊ |
␉␉␉␉␉if [ $i -lt $sliceNumber ]; then␊ |
␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "WARN: Conditions point to the possibility of a boot failure"␊ |
␊ |
␉␉␉␉␉␉# Fix by making previous paritionboot sector un-bootable␊ |
␉␉␉␉␉␉# Change Byte 01FExh to 00 (510 decimal)␉␉␊ |
␉␉␉␉␉␉message="---␊ |
FIX: Make ${targetDisk}s${i} boot sector un-bootable by changing byte 1FEh to 00.␊ |
NOTE: Any Extra folder you had there will still be there. If you want to use␊ |
NOTE: ${targetDisk}s${i} again as your boot partition then re-run this installer␊ |
NOTE: selecting it as the target, ONLY choosing the 'Chameleon Bootloader' option␊ |
NOTE: and NONE of the other options.␊ |
---"␊ |
␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
␉␉␉␉␉␉␊ |
␉␉␉# stage0FirstBootable=1 is used to know if 'A' is true.␊ |
␉␉␉if [ $stage0FirstBootable == 1 ]; then␊ |
␉␉␉␉# i = current slice we're checking, slicenumber = slice trying to install to.␊ |
␉␉␉␉if [ $i -lt $sliceNumber ]; then␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "WARN: Conditions point to you receiving a boot failure"␊ |
␉␉␉␉␉# Fix by making previous paritionboot sector un-bootable␊ |
␉␉␉␉␉# Change Byte 01FExh to 00 (510 decimal)␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "---"␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "FIX: Make ${targetDisk}s${i} boot sector un-bootable by changing byte 1FEh to 00."␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: Any Extra folder you had there will still be there. If you want to use"␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: ${targetDisk}s${i} again as your boot partition then re-run this installer"␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: selecting it as the target, ONLY choosing the 'Chameleon Bootloader' option"␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: and NONE of the other options."␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "---"␊ |
␉␉␉␉␉dd if=${targetDisk}s${i} count=1 bs=512 of=/tmp/originalBootSector␊ |
␉␉␉␉␉cp /tmp/originalBootSector /tmp/newBootSector␊ |
␉␉␉␉␉dd if="$scriptDir/patch" of=/tmp/newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
␉␉␉␉␉dd if=/tmp/newBootSector of=${targetDisk}s${i} count=1 bs=512␊ |
␉␉␉␉else␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: but won't interfere as you're installing to an earlier partition."␊ |
␉␉␉␉␉␉# /Volumes/EFI needs unmounting before changing partition boot sector␊ |
␉␉␉␉␉␉if [ $i == 1 ]; then␊ |
␉␉␉␉␉␉␉umount /Volumes/EFI␊ |
␉␉␉␉␉␉else␊ |
␉␉␉␉␉␉␉diskutil unmount "${targetDisk}"s${i}␊ |
␉␉␉␉␉␉fi␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␊ |
␉␉␉␉␉␉if [ "$( fstyp "${targetDisk}"s${i} | grep hfs )" ]; then␊ |
␉␉␉␉␉␉␉#echo "DEBUG: HFS - changing byte 1FEh to 00"␊ |
␉␉␉␉␉␉␉dd if=${targetDisk}s${i} count=2 bs=512 of=originalBootSector␊ |
␉␉␉␉␉␉␉cp originalBootSector newBootSector␊ |
␉␉␉␉␉␉␉dd if="patch" of=newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
␉␉␉␉␉␉␉dd if=newBootSector of=${targetDisk}s${i} count=2 bs=510␊ |
␉␉␉␉␉␉fi␊ |
␉␉␉␉␉␉if [ "$( fstyp "${targetDisk}"s${i} | grep msdos )" ]; then␊ |
␉␉␉␉␉␉␉#echo "DEBUG: MSDOS - changing byte 1FEh to 00"␊ |
␉␉␉␉␉␉␉dd if=${targetDisk}s${i} count=1 bs=512 of=/tmp/originalBootSector␊ |
␉␉␉␉␉␉␉cp /tmp/originalBootSector /tmp/newBootSector␊ |
␉␉␉␉␉␉␉dd if="$scriptDir/patch" of=/tmp/newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
␉␉␉␉␉␉␉dd if=/tmp/newBootSector of=${targetDisk}s${i} count=1 bs=512␊ |
␉␉␉␉␉␉fi␊ |
␉␉␉␉␉␉␊ |
␉␉␉␉␉␉# /Volumes/EFI needs re-mounting so EFI/postinstall script can use it.␊ |
␉␉␉␉␉␉# Don't check for a GPT as wouldn't have got here if it wasn't␊ |
␉␉␉␉␉␉if [ $i == 1 ]; then␊ |
␉␉␉␉␉␉␉"$scriptDir"MountESP.sh "${targetDisk}" "${installerVolume}" "${scriptDir}"␊ |
␉␉␉␉␉␉else␊ |
␉␉␉␉␉␉␉diskutil mount "${targetDisk}"s${i}␊ |
␉␉␉␉␉␉fi␊ |
␉␉␉␉␉␉␊ |
␉␉␉␉␉else␊ |
␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: but won't interfere as you're installing to an earlier partition."␊ |
␉␉␉␉␉fi␊ |
␉␉␉␉elif [ $stage0type == 1 ]; then␊ |
␉␉␉␉␉# boot0 was found which looks for boot1 on the first active partition.␊ |
␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: so select to boot that partition (if used) with active flag."␊ |
␉␉␉␉#else␊ |
␉␉␉␉␉#echo "DEBUG: Boot0 not found"␊ |
␉␉␉␉fi␊ |
␉␉␉else␊ |
␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: so select to boot that partition (if used) with active flag."␊ |
␉␉␉fi␊ |
␉␉fi␊ |
␉␉␊ |
␉done␊ |
␊ |
#else␊ |
␉#echo "DEBUG: Just one slice"␊ |
fi␊ |
␊ |
exit 0 |
exit 0␊ |