1 | #!/bin/bash␊ |
2 | ␊ |
3 | echo "==============================================="␊ |
4 | echo "Check Previous Chameleon: Will there be problems?"␊ |
5 | echo "***********************************************"␊ |
6 | ␊ |
7 | # Checks for another existing Chameleon installation on the same disk␊ |
8 | # and tries to make sure the user doesn't end up with an un-bootable␊ |
9 | # system due to having installed Chameleon previously elsewhere.␊ |
10 | ␊ |
11 | # Receives targetDisk: for example, /dev/disk3.␊ |
12 | # Receives targetDeviceRaw: for example, /dev/rdisk3s1.␊ |
13 | # Receives targetDevice: Stores device number, for example /dev/disk2s1.␊ |
14 | # Receives installerVolume: Volume to write the installer log to.␊ |
15 | # Receives partitiontable: for example, GUID_partition_scheme␊ |
16 | # Receives scriptDir: The location of the main script dir.␊ |
17 | ␊ |
18 | if [ "$#" -eq 6 ]; then␊ |
19 | ␉targetDisk="$1"␊ |
20 | ␉targetDeviceRaw="$2"␊ |
21 | ␉targetDevice="$3"␊ |
22 | ␉installerVolume="$4"␊ |
23 | ␉partitiontable="$5"␊ |
24 | ␉scriptDir="$6"␊ |
25 | ␉echo "DEBUG: passed argument for targetDisk = $targetDisk"␊ |
26 | ␉echo "DEBUG: passed argument for targetDeviceRaw = $targetDeviceRaw"␊ |
27 | ␉echo "DEBUG: passed argument for targetDevice = $targetDevice"␊ |
28 | ␉echo "DEBUG: passed argument for installerVolume = $installerVolume"␊ |
29 | ␉echo "DEBUG: passed argument for partitiontable = $partitiontable"␊ |
30 | ␉echo "DEBUG: passed argument for scriptDir = $scriptDir"␊ |
31 | else␊ |
32 | ␉echo "Error - wrong number of values passed"␊ |
33 | ␉exit 9␊ |
34 | fi␊ |
35 | ␊ |
36 | ␊ |
37 | # Check for existing Chameleon installations on a different␊ |
38 | # partition of the same target disk.␊ |
39 | #echo "DEBUG: Checking for existing Chameleon installations on ${targetDisk#/dev/}..."␊ |
40 | ␊ |
41 | sliceNumber=$( echo ${targetDeviceRaw#*disk*s} )␊ |
42 | # strip slice from end␊ |
43 | targetDiskRawNoSlice=$( echo ${targetDeviceRaw%$sliceNumber} )␊ |
44 | ␊ |
45 | # Are there any other partitions on the disk?␊ |
46 | # How many actual partitions are there?␊ |
47 | numSlices=$(( $( diskutil list | grep $( echo ${targetDisk#/dev/} ) | sed -n '$=' ) -2 ))␊ |
48 | ␊ |
49 | # Only check the disk for Chameleon installations if there is more than one partition.␊ |
50 | if [ $numSlices -gt 1 ]; then ␊ |
51 | ␊ |
52 | ␉# If a GPT is used then we are going to have the check the EFI system partition␊ |
53 | ␉# for the stage 2 'boot' file. As this script is called from the Main EFI␊ |
54 | ␉# postinstall script, so lets mount the EFI system partition here instead.␊ |
55 | ␊ |
56 | ␉if [ "${partitiontable}" = "GUID_partition_scheme" ]; then␊ |
57 | ␊ |
58 | ␉␉# Unmount ALL mounted volumes named EFI␊ |
59 | ␉␉# the following script returns 0 if it succeeds␊ |
60 | ␉␉# the following script returns 1 if it fails to un-mount any EFI volume␊ |
61 | ␉␉"$scriptDir"UnMountEFIvolumes.sh "${installerVolume}" "${scriptDir}"␊ |
62 | ␉␉returnValue=$?␊ |
63 | ␉␉if [ ${returnValue} = 0 ]; then␊ |
64 | ␉␉␉# OK to proceed␊ |
65 | ␊ |
66 | ␉␉␉if [ ! -e "/Volumes/EFI" ]; then␊ |
67 | ␉␉␉␉#echo "DEBUG: Executing Command: mkdir -p ${/Volumes/EFI}"␊ |
68 | ␉␉␉␉mkdir -p "/Volumes/EFI"␊ |
69 | ␉␉␉#else␊ |
70 | ␉␉␉␉#echo "DEBUG: folder /Volumes/EFI already exists"␊ |
71 | ␉␉␉fi␊ |
72 | ␊ |
73 | ␉␉␉# Mount '/Volumes/EFI' using the correct format type␊ |
74 | ␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep hfs )" ]; then␊ |
75 | ␉␉␉␉#echo "Executing command: mount_hfs ${targetDevice} ${targetVolume}"␊ |
76 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "Mounting ${targetDisk}s1 as /Volumes/EFI"␊ |
77 | ␉␉␉␉mount_hfs "${targetDisk}"s1 "/Volumes/EFI"␊ |
78 | ␉␉␉fi␊ |
79 | ␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep msdos )" ]; then␊ |
80 | ␉␉␉␉#echo "Executing command: mount_msdos -u 0 -g 0 ${targetDevice} ${/Volumes/EFI}"␊ |
81 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "Mounting ${targetDisk}s1 as /Volumes/EFI"␊ |
82 | ␉␉␉␉mount_msdos -u 0 -g 0 "${targetDisk}"s1 "/Volumes/EFI"␊ |
83 | ␉␉␉fi␊ |
84 | ␉␉else␊ |
85 | ␉␉␉# quit out and notify EFI post script not to write Chameleon files.␊ |
86 | ␉␉␉exit 2␊ |
87 | ␉␉fi␊ |
88 | ␉fi␊ |
89 | ␊ |
90 | ␉#Scan all partitions for Chameleon code␊ |
91 | ␉for (( i=1; i <= $numSlices; i++ ));␊ |
92 | ␉do␊ |
93 | ␉␉stageExistence=0␊ |
94 | ␉␉stage0FirstBootable=0␊ |
95 | ␉␉previousExistence="NONE"␊ |
96 | ␉␉targetDiskRaw=$targetDiskRawNoSlice$i␊ |
97 | ␊ |
98 | ␉␉# Check for existing stage 0 boot file (same code as CheckDiskMicrocode.sh script)␊ |
99 | ␉␉stage0type=$( dd 2>/dev/null if="$targetDisk" count=3 bs=1 skip=105 | xxd | awk '{print $2$3}' )␊ |
100 | ␉␉if [ "${stage0type}" == "0b807c" ] || [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
101 | ␉␉␉#echo "DEBUG: stage 0 loader found on $targetDisk"␊ |
102 | ␉␉␉(( stageExistence++ ))␊ |
103 | ␉␉␉␊ |
104 | ␉␉␉# While here, check just for either existing boot0hfs, boot0md or boot0md (dmazar's boot0workV2)␊ |
105 | ␉␉␉if [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
106 | ␉␉␉␉stage0FirstBootable=1␊ |
107 | ␉␉␉fi␊ |
108 | ␉␉fi␊ |
109 | ␉␉␉␊ |
110 | ␉␉# Check for existence of a bootable partition boot sector containing either boot1h or boot1f32␊ |
111 | ␉␉boot1Search=$( dd 2>/dev/null if="$targetDiskRaw" count=1 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
112 | ␉␉if [ "${boot1Search:0:16}" == "fa31c08ed0bcf0ff" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
113 | ␉␉␉#echo "DEBUG: boot1h found on "$targetDiskRaw␊ |
114 | ␉␉␉(( stageExistence++ ))␊ |
115 | ␉␉␉previousExistence="boot1"␊ |
116 | ␉␉elif [ "${boot1Search:0:4}" == "e962" ] && [ "${boot1Search:180:12}" == "424f4f542020" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
117 | ␉␉␉#echo "DEBUG: boot1f32 found on "$targetDiskRaw␊ |
118 | ␉␉␉(( stageExistence++ ))␊ |
119 | ␉␉␉previousExistence="boot1f32"␊ |
120 | ␉␉fi␊ |
121 | ␉␉␊ |
122 | ␉␉# Check for existing stage 2 boot file.␊ |
123 | ␉␉# Include checking the EFI system partition if it exists and is mounted.␊ |
124 | ␉␉if [ -e "$( df | grep ${targetDisk}s${i} | awk '{ print $6 }' )"/boot ]; then␊ |
125 | ␉␉␉#echo "DEBUG: boot found on $targetDiskRaw"␊ |
126 | ␉␉␉(( stageExistence++ ))␊ |
127 | ␉␉fi␊ |
128 | ␉␉␉␉␉␊ |
129 | ␉␉if [ $stageExistence -ge 2 ] && [ "$previousExistence" != "NONE" ] && [ $i -ne $sliceNumber ]; then␊ |
130 | ␉␉␉# There is previous Chameleon stage 1 code on a partition boot sector,␊ |
131 | ␉␉␉# and either a complete or incomplete installation (ie. boot0 or boot are missing).␊ |
132 | ␉␉␉␊ |
133 | ␉␉␉if [ $stageExistence == 3 ]; then␊ |
134 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: There is already an existing Chameleon installation on $targetDiskRaw."␊ |
135 | ␉␉␉␉if [ $i -lt $sliceNumber ]; then␊ |
136 | ␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: And that installation will still be used as it's on an earlier partition."␊ |
137 | ␉␉␉␉else␊ |
138 | ␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: but won't interfere as you're installing to an earlier partition."␊ |
139 | ␉␉␉␉fi␊ |
140 | ␉␉␉else␊ |
141 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: $previousExistence already exists at ${targetDisk}s${i}"␊ |
142 | ␉␉␉␉␊ |
143 | ␉␉␉␉# A b1f:error or boot0:error could result if the following conditions are true:␊ |
144 | ␉␉␉␉# A) Boot0hfs, Boot0md or Boot0md (dmazar's Boot0workV2) is being used.␊ |
145 | ␉␉␉␉# B) The previous stage 1 code is on a lower partiton than the one being installed to now.␊ |
146 | ␉␉␉␉# C) boot is missing from that partition.␊ |
147 | ␉␉␉␉␉␉␊ |
148 | ␉␉␉␉# stage0FirstBootable=1 is used to know if 'A' is true.␊ |
149 | ␉␉␉␉if [ $stage0FirstBootable == 1 ]; then␊ |
150 | ␉␉␉␉␉# i = current slice we're checking, slicenumber = slice trying to install to.␊ |
151 | ␉␉␉␉␉if [ $i -lt $sliceNumber ]; then␊ |
152 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "WARN: Conditions point to the possibility of a boot failure"␊ |
153 | ␊ |
154 | ␉␉␉␉␉␉# Fix by making previous paritionboot sector un-bootable␊ |
155 | ␉␉␉␉␉␉# Change Byte 01FExh to 00 (510 decimal)␊ |
156 | ␉␉␉␉␉␉mesaageToPost="---␊ |
157 | FIX: Make ${targetDisk}s${i} boot sector un-bootable by changing byte 1FEh to 00.␊ |
158 | NOTE: Any Extra folder you had there will still be there. If you want to use␊ |
159 | NOTE: ${targetDisk}s${i} again as your boot partition then re-run this installer␊ |
160 | NOTE: selecting it as the target, ONLY choosing the 'Chameleon Bootloader' option␊ |
161 | NOTE: and NONE of the other options.␊ |
162 | ---"␊ |
163 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${mesaageToPost}"␊ |
164 | ␉␉␉␉␉␉dd if=${targetDisk}s${i} count=1 bs=512 of=/tmp/originalBootSector␊ |
165 | ␉␉␉␉␉␉cp /tmp/originalBootSector /tmp/newBootSector␊ |
166 | ␉␉␉␉␉␉dd if="$scriptDir/patch" of=/tmp/newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
167 | ␉␉␉␉␉␉dd if=/tmp/newBootSector of=${targetDisk}s${i} count=1 bs=512␊ |
168 | ␉␉␉␉␉else␊ |
169 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: but won't interfere as you're installing to an earlier partition."␊ |
170 | ␉␉␉␉␉fi␊ |
171 | ␉␉␉␉else␊ |
172 | ␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: so select to boot that partition (if used) with active flag."␊ |
173 | ␉␉␉␉fi␊ |
174 | ␉␉␉fi␊ |
175 | ␉␉fi␊ |
176 | ␉done␊ |
177 | #else␊ |
178 | ␉#echo "DEBUG: Just one slice"␊ |
179 | fi␊ |
180 | ␊ |
181 | exit 0 |