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 | # Functions␊ |
38 | # ===============================================␊ |
39 | mountESP()␊ |
40 | {␊ |
41 | ␉if [ "${partitiontable}" = "GUID_partition_scheme" ]; then␊ |
42 | ␊ |
43 | ␉␉# Unmount ALL mounted volumes named EFI␊ |
44 | ␉␉# the following script returns 0 if it succeeds␊ |
45 | ␉␉# the following script returns 1 if it fails to un-mount any EFI volume␊ |
46 | ␉␉"$scriptDir"UnMountEFIvolumes.sh "${installerVolume}" "${scriptDir}"␊ |
47 | ␉␉returnValue=$?␊ |
48 | ␉␉if [ ${returnValue} = 0 ]; then␊ |
49 | ␉␉␉# OK to proceed␊ |
50 | ␊ |
51 | ␉␉␉if [ ! -e "/Volumes/EFI" ]; then␊ |
52 | ␉␉␉␉#echo "DEBUG: Executing Command: mkdir -p ${/Volumes/EFI}"␊ |
53 | ␉␉␉␉mkdir -p "/Volumes/EFI"␊ |
54 | ␉␉␉#else␊ |
55 | ␉␉␉␉#echo "DEBUG: folder /Volumes/EFI already exists"␊ |
56 | ␉␉␉fi␊ |
57 | ␊ |
58 | ␉␉␉# Mount '/Volumes/EFI' using the correct format type␊ |
59 | ␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep hfs )" ]; then␊ |
60 | ␉␉␉␉#echo "Executing command: mount_hfs ${targetDevice} ${targetVolume}"␊ |
61 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "Mounting ${targetDisk}s1 as /Volumes/EFI"␊ |
62 | ␉␉␉␉mount_hfs "${targetDisk}"s1 "/Volumes/EFI"␊ |
63 | ␉␉␉fi␊ |
64 | ␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep msdos )" ]; then␊ |
65 | ␉␉␉␉#echo "Executing command: mount_msdos -u 0 -g 0 ${targetDevice} ${/Volumes/EFI}"␊ |
66 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "Mounting ${targetDisk}s1 as /Volumes/EFI"␊ |
67 | ␉␉␉␉mount_msdos -u 0 -g 0 "${targetDisk}"s1 "/Volumes/EFI"␊ |
68 | ␉␉␉fi␊ |
69 | ␉␉else␊ |
70 | ␉␉␉# quit out and notify EFI post script not to write Chameleon files.␊ |
71 | ␉␉␉exit 2␊ |
72 | ␉␉fi␊ |
73 | ␉fi␊ |
74 | }␊ |
75 | ␊ |
76 | ␊ |
77 | # ===============================================␊ |
78 | # Prepare some vars␊ |
79 | # ===============================================␊ |
80 | sliceNumber=$( echo ${targetDeviceRaw#*disk*s} )␊ |
81 | ␊ |
82 | # strip slice from end␊ |
83 | targetDiskRawNoSlice=$( echo ${targetDeviceRaw%$sliceNumber} )␊ |
84 | ␊ |
85 | # Are there any other partitions on the disk?␊ |
86 | # How many actual partitions are there?␊ |
87 | numSlices=$(( $( diskutil list | grep $( echo ${targetDisk#/dev/} ) | sed -n '$=' ) -2 ))␊ |
88 | ␊ |
89 | ␊ |
90 | # ===============================================␊ |
91 | # Checking the disk for existing Chameleon installations␊ |
92 | # if there is more than one partition on the disk.␊ |
93 | # ===============================================␊ |
94 | if [ $numSlices -gt 1 ]; then ␊ |
95 | ␊ |
96 | ␉#echo "DEBUG: Checking for existing Chameleon installations on ${targetDisk#/dev/}..."␊ |
97 | ␉"$scriptDir"InstallLog.sh "${installerVolume}" "LineBreak"␊ |
98 | ␉"$scriptDir"InstallLog.sh "${installerVolume}" "Checking for previous chameleon installations on ${targetDisk#/dev/}"␊ |
99 | ␊ |
100 | ␉# If a GPT is used then we are going to have the check the EFI system partition␊ |
101 | ␉# for the stage 2 'boot' file. As this script is called from the Main EFI␊ |
102 | ␉# postinstall script, so lets mount the EFI system partition here instead.␊ |
103 | ␊ |
104 | ␉mountESP␊ |
105 | ␉␊ |
106 | ␉#Scan all partitions for Chameleon code␊ |
107 | ␉for (( i=1; i <= $numSlices; i++ ));␊ |
108 | ␉do␊ |
109 | ␉␉stagesFound=0␊ |
110 | ␉␉stage0type=0␊ |
111 | ␉␉stage1Existence="NONE"␊ |
112 | ␉␉stage2Existence=0␊ |
113 | ␉␉targetDiskRaw=$targetDiskRawNoSlice$i␊ |
114 | ␉␉␊ |
115 | ␉␉# Check for existing stage 0 boot file (code from CheckDiskMicrocode.sh script)␊ |
116 | ␉␉stage0type=$( dd 2>/dev/null if="$targetDisk" count=3 bs=1 skip=105 | xxd | awk '{print $2$3}' )␊ |
117 | ␉␉if [ "${stage0type}" == "0a803c" ] || [ "${stage0type}" == "ee7505" ] || [ "${stage0type}" == "742b80" ]; then␊ |
118 | ␉␉␉#echo "DEBUG: stage 0 (hfs) loader found on $targetDisk"␊ |
119 | ␉␉␉(( stagesFound++ ))␊ |
120 | ␉␉␉stage0type=2␊ |
121 | ␉␉elif [ "${stage0type}" == "0b807c" ]; then␊ |
122 | ␉␉␉#echo "DEBUG: stage 0 (active) loader found on $targetDisk"␊ |
123 | ␉␉␉(( stagesFound++ ))␊ |
124 | ␉␉␉stage0type=1␊ |
125 | ␉␉fi␊ |
126 | ␉␉␉␊ |
127 | ␉␉# Check for existence of a bootable partition boot sector containing either boot1h or boot1f32␊ |
128 | ␉␉boot1Search=$( dd 2>/dev/null if="$targetDiskRaw" count=1 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
129 | ␉␉if [ "${boot1Search:0:16}" == "fa31c08ed0bcf0ff" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
130 | ␉␉␉#echo "DEBUG: boot1h found on "$targetDiskRaw␊ |
131 | ␉␉␉(( stagesFound++ ))␊ |
132 | ␉␉␉stage1Existence="boot1h"␊ |
133 | ␉␉elif [ "${boot1Search:0:4}" == "e962" ] && [ "${boot1Search:180:12}" == "424f4f542020" ] && [ "${boot1Search:1020:2}" == "55" ]; then␊ |
134 | ␉␉␉#echo "DEBUG: boot1f32 found on "$targetDiskRaw␊ |
135 | ␉␉␉(( stagesFound++ ))␊ |
136 | ␉␉␉stage1Existence="boot1f32"␊ |
137 | ␉␉fi␊ |
138 | ␉␉␊ |
139 | ␉␉# Check for existing stage 2 boot file.␊ |
140 | ␉␉# Include checking the EFI system partition if it exists and is mounted.␊ |
141 | ␉␉if [ -e "$( df | grep ${targetDisk}s${i} | awk '{ print $6 }' )"/boot ]; then␊ |
142 | ␉␉␉#echo "DEBUG: boot found on $targetDiskRaw"␊ |
143 | ␉␉␉(( stagesFound++ ))␊ |
144 | ␉␉␉stage2Existence=1␊ |
145 | ␉␉fi␊ |
146 | ␉␉␉␉␉␊ |
147 | ␉␉if [ $stagesFound -ge 2 ] && [ "$stage1Existence" != "NONE" ] && [ $i -ne $sliceNumber ]; then␊ |
148 | ␉␉␉# There is previous Chameleon stage 1 code on a partition boot sector,␊ |
149 | ␉␉␉# and either a complete or incomplete installation (ie. boot0 or boot are missing).␊ |
150 | ␉␉␉␊ |
151 | ␉␉␉if [ $stagesFound == 3 ] && [ $i -lt $sliceNumber ]; then␊ |
152 | ␉␉␉␉# Exisitng installation found which will still be default.␊ |
153 | ␉␉␉␉message="************************** TAKE NOTE *****************************␊ |
154 | **** There is an existing Chameleon installation on $targetDiskRaw␊ |
155 | **** and that installation will still be the default loader as it's␊ |
156 | **** on an earlier partition. If you want this new installation on␊ |
157 | **** $installerVolume to be default then you will need to remove the␊ |
158 | **** boot file from $targetDiskRaw and re-run this installer.␊ |
159 | **************************************************************"␊ |
160 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
161 | ␉␉␉fi␊ |
162 | ␉␉␉if [ $stagesFound == 3 ] && [ $i -gt $sliceNumber ]; then␊ |
163 | ␉␉␉␉# Exisitng installation found which will no longer be default.␊ |
164 | ␉␉␉␉message="NOTE: There is an existing Chameleon installation on $targetDiskRaw␊ |
165 | NOTE: but this installation on $targetDevice will be the default loader␊ |
166 | NOTE: because you're installing to an earlier partition on the disk."␊ |
167 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
168 | ␉␉␉fi␊ |
169 | ␉␉␉␊ |
170 | ␉␉␉# User could see a b1f:error or boot0:error if the following conditions are true:␊ |
171 | ␉␉␉# A) Boot0hfs, Boot0md or Boot0md (dmazar's Boot0workV2) is being used.␊ |
172 | ␉␉␉# B) The previous stage 1 code is on a lower partiton than the one being installed to now.␊ |
173 | ␉␉␉# C) boot is missing from that partition.␊ |
174 | ␊ |
175 | ␉␉␉if [ $stagesFound == 2 ] && [ $stage2Existence == 0 ]; then␊ |
176 | ␉␉␉␉# Exisitng boot0 and boot1 only found - missing boot␊ |
177 | ␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: Found $stage1Existence installed to ${targetDisk}s${i}"␊ |
178 | ␉␉␉␉␉␉␊ |
179 | ␉␉␉␉# stage0type=2 is used to know if 'A' is true.␊ |
180 | ␉␉␉␉if [ $stage0type == 2 ]; then␊ |
181 | ␉␉␉␉␉# i = current slice we're checking, slicenumber = slice trying to install to.␊ |
182 | ␉␉␉␉␉if [ $i -lt $sliceNumber ]; then␊ |
183 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "WARN: Conditions point to the possibility of a boot failure"␊ |
184 | ␊ |
185 | ␉␉␉␉␉␉# Fix by making previous paritionboot sector un-bootable␊ |
186 | ␉␉␉␉␉␉# Change Byte 01FExh to 00 (510 decimal)␉␉␊ |
187 | ␉␉␉␉␉␉message="---␊ |
188 | FIX: Make ${targetDisk}s${i} boot sector un-bootable by changing byte 1FEh to 00.␊ |
189 | NOTE: Any Extra folder you had there will still be there. If you want to use␊ |
190 | NOTE: ${targetDisk}s${i} again as your boot partition then re-run this installer␊ |
191 | NOTE: selecting it as the target, ONLY choosing the 'Chameleon Bootloader' option␊ |
192 | NOTE: and NONE of the other options.␊ |
193 | ---"␊ |
194 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "${message}"␊ |
195 | ␉␉␉␉␉␉␊ |
196 | ␉␉␉␉␉␉if [ $i == 1 ]; then␊ |
197 | ␉␉␉␉␉␉␉umount /Volumes/EFI␊ |
198 | ␉␉␉␉␉␉fi␊ |
199 | ␉␉␉␉␉␉␉␉␉␉␉␉␊ |
200 | ␉␉␉␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep hfs )" ]; then␊ |
201 | ␉␉␉␉␉␉␉#echo "DEBUG: HFS - changing byte 1FEh to 00"␊ |
202 | ␉␉␉␉␉␉␉dd if=${targetDisk}s${i} count=2 bs=512 of=originalBootSector␊ |
203 | ␉␉␉␉␉␉␉cp originalBootSector newBootSector␊ |
204 | ␉␉␉␉␉␉␉dd if="patch" of=newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
205 | ␉␉␉␉␉␉␉dd if=newBootSector of=${targetDisk}s${i} count=2 bs=510␊ |
206 | ␉␉␉␉␉␉fi␊ |
207 | ␉␉␉␉␉␉if [ "$( fstyp "${targetDisk}"s1 | grep msdos )" ]; then␊ |
208 | ␉␉␉␉␉␉␉#echo "DEBUG: MSDOS - changing byte 1FEh to 00"␊ |
209 | ␉␉␉␉␉␉␉dd if=${targetDisk}s${i} count=1 bs=512 of=/tmp/originalBootSector␊ |
210 | ␉␉␉␉␉␉␉cp /tmp/originalBootSector /tmp/newBootSector␊ |
211 | ␉␉␉␉␉␉␉dd if="$scriptDir/patch" of=/tmp/newBootSector bs=1 count=1 seek=510 conv=notrunc␊ |
212 | ␉␉␉␉␉␉␉dd if=/tmp/newBootSector of=${targetDisk}s${i} count=1 bs=512␊ |
213 | ␉␉␉␉␉␉fi␊ |
214 | ␉␉␉␉␉␉␊ |
215 | ␉␉␉␉␉␉mountESP␊ |
216 | ␉␉␉␉␉␉␊ |
217 | ␉␉␉␉␉else␊ |
218 | ␉␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "INFO: but won't interfere as you're installing to an earlier partition."␊ |
219 | ␉␉␉␉␉fi␊ |
220 | ␉␉␉␉elif [ $stage0type == 1 ]; then␊ |
221 | ␉␉␉␉␉# boot0 was found which looks for boot1 on the first active partition.␊ |
222 | ␉␉␉␉␉"$scriptDir"InstallLog.sh "${installerVolume}" "NOTE: so select to boot that partition (if used) with active flag."␊ |
223 | ␉␉␉␉#else␊ |
224 | ␉␉␉␉␉#echo "DEBUG: Boot0 not found"␊ |
225 | ␉␉␉␉fi␊ |
226 | ␉␉␉fi␊ |
227 | ␉␉fi␊ |
228 | ␉␉␊ |
229 | ␉done␊ |
230 | #else␊ |
231 | ␉#echo "DEBUG: Just one slice"␊ |
232 | fi␊ |
233 | ␊ |
234 | exit 0 |