Root/
| |
---|---|
Source at commit 1085 created 13 years 1 month ago. By azimutz, Runaway "min"; fixes build. | |
1 | #!/bin/bash␊ |
2 | ␊ |
3 | diskloader="/usr/standalone/i386/boot0"␊ |
4 | partitionloader="/usr/standalone/i386/boot1f32"␊ |
5 | filesystemloader="/usr/standalone/i386/boot"␊ |
6 | bootervolumename="EFI"␊ |
7 | booterextensions="Extra/Extensions"␊ |
8 | ␊ |
9 | bootresources="${0%/*}"␊ |
10 | ␊ |
11 | diskmicrocodetype[1]="GRUB,47525542"␊ |
12 | diskmicrocodetype[2]="LILO,4c494c4f"␊ |
13 | ␊ |
14 | start ()␊ |
15 | {␊ |
16 | # $1 volume␊ |
17 | ␊ |
18 | osxvolume="${@}"␊ |
19 | ␊ |
20 | if [ -z "${osxvolume}" ]; then␊ |
21 | ␉echo␊ |
22 | ␉echo "Cannot find the volume. Exiting."␊ |
23 | ␉exit␊ |
24 | fi␊ |
25 | ␊ |
26 | bootdev=$( df "${osxvolume}" | sed -n '2p' | awk '{print $1}' )␊ |
27 | ␊ |
28 | if [ "${bootdev}" = "${bootdev#*disk*s}" ]; then␊ |
29 | ␉echo␊ |
30 | ␉echo "ERROR Volume does not use slices."␊ |
31 | ␉echo "Volume may be stored on a RAID array."␊ |
32 | ␉echo␊ |
33 | ␉exit␊ |
34 | fi␊ |
35 | ␊ |
36 | bootuuid=$( diskutil info "$bootdev" | grep Volume\ UUID | awk {'print $3'} )␊ |
37 | partitiontable=$( diskutil list ${bootdev%s*} | sed -n '3p' | awk '{print $2}' )␊ |
38 | ␊ |
39 | if [ ${partitiontable} != "GUID_partition_scheme" ]; then␊ |
40 | ␉echo␊ |
41 | ␉echo "ERROR Volume is not on a GPT partitioned disc."␊ |
42 | ␉echo␊ |
43 | ␉exit␊ |
44 | fi␊ |
45 | ␊ |
46 | echo "GPT found."␊ |
47 | ␊ |
48 | echo "OS X Volume is ${osxvolume}"␊ |
49 | echo "OX X Volume device is ${bootdev}"␊ |
50 | echo "OS X Volume UUID is ${bootuuid}"␊ |
51 | ␊ |
52 | ␊ |
53 | bootvolume="/Volumes/$bootervolumename"␊ |
54 | bootdev=${bootdev%s*}s1␊ |
55 | bootrdev=${bootdev/disk/rdisk}␊ |
56 | bootdisk=${bootdev%s*}␊ |
57 | bootrdisk=${bootdisk/disk/rdisk}␊ |
58 | bootslice=${bootdev#*disk*s}␊ |
59 | ␊ |
60 | echo "EFI Volume device is ${bootdev}"␊ |
61 | echo "EFI Volume raw device is ${bootrdev}"␊ |
62 | echo "EFI Volume slice is ${bootslice}"␊ |
63 | echo "Disk device is ${bootdisk}"␊ |
64 | echo "Disk raw device is ${bootrdisk}"␊ |
65 | echo "Disk loader is ${diskloader}"␊ |
66 | echo "Partition loader is ${partitionloader}"␊ |
67 | echo "Filesystem loader is ${filesystemloader}"␊ |
68 | ␊ |
69 | }␊ |
70 | ␊ |
71 | checkdiskmicrocodetype ()␊ |
72 | {␊ |
73 | diskmicrocode=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
74 | ␊ |
75 | diskmicrocodetypecounter=0␊ |
76 | while [ ${diskmicrocodetypecounter} -lt ${#diskmicrocodetype[@]} ]; do␊ |
77 | diskmicrocodetypecounter=$(( ${diskmicrocodetypecounter} + 1 ))␊ |
78 | diskmicrocodetypeid=${diskmicrocodetype[${diskmicrocodetypecounter}]#*,}␊ |
79 | if [ ! "${diskmicrocode}" = "${diskmicrocode/${diskmicrocodetypeid}/}" ]; then␊ |
80 | echo "${diskmicrocodetype[${diskmicrocodetypecounter}]%,*} found."␊ |
81 | fi␊ |
82 | done␊ |
83 | }␊ |
84 | ␊ |
85 | checkdiskmicrocode ()␊ |
86 | {␊ |
87 | # 1 action ( check or set )␊ |
88 | ␊ |
89 | diskmicrocode=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
90 | diskmicrocodemd5=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | md5 )␊ |
91 | ␊ |
92 | if [ $( echo "${diskmicrocode}" | awk -F0 '{print NF-1}' ) = 874 ]; then␊ |
93 | ␉if [ "${1}" = "set" ]; then␊ |
94 | ␉␉echo "No disk microcode found. Updating."␊ |
95 | ␉␉diskupdate=true␊ |
96 | ␉else␊ |
97 | ␉␉echo "No disk microcode found."␊ |
98 | ␉fi␊ |
99 | else␊ |
100 | ␉if [ ${1} = set ]; then␊ |
101 | ␉␉echo "Disk microcode found. Preserving."␊ |
102 | ␉else␊ |
103 | ␉␉echo "Disk microcode found."␊ |
104 | ␉fi␊ |
105 | ␉echo "Disk microcode MD5 is ${diskmicrocodemd5}"␊ |
106 | fi␊ |
107 | }␊ |
108 | ␊ |
109 | checkdisksignature ()␊ |
110 | {␊ |
111 | disksignature=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=4 bs=1 skip=440 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
112 | ␊ |
113 | if [ $( echo "${disksignature}" | awk -F0 '{print NF-1}' ) = 8 ]; then␊ |
114 | ␉echo "No disk signature found."␊ |
115 | else␊ |
116 | ␉echo "Disk signature found."␊ |
117 | ␉echo "Disk signature is 0x${disksignature}"␊ |
118 | fi␊ |
119 | }␊ |
120 | ␊ |
121 | checkpartitionbootcode ()␊ |
122 | {␊ |
123 | # 1 action ( check or set )␊ |
124 | ␊ |
125 | partitionbootcode=$( dd if=${bootrdev} count=1 2>/dev/null | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
126 | partitionbootcodeextended=$( dd if=${bootrdev} count=1 skip=1 2>/dev/null | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
127 | ␊ |
128 | if [ $( echo "${partitionbootcode}" | awk -F0 '{print NF-1}' ) = 1024 ]; then␊ |
129 | ␉if [ "${1}" = "set" ]; then␊ |
130 | ␉␉echo "No partition bootcode found. Updating."␊ |
131 | ␉else␊ |
132 | ␉␉echo "No partition bootcode found."␊ |
133 | ␉fi␊ |
134 | else␊ |
135 | ␉if [ "${1}" = "set" ]; then␊ |
136 | ␉␉echo "Partition bootcode found. Overwriting."␊ |
137 | ␉else␊ |
138 | ␉␉echo "Partition bootcode found."␊ |
139 | ␉fi␊ |
140 | ␉if [ $( echo "${partitionbootcodeextended}" | awk -F0 '{print NF-1}' ) = 1024 ]; then␊ |
141 | ␉␉partitionbootcodemd5=$( dd 2>/dev/null if=${bootrdev} count=1 | md5 )␊ |
142 | ␉else␊ |
143 | ␉␉partitionbootcodemd5=$( dd 2>/dev/null if=${bootrdev} count=2 | md5 )␊ |
144 | ␉␉echo "Partition bootcode is dual sector."␊ |
145 | ␉fi␊ |
146 | ␉echo "Partition bootcode MD5 is ${partitionbootcodemd5}"␊ |
147 | fi␊ |
148 | }␊ |
149 | ␊ |
150 | checkpartitionactive ()␊ |
151 | {␊ |
152 | partitionactive=$( fdisk -d ${bootrdisk} | grep -n "*" | awk -F: '{print $1}')␊ |
153 | ␊ |
154 | if [ -n "${partitionactive}" ]; then ␊ |
155 | ␉echo "Partition flagged active is ${partitionactive}"␊ |
156 | else␊ |
157 | ␉echo "No partition flagged active."␊ |
158 | fi␊ |
159 | ␊ |
160 | }␊ |
161 | ␊ |
162 | start ${3}␊ |
163 | ␊ |
164 | if [ "$( df | grep ${bootdev} )" ]; then␊ |
165 | umount -f ${bootdev}␊ |
166 | fi ␊ |
167 | ␊ |
168 | #if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then␊ |
169 | #␉echo "${bootdev} isn't a FAT32 partition"␊ |
170 | #␉newfs_msdos -v "${bootervolumename}" "${bootdev}"␊ |
171 | #fi ␊ |
172 | ␊ |
173 | if ! [ "$( fstyp ${bootdev} | grep msdos )" ]; then␊ |
174 | ␉echo "${bootdev} isn't a FAT32 partition"␊ |
175 | ␉echo "Executing command: newfs_msdos -F 32 ${bootdev}"␊ |
176 | ␉newfs_msdos -F 32 "${bootdev}"␊ |
177 | else␊ |
178 | ␉echo "${bootdev} is already a FAT32 partition (skipping)"␊ |
179 | fi ␊ |
180 | ␊ |
181 | diskupdate=false␊ |
182 | checkdiskmicrocodetype␊ |
183 | checkdiskmicrocode set␊ |
184 | checkdisksignature␊ |
185 | checkpartitionbootcode set␊ |
186 | checkpartitionactive␊ |
187 | ␊ |
188 | if ${diskupdate}; then␊ |
189 | ␉echo "Executing command: fdisk -u -f ${diskloader} -y ${bootdisk}"␊ |
190 | ␉fdisk -u -f "${osxvolume}/${diskloader}" -y ${bootdisk}␊ |
191 | fi␊ |
192 | ␊ |
193 | #echo "Executing command: dd if=${partitionloader} of=${bootrdev}"␊ |
194 | #dd if="${osxvolume}/${partitionloader}" of=${bootrdev}␊ |
195 | ␊ |
196 | echo "Stage 1"␊ |
197 | ␊ |
198 | echo "Executing command: dd if=${bootrdev} count=1 bs=512 of=/tmp/origbs"␊ |
199 | dd if=${bootrdev} count=1 bs=512 of=/tmp/origbs␊ |
200 | ␊ |
201 | echo "Executing command: cp ${osxvolume}/${partitionloader} /tmp/newbs"␊ |
202 | cp "${osxvolume}/${partitionloader}" /tmp/newbs␊ |
203 | ␊ |
204 | echo "Executing command: dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc"␊ |
205 | dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc␊ |
206 | ␊ |
207 | echo "Executing command: dd of=${bootrdev} count=1 bs=512 if=/tmp/newbs"␊ |
208 | dd if=/tmp/newbs of=${bootrdev} count=1 bs=512␊ |
209 | ␊ |
210 | # If table is MBR make the correct slice active. If table is GPT make the first partition active (BadAxe compatibility).␊ |
211 | [ "${partitiontable}" = "GUID_partition_scheme" ] && bootslice=1␊ |
212 | if [[ "${partitiontable}" = "FDisk_partition_scheme" || "${partitiontable}" = "GUID_partition_scheme" ]]; then␊ |
213 | ␉fdisk -e ${bootdisk} <<-MAKEACTIVE␊ |
214 | ␉print␊ |
215 | ␉flag ${bootslice}␊ |
216 | ␉write␊ |
217 | ␉y␊ |
218 | ␉quit␊ |
219 | ␉MAKEACTIVE␊ |
220 | fi␊ |
221 | ␊ |
222 | checkdiskmicrocode check␊ |
223 | checkdisksignature␊ |
224 | checkpartitionbootcode check␊ |
225 | checkpartitionactive␊ |
226 | ␊ |
227 | [ -d "${bootvolume}" ] || mkdir -p "${bootvolume}"␊ |
228 | echo "Executing command: mount_hfs ${bootdev} ${bootvolume}"␊ |
229 | mount_msdos -u 0 -g 0 "${bootdev}" "${bootvolume}"␊ |
230 | ␊ |
231 | echo "Executing command: cp ${osxvolume}${filesystemloader} ${bootvolume}/boot"␊ |
232 | cp "${osxvolume}${filesystemloader}" "${bootvolume}/boot"␊ |
233 | ␊ |
234 | if ! [ -d "${bootvolume}/Extra/Extensions" ]; then␊ |
235 | ␉echo "Executing command: mkdir -p ${bootvolume}/Extra/Extensions"␊ |
236 | ␉mkdir -p "${bootvolume}/Extra/Extensions"␊ |
237 | fi␊ |
238 | # unpack any existing Extensions.mkext already on the booter volume␊ |
239 | if [ -e "${bootvolume}/Extra/Extensions.mkext" ]; then␊ |
240 | ␉echo "Executing command: mkextunpack -d ${bootvolume}/Extra/Extensions ${bootvolume}/Extra/Extensions.mkext"␊ |
241 | ␉mkextunpack -d "${bootvolume}/Extra/Extensions" "${bootvolume}/Extra/Extensions.mkext"␊ |
242 | ␉echo "Executing command: rm -R -f ${bootvolume}/Extra/Extensions.mkext"␊ |
243 | ␉rm -R -f "${bootvolume}/Extra/Extensions.mkext"␊ |
244 | fi␉␊ |
245 | ␊ |
246 | # copy existing /Extra␊ |
247 | if [ -d "${2}/Extra" ]; then␊ |
248 | ␉[ -d "${bootvolume}/Extra/Extensions" ] || mkdir -p "${bootvolume}/Extra/Extensions"␊ |
249 | ␉echo "Executing command: find ${2}/Extra -name '*.plist' -depth 1 -exec cp -f {} ${bootvolume}/Extra \;"␊ |
250 | ␉find "${2}/Extra" -name '*.plist' -depth 1 -exec cp -f {} "${bootvolume}/Extra/" \;␊ |
251 | ␉if [ -f "${2}/Extra/Extensions.mkext" ]; then␊ |
252 | ␉␉echo "Executing command: mkextunpack -d ${2}/Extra/Extensions ${2}/Extra/Extensions.mkext"␊ |
253 | ␉␉mkextunpack -d "${bootvolume}/Extra/Extensions" "${2}/Extra/Extensions.mkext"␊ |
254 | ␉fi␊ |
255 | ␉if [ -d "${2}/Extra/Extensions" ]; then␊ |
256 | ␉␉echo "Executing command: find ${2}/Extra/Extensions -name '*.kext' -depth 1 -exec cp -R {} ${bootvolume}/Extra/Extensions \;"␊ |
257 | ␉␉find "${2}/Extra/Extensions" -name '*.kext' -depth 1 -exec cp -R {} "${bootvolume}/Extra/Extensions" \;␊ |
258 | ␉fi␊ |
259 | fi␊ |
260 | ␊ |
261 | # setup link for extras␊ |
262 | echo "Executing command: ln -s /Volumes/${bootervolumename} ${2}/.Chameleon"␊ |
263 | ln -s "/Volumes/${bootervolumename}" "${2}/.Chameleon"␊ |
264 | ␊ |
265 | exit␊ |
266 |