]> code.delx.au - refind/blob - install.sh
install.sh & related: Improved Secure Boot detection & removed error
[refind] / install.sh
1 #!/bin/bash
2 #
3 # Linux/MacOS X script to install rEFInd
4 #
5 # Usage:
6 #
7 # ./install.sh [options]
8 #
9 # options include:
10 # "--notesp" to install to the OS X root filesystem rather than to the ESP.
11 # This option may not be used under Linux.
12 # "--usedefault {devicefile}" to install as default
13 # (/EFI/BOOT/BOOTX64.EFI and similar) to the specified device
14 # (/dev/sdd1 or whatever) without registering with the NVRAM.
15 # "--ownhfs {devicefile}" to install to an HFS+ volume that's NOT currently
16 # an OS X boot volume.
17 # "--root {dir}" to specify installation using the specified directory
18 # as the system's root
19 # "--alldrivers" to install all drivers along with regular files
20 # "--nodrivers" to suppress driver installation (default in Linux is
21 # driver used on /boot; --nodrivers is OS X default)
22 # "--shim {shimfile}" to install a shim.efi file for Secure Boot
23 # "--preloader" is synonymous with "--shim"
24 # "--localkeys" to re-sign x86-64 binaries with a locally-generated key
25 # "--yes" to assume a "yes" response to all prompts
26 #
27 # The "esp" option is valid only on Mac OS X; it causes
28 # installation to the EFI System Partition (ESP) rather than
29 # to the current OS X boot partition. Under Linux, this script
30 # installs to the ESP by default.
31 #
32 # This program is copyright (c) 2012-2015 by Roderick W. Smith
33 # It is released under the terms of the GNU GPL, version 3,
34 # a copy of which should be included in the file COPYING.txt.
35 #
36 # Revision history:
37 #
38 # 0.8.7 -- Better detection of Secure Boot mode & fixed errors when copying
39 # Shim & MokManager files over themselves.
40 # 0.8.6 -- Fixed bugs that caused misidentification of ESP on disks with
41 # partition numbers over 10 on OS X and misidentification of mount
42 # point if already-mounted ESP had space in path.
43 # 0.8.5 -- Refinement/cleanup of new OS X ESP-as-default policy
44 # 0.8.4 -- OS X default changed to install to ESP under /EFI/BOOT
45 # 0.7.9 -- Fixed bug that caused errors if dmraid utility not installed
46 # 0.7.7 -- Fixed bug that created mangled refind_linux.conf file; added ability
47 # to locate and mount ESP on Linux, if it's not mounted
48 # 0.7.6 -- Added --ownhfs {device-filename} option
49 # 0.7.5 -- Fixed bug when installing to ESP on recent versions of OS X
50 # 0.7.2 -- Fixed code that could be confused by use of autofs to mount the ESP
51 # 0.7.0 -- Added support for the new Btrfs driver
52 # 0.6.12 -- Added support for PreLoader as well as for shim
53 # 0.6.11 -- Improvements in script's ability to handle directories with spaces
54 # in their names
55 # 0.6.9 -- Install gptsync on Macs
56 # 0.6.8 -- Bug fix: ESP scan now uses "uniq".
57 # 0.6.6 -- Bug fix: Upgrade drivers when installed to EFI/BOOT. Also enable
58 # copying shim.efi and MokManager.efi over themselves.
59 # 0.6.4 -- Copies ext2 driver rather than ext4 driver for ext2/3fs
60 # 0.6.3 -- Support for detecting rEFInd in EFI/BOOT and EFI/Microsoft/Boot
61 # directories & for installing to EFI/BOOT in BIOS mode
62 # 0.6.2-1 -- Added --yes option & tweaked key-copying for use with RPM install script
63 # 0.6.1 -- Added --root option; minor bug fixes
64 # 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option;
65 # changed default driver installation behavior in Linux to install
66 # the driver needed to read /boot (if available)
67 # 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
68 # 0.5.1.1 -- Fixed bug that caused script failure under OS X
69 # 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
70 # in /boot
71 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
72 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
73 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
74 # 0.4.1 -- Added check for rEFItBlesser in OS X
75 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
76 # 0.3.2.1 -- Check for presence of source files; aborts if not present
77 # 0.3.2 -- Initial version
78 #
79 # Note: install.sh version numbers match those of the rEFInd package
80 # with which they first appeared.
81
82 RootDir="/"
83 TargetDir=/EFI/refind
84 LocalKeysBase="refind_local"
85 ShimSource="none"
86 ShimType="none"
87 TargetShim="default"
88 TargetX64="refind_x64.efi"
89 TargetIA32="refind_ia32.efi"
90 LocalKeys=0
91 DeleteRefindDir=0
92 AlwaysYes=0
93
94 #
95 # Functions used by both OS X and Linux....
96 #
97
98 GetParams() {
99 InstallToEspOnMac=1
100 # Install the driver required to read Linux /boot, if it's available
101 # Note: Under OS X, this will be installed only if a Linux partition
102 # is detected, in which case the ext4fs driver will be installed.
103 InstallDrivers="boot"
104 while [[ $# -gt 0 ]]; do
105 case $1 in
106 --notesp) InstallToEspOnMac=0
107 ;;
108 --ownhfs) OwnHfs=1
109 InstallToEspOnMac=0
110 TargetPart="$2"
111 TargetDir=/System/Library/CoreServices
112 shift
113 ;;
114 --usedefault) TargetDir=/EFI/BOOT
115 TargetPart="$2"
116 TargetX64="bootx64.efi"
117 TargetIA32="bootia32.efi"
118 shift
119 ;;
120 --root) RootDir="$2"
121 InstallToEspOnMac=0
122 shift
123 ;;
124 --localkeys) LocalKeys=1
125 ;;
126 --shim | --preloader) ShimSource="$2"
127 ShimType=`basename $ShimSource`
128 shift
129 ;;
130 --drivers | --alldrivers) InstallDrivers="all"
131 ;;
132 --nodrivers) InstallDrivers="none"
133 ;;
134 --yes) AlwaysYes=1
135 ;;
136 * ) echo "Usage: $0 [--notesp | --usedefault {device-file} | --root {dir} |"
137 echo " --ownhfs {device-file} ]"
138 echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]"
139 echo " [--localkeys] [--yes]"
140 exit 1
141 esac
142 shift
143 done
144 if [[ "$InstallToEspOnMac" == 0 && "$RootDir" == '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then
145 echo "You may use --notesp OR --usedefault, but not both! Aborting!"
146 exit 1
147 fi
148 if [[ "$RootDir" != '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then
149 echo "You may use --root OR --usedefault, but not both! Aborting!"
150 exit 1
151 fi
152 if [[ "$TargetDir" != '/System/Library/CoreServices' && "$OwnHfs" == '1' ]] ; then
153 echo "If you use --ownhfs, you may NOT use --usedefault! Aborting!"
154 exit 1
155 fi
156 RLConfFile="$RootDir/boot/refind_linux.conf"
157 EtcKeysDir="$RootDir/etc/refind.d/keys"
158 } # GetParams()
159
160 # Get a yes/no response from the user and place it in the YesNo variable.
161 # If the AlwaysYes variable is set to 1, skip the user input and set "Y"
162 # in the YesNo variable.
163 ReadYesNo() {
164 if [[ $AlwaysYes == 1 ]] ; then
165 YesNo="Y"
166 echo "Y"
167 else
168 read YesNo
169 fi
170 }
171
172 # Abort if the rEFInd files can't be found.
173 # Also sets $ConfFile to point to the configuration file,
174 # $IconsDir to point to the icons directory, and
175 # $ShimSource to the source of the shim.efi file (if necessary).
176 CheckForFiles() {
177 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
178 # is found, even on the wrong platform. This is because the platform
179 # hasn't yet been determined. This could obviously be improved, but it
180 # would mean restructuring lots more code....
181 if [[ ! -f "$RefindDir/refind_ia32.efi" && ! -f "$RefindDir/refind_x64.efi" ]] ; then
182 echo "The rEFInd binary file is missing! Aborting installation!"
183 exit 1
184 fi
185
186 if [[ -f "$RefindDir/refind.conf-sample" ]] ; then
187 ConfFile="$RefindDir/refind.conf-sample"
188 elif [[ -f "$ThisDir/refind.conf-sample" ]] ; then
189 ConfFile="$ThisDir/refind.conf-sample"
190 else
191 echo "The sample configuration file is missing! Aborting installation!"
192 exit 1
193 fi
194
195 if [[ -d "$RefindDir/icons" ]] ; then
196 IconsDir="$RefindDir/icons"
197 elif [[ -d "$ThisDir/icons" ]] ; then
198 IconsDir="$ThisDir/icons"
199 else
200 echo "The icons directory is missing! Aborting installation!"
201 exit 1
202 fi
203
204 if [[ "$ShimSource" != "none" ]] ; then
205 if [[ -f "$ShimSource" ]] ; then
206 if [[ $ShimType == "shimx64.efi" || $ShimType == "shim.efi" ]] ; then
207 TargetX64="grubx64.efi"
208 MokManagerSource=`dirname "$ShimSource"`/MokManager.efi
209 elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then
210 TargetX64="loader.efi"
211 MokManagerSource=`dirname "$ShimSource"`/HashTool.efi
212 else
213 echo "Unknown shim/PreBootloader filename: $ShimType!"
214 echo "Known filenames are shimx64.efi, shim.efi, and PreLoader.efi. Aborting!"
215 exit 1
216 fi
217 else
218 echo "The specified shim/PreBootloader file, $ShimSource, doesn't exist!"
219 echo "Aborting installation!"
220 exit 1
221 fi
222 fi
223 } # CheckForFiles()
224
225 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
226 # available) to target.
227 CopyShimFiles() {
228 local inode1=`ls -i "$ShimSource" | cut -f 1 -d " "`
229 local inode2=`ls -i "$InstallDir/$TargetDir/$TargetShim" | cut -f 1 -d " "`
230 if [[ $inode1 != $inode2 ]] ; then
231 cp -fb "$ShimSource" "$InstallDir/$TargetDir/$TargetShim"
232 if [[ $? != 0 ]] ; then
233 Problems=1
234 fi
235 fi
236 inode1 = `ls -i "$MokManagerSource" | cut -f 1 -d " "`
237 local TargetMMName=`basename $MokManagerSource`
238 inode2 = `ls -i "$InstallDir/$TargetDir/$TargetShim/$TargetMMName" | cut -f 1 -d " "`
239 if [[ $inode1 != $inode2 ]] ; then
240 if [[ -f "$MokManagerSource" ]] ; then
241 cp -fb "$MokManagerSource" "$InstallDir/$TargetDir/"
242 fi
243 if [[ $? != 0 ]] ; then
244 Problems=1
245 fi
246 fi
247 } # CopyShimFiles()
248
249 # Copy the public keys to the installation medium
250 CopyKeys() {
251 if [[ $LocalKeys == 1 ]] ; then
252 mkdir -p "$InstallDir/$TargetDir/keys/"
253 cp "$EtcKeysDir/$LocalKeysBase.cer" "$InstallDir/$TargetDir/keys/"
254 cp "$EtcKeysDir/$LocalKeysBase.crt" "$InstallDir/$TargetDir/keys/"
255 fi
256 } # CopyKeys()
257
258 # Set varaibles for installation in EFI/BOOT directory
259 SetVarsForBoot() {
260 TargetDir="/EFI/BOOT"
261 if [[ $ShimSource == "none" ]] ; then
262 TargetX64="bootx64.efi"
263 TargetIA32="bootia32.efi"
264 else
265 if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then
266 TargetX64="grubx64.efi"
267 elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then
268 TargetX64="loader.efi"
269 else
270 echo "Unknown shim/PreBootloader type: $ShimType"
271 echo "Aborting!"
272 exit 1
273 fi
274 TargetIA32="bootia32.efi"
275 TargetShim="bootx64.efi"
276 fi
277 } # SetVarsForBoot()
278
279 # Set variables for installation in EFI/Microsoft/Boot directory
280 SetVarsForMsBoot() {
281 TargetDir="/EFI/Microsoft/Boot"
282 if [[ $ShimSource == "none" ]] ; then
283 TargetX64="bootmgfw.efi"
284 else
285 if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then
286 TargetX64="grubx64.efi"
287 elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then
288 TargetX64="loader.efi"
289 else
290 echo "Unknown shim/PreBootloader type: $ShimType"
291 echo "Aborting!"
292 exit 1
293 fi
294 TargetShim="bootmgfw.efi"
295 fi
296 } # SetVarsForMsBoot()
297
298 # TargetDir defaults to /EFI/refind; however, this function adjusts it as follows:
299 # - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot,
300 # install to that directory under the suitable name; but DO NOT do this if
301 # refind.conf is also in /EFI/refind.
302 # - If booted in BIOS mode and the ESP lacks any other EFI files, install to
303 # /EFI/BOOT
304 # - If booted in BIOS mode and there's no refind.conf file and there is a
305 # /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and
306 # install under that name, "hijacking" the Windows boot loader filename
307 DetermineTargetDir() {
308 Upgrade=0
309
310 if [[ -f $InstallDir/EFI/BOOT/refind.conf ]] ; then
311 SetVarsForBoot
312 Upgrade=1
313 fi
314 if [[ -f $InstallDir/EFI/Microsoft/Boot/refind.conf ]] ; then
315 SetVarsForMsBoot
316 Upgrade=1
317 fi
318 if [[ -f $InstallDir/EFI/refind/refind.conf ]] ; then
319 TargetDir="/EFI/refind"
320 if [[ "$OSName" == 'Darwin' ]] ; then
321 TargetX64="refind_x64.efi"
322 TargetIA32="refind_ia32.efi"
323 fi
324 Upgrade=1
325 fi
326 if [[ $Upgrade == 1 ]] ; then
327 echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it."
328 fi
329
330 if [[ ! -d /sys/firmware/efi && ! $OSName == 'Darwin' && $Upgrade == 0 ]] ; then # BIOS-mode
331 FoundEfiFiles=`find "$InstallDir/EFI/BOOT" -name "*.efi" 2> /dev/null`
332 FoundConfFiles=`find "$InstallDir" -name "refind\.conf" 2> /dev/null`
333 if [[ ! -n "$FoundConfFiles" && -f "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" ]] ; then
334 mv -n "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" "$InstallDir/EFI/Microsoft" &> /dev/null
335 SetVarsForMsBoot
336 echo "Running in BIOS mode with a suspected Windows installation; moving boot loader"
337 echo "files so as to install to $InstallDir$TargetDir."
338 elif [[ ! -n "$FoundEfiFiles" ]] ; then # In BIOS mode and no default loader; install as default loader
339 SetVarsForBoot
340 echo "Running in BIOS mode with no existing default boot loader; installing to"
341 echo $InstallDir$TargetDir
342 else
343 echo "Running in BIOS mode with an existing default boot loader; backing it up and"
344 echo "installing rEFInd in its place."
345 if [[ -d "$InstallDir/EFI/BOOT-rEFIndBackup" ]] ; then
346 echo ""
347 echo "Caution: An existing backup of a default boot loader exists! If the current"
348 echo "default boot loader and the backup are different boot loaders, the current"
349 echo "one will become inaccessible."
350 echo ""
351 echo -n "Do you want to proceed with installation (Y/N)? "
352 ReadYesNo
353 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
354 echo "OK; continuing with the installation..."
355 else
356 exit 0
357 fi
358 fi
359 mv -n "$InstallDir/EFI/BOOT" "$InstallDir/EFI/BOOT-rEFIndBackup"
360 SetVarsForBoot
361 fi
362 fi # BIOS-mode
363 } # DetermineTargetDir()
364
365 # Determine (or guess) the filesystem used on the Linux /boot filesystem.
366 # Store the result in the BootFS global variable.
367 SetBootFS() {
368 local Blkid
369
370 Blkid=`which blkid 2> /dev/null`
371 BootFS=""
372 if [[ $OSName == 'Linux' && -x "$Blkid" ]] ; then
373 BootPart=`df /boot | grep dev | cut -f 1 -d " "`
374 BootFS=`$Blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
375 fi
376 if [[ $OSName == 'Darwin' ]] ; then
377 # 0FC63DAF-8483-4772-8E79-3D69D8477DE4 = Linux filesystem
378 # BC13C2FF-59E6-4262-A352-B275FD6F7172 = Freedesktop $boot partition
379 # 933AC7E1-2EB4-4F13-B844-0E14E2AEF915 = Freedesktop Linux /home
380 # E6D6D379-F507-44C2-A23C-238F2A3DF928 = Linux LVM
381 # A19D880F-05FC-4D3B-A006-743F0F84911E = Linux RAID
382 # 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F = Linux swap
383 Temp=$(diskutil list | grep -i '0FC63DAF-8483-4772-8E79-3D69D8477DE4\|BC13C2FF-59E6-4262-A352-B275FD6F7172\|933AC7E1-2EB4-4F13-B844-0E14E2AEF915\|E6D6D379-F507-44C2-A23C-238F2A3DF928\|A19D880F-05FC-4D3B-A006-743F0F84911E\|0657FD6D-A4AB-43C4-84E5-0933C84B4F4F\|Linux')
384 BootFS=""
385 if [[ -n $Temp ]] ; then
386 echo "Found suspected Linux partition(s); installing ext4fs driver."
387 BootFS="ext4"
388 fi
389 fi
390 } # SetBootFS()
391
392 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
393 # honoring the $InstallDrivers condition. Must be passed a suitable
394 # architecture code (ia32 or x64).
395 CopyDrivers() {
396 if [[ $InstallDrivers == "all" ]] ; then
397 mkdir -p "$InstallDir/$TargetDir/drivers_$1"
398 cp "$ThisDir"/drivers_$1/*_$1.efi "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null
399 cp "$RefindDir"/drivers_$1/*_$1.efi "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null
400 elif [[ "$InstallDrivers" == "boot" ]] ; then
401 SetBootFS
402 DriverType=""
403 case $BootFS in
404 ext2 | ext3) DriverType="ext2"
405 # Could use ext4, but that can create unwanted entries from symbolic
406 # links in / to /boot/vmlinuz if a separate /boot partition is used.
407 ;;
408 ext4) DriverType="ext4"
409 ;;
410 reiserfs) DriverType="reiserfs"
411 ;;
412 btrfs) DriverType="btrfs"
413 ;;
414 hfsplus) DriverType="hfs"
415 ;;
416 ntfs) DriverType="ntfs"
417 ;;
418 *) BootFS=""
419 esac
420 if [[ -n $BootFS ]] ; then
421 echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
422 mkdir -p "$InstallDir/$TargetDir/drivers_$1"
423 cp "$ThisDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null
424 cp "$RefindDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1"/ 2> /dev/null
425 fi
426 fi
427 } # CopyDrivers()
428
429 # Copy tools (currently only gptsync, and that only on Macs) to the EFI/tools
430 # directory on the ESP. Must be passed a suitable architecture code (ia32
431 # or x64).
432 CopyTools() {
433 mkdir -p "$InstallDir/EFI/tools"
434 if [[ $OSName == 'Darwin' ]] ; then
435 cp -f "$RefindDir/tools_$1/gptsync_$1.efi" "$InstallDir/EFI/tools/"
436 if [[ -f "$InstallDir/EFI/tools/gptsync.efi" ]] ; then
437 mv "$InstallDir/EFI/tools/gptsync.efi" "$InstallDir/EFI/tools/gptsync.efi-disabled"
438 echo "Found old gptsync.efi; disabling it by renaming it to gptsync.efi-disabled"
439 fi
440 fi
441 } # CopyTools()
442
443 # Copy the rEFInd files to the ESP or OS X root partition.
444 # Sets Problems=1 if any critical commands fail.
445 CopyRefindFiles() {
446 mkdir -p "$InstallDir/$TargetDir"
447 if [[ "$TargetDir" == '/EFI/BOOT' ]] ; then
448 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" 2> /dev/null
449 if [[ $? != 0 ]] ; then
450 echo "Note: IA32 (x86) binary not installed!"
451 fi
452 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64" 2> /dev/null
453 if [[ $? != 0 ]] ; then
454 Problems=1
455 fi
456 if [[ "$ShimSource" != "none" ]] ; then
457 TargetShim="bootx64.efi"
458 CopyShimFiles
459 fi
460 if [[ $InstallDrivers == "all" ]] ; then
461 cp -r "$RefindDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null
462 cp -r "$ThisDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null
463 elif [[ $Upgrade == 1 || $InstallToEspOnMac == 1 ]] ; then
464 if [[ $Platform == 'EFI64' ]] ; then
465 CopyDrivers x64
466 CopyTools x64
467 else
468 CopyDrivers ia32
469 CopyTools ia32
470 fi
471 fi
472 Refind=""
473 if [[ $Platform == 'EFI64' ]] ; then
474 Refind='bootx64.efi'
475 elif [[ $Platform == 'EFI32' ]] ; then
476 Refind='bootia32.efi'
477 fi
478 CopyKeys
479 elif [[ $Platform == 'EFI64' || $TargetDir == "/EFI/Microsoft/Boot" ]] ; then
480 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64"
481 if [[ $? != 0 ]] ; then
482 Problems=1
483 fi
484 CopyDrivers x64
485 CopyTools x64
486 Refind="refind_x64.efi"
487 CopyKeys
488 if [[ "$ShimSource" != "none" ]] ; then
489 if [[ "$TargetShim" == "default" ]] ; then
490 TargetShim=`basename "$ShimSource"`
491 fi
492 CopyShimFiles
493 Refind="$TargetShim"
494 if [[ $LocalKeys == 0 ]] ; then
495 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
496 mkdir -p "$EtcKeysDir"
497 cp "$ThisDir/keys/refind.cer" "$EtcKeysDir" 2> /dev/null
498 cp "$ThisDir/keys/refind.crt" "$EtcKeysDir" 2> /dev/null
499 fi
500 fi
501 if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then
502 SetupMacHfs $TargetX64
503 fi
504 elif [[ $Platform == 'EFI32' ]] ; then
505 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32"
506 if [[ $? != 0 ]] ; then
507 Problems=1
508 fi
509 CopyDrivers ia32
510 CopyTools ia32
511 Refind="refind_ia32.efi"
512 if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then
513 SetupMacHfs $TargetIA32
514 fi
515 else
516 echo "Unknown platform! Aborting!"
517 exit 1
518 fi
519 echo "Copied rEFInd binary files"
520 echo ""
521 if [[ -d "$InstallDir/$TargetDir/icons" ]] ; then
522 rm -rf "$InstallDir/$TargetDir/icons-backup" &> /dev/null
523 mv -f "$InstallDir/$TargetDir/icons" "$InstallDir/$TargetDir/icons-backup"
524 echo "Notice: Backed up existing icons directory as icons-backup."
525 fi
526 cp -r "$IconsDir" "$InstallDir/$TargetDir"
527 if [[ $? != 0 ]] ; then
528 Problems=1
529 fi
530 mkdir -p "$InstallDir/$TargetDir/keys"
531 cp -rf "$ThisDir"/keys/*.[cd]er "$InstallDir/$TargetDir/keys/" 2> /dev/null
532 cp -rf "$EtcKeysDir"/*.[cd]er "$InstallDir/$TargetDir/keys/" 2> /dev/null
533 if [[ -f "$InstallDir/$TargetDir/refind.conf" ]] ; then
534 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
535 echo "to avoid overwriting your customizations."
536 echo ""
537 cp -f "$ConfFile" "$InstallDir/$TargetDir"
538 if [[ $? != 0 ]] ; then
539 Problems=1
540 fi
541 else
542 echo "Copying sample configuration file as refind.conf; edit this file to configure"
543 echo "rEFInd."
544 echo ""
545 cp -f "$ConfFile" "$InstallDir/$TargetDir/refind.conf"
546 if [[ $? != 0 ]] ; then
547 Problems=1
548 fi
549 fi
550 if [[ $DeleteRefindDir == 1 ]] ; then
551 echo "Deleting the temporary directory $RefindDir"
552 rm -r "$RefindDir"
553 fi
554 } # CopyRefindFiles()
555
556 # Mount the partition the user specified with the --usedefault or --ownhfs option
557 MountDefaultTarget() {
558 InstallDir=/tmp/refind_install
559 mkdir -p "$InstallDir"
560 UnmountEsp=1
561 if [[ $OSName == 'Darwin' ]] ; then
562 if [[ $OwnHfs == '1' ]] ; then
563 Temp=`diskutil info "$TargetPart" | grep "Mount Point"`
564 InstallDir=`echo $Temp | cut -f 3-30 -d ' '`
565 if [[ $InstallDir == '' ]] ; then
566 InstallDir=/tmp/refind_install
567 mount -t hfs "$TargetPart" "$InstallDir"
568 else
569 UnmountEsp=0
570 fi
571 else
572 mount -t msdos "$TargetPart" "$InstallDir"
573 fi
574 elif [[ $OSName == 'Linux' ]] ; then
575 mount -t vfat "$TargetPart" "$InstallDir"
576 fi
577 if [[ $? != 0 ]] ; then
578 echo "Couldn't mount $TargetPart ! Aborting!"
579 rmdir "$InstallDir"
580 exit 1
581 fi
582 } # MountDefaultTarget()
583
584 #
585 # A series of OS X support functions....
586 #
587
588 # Mount the ESP at /Volumes/ESP or determine its current mount
589 # point.
590 # Sets InstallDir to the ESP mount point
591 # Sets UnmountEsp if we mounted it
592 MountOSXESP() {
593 # Identify the ESP. Note: This returns the FIRST ESP found;
594 # if the system has multiple disks, this could be wrong!
595 Temp=$(mount | sed -n -E "/^(\/dev\/disk[0-9]+s[0-9]+) on \/ \(.*$/s//\1/p")
596 if [ $Temp ]; then
597 Temp=$(diskutil list | grep " EFI " | grep -o 'disk.*' | head -n 1)
598 if [ -z $Temp ]; then
599 echo "Warning: root device doesn't have an EFI partition"
600 fi
601 else
602 echo "Warning: root device could not be found"
603 fi
604 if [ -z $Temp ]; then
605 Temp=$(diskutil list | sed -n -E '/^ *[0-9]+:[ ]+EFI EFI[ ]+[0-9.]+ [A-Z]+[ ]+(disk[0-9]+s[0-9]+)$/ { s//\1/p
606 q
607 }' )
608
609 if [ -z $Temp ]; then
610 echo "Could not find an EFI partition. Aborting!"
611 exit 1
612 fi
613 fi
614 Esp=/dev/`echo $Temp`
615 # If the ESP is mounted, use its current mount point....
616 Temp=`df -P | grep "$Esp "`
617 InstallDir=`echo $Temp | cut -f 6- -d ' '`
618 if [[ "$InstallDir" == '' ]] ; then
619 mkdir /Volumes/ESP &> /dev/null
620 mount -t msdos "$Esp" /Volumes/ESP
621 # Some systems have HFS+ "ESPs." They shouldn't, but they do. If this is
622 # detected, mount it as such and set appropriate options.
623 if [[ $? != 0 ]] ; then
624 mount -t hfs "$Esp" /Volumes/Esp
625 OwnHfs=1
626 InstallToEspOnMac=0
627 if [[ $? != 0 ]] ; then
628 echo "Unable to mount ESP! Aborting!\n"
629 exit 1
630 fi
631 fi
632 UnmountEsp=1
633 InstallDir="/Volumes/ESP"
634 fi
635 } # MountOSXESP()
636
637 # Set up for booting from Mac HFS+ volume that boots rEFInd in MJG's way
638 # (http://mjg59.dreamwidth.org/7468.html)
639 # Must be passed the original rEFInd binary filename (without a path).
640 SetupMacHfs() {
641 if [[ -s "$InstallDir/mach_kernel" ]] ; then
642 echo "Attempt to install rEFInd to a partition with a /mach_kernel file! Aborting!"
643 exit 1
644 fi
645 cp -n "$InstallDir/$TargetDir/boot.efi" "$InstallDir/$TargetDir/boot.efi-backup" &> /dev/null
646 ln -f "$InstallDir/$TargetDir/$1" "$InstallDir/$TargetDir/boot.efi"
647 touch "$InstallDir/mach_kernel"
648 rm "$InstallDir/$TargetDir/SystemVersion.plist" &> /dev/null
649 cat - << ENDOFHERE >> "$InstallDir/$TargetDir/SystemVersion.plist"
650 <xml version="1.0" encoding="UTF-8"?>
651 <plist version="1.0">
652 <dict>
653 <key>ProductBuildVersion</key>
654 <string></string>
655 <key>ProductName</key>
656 <string>rEFInd</string>
657 <key>ProductVersion</key>
658 <string>0.8.6</string>
659 </dict>
660 </plist>
661 ENDOFHERE
662 } # SetupMacHfs()
663
664 # Control the OS X installation.
665 # Sets Problems=1 if problems found during the installation.
666 InstallOnOSX() {
667 echo "Installing rEFInd on OS X...."
668 if [[ "$InstallToEspOnMac" == "1" ]] ; then
669 MountOSXESP
670 elif [[ "$TargetDir" == "/EFI/BOOT" || "$OwnHfs" == '1' ]] ; then
671 MountDefaultTarget
672 else
673 InstallDir="$RootDir/"
674 fi
675 echo "Installing rEFInd to the partition mounted at $InstallDir"
676 DetermineTargetDir
677 Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
678 CopyRefindFiles
679 if [[ $InstallToEspOnMac == "1" ]] ; then
680 bless --mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind" --shortform
681 elif [[ "$TargetDir" != "/EFI/BOOT" ]] ; then
682 bless --setBoot --folder "$InstallDir/$TargetDir" --file "$InstallDir/$TargetDir/$Refind"
683 fi
684 if [[ $? != 0 ]] ; then
685 Problems=1
686 fi
687 if [[ -f /Library/StartupItems/rEFItBlesser || -d /Library/StartupItems/rEFItBlesser ]] ; then
688 echo
689 echo "/Library/StartupItems/rEFItBlesser found!"
690 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
691 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
692 ReadYesNo
693 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
694 echo "Deleting /Library/StartupItems/rEFItBlesser..."
695 rm -r /Library/StartupItems/rEFItBlesser
696 else
697 echo "Not deleting rEFItBlesser."
698 fi
699 fi
700 echo
701 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
702 echo "bless status with 'bless --info', since this is known to cause disk corruption"
703 echo "on some systems!!"
704 echo
705 } # InstallOnOSX()
706
707
708 #
709 # Now a series of Linux support functions....
710 #
711
712 # Check for evidence that we're running in Secure Boot mode. If so, and if
713 # appropriate options haven't been set, warn the user and offer to abort.
714 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
715 # or --localkeys option, warn the user and offer to abort.
716 CheckSecureBoot() {
717 local IsSecureBoot
718 if [[ -f /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data ]] ; then
719 IsSecureBoot=`od -An -t u1 /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data | tr -d '[[:space:]]'`
720 else
721 IsSecureBoot="0"
722 fi
723 if [[ $IsSecureBoot == "1" && "$TargetDir" != '/EFI/BOOT' && "$ShimSource" == "none" ]] ; then
724 echo ""
725 echo "CAUTION: Your computer appears to be booted with Secure Boot, but you haven't"
726 echo "specified a valid shim.efi file source. Chances are you should re-run with"
727 echo "the --shim option. You can read more about this topic at"
728 echo "http://www.rodsbooks.com/refind/secureboot.html."
729 echo ""
730 echo -n "Do you want to proceed with installation (Y/N)? "
731 ReadYesNo
732 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
733 echo "OK; continuing with the installation..."
734 else
735 exit 0
736 fi
737 fi
738
739 if [[ "$ShimSource" != "none" && ! $IsSecureBoot == "1" ]] ; then
740 echo ""
741 echo "You've specified installing using a shim.efi file, but your computer does not"
742 echo "appear to be running in Secure Boot mode. Although installing in this way"
743 echo "should work, it's unnecessarily complex. You may continue, but unless you"
744 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
745 echo "--shim option. You can read more about this topic at"
746 echo "http://www.rodsbooks.com/refind/secureboot.html."
747 echo ""
748 echo -n "Do you want to proceed with installation (Y/N)? "
749 ReadYesNo
750 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
751 echo "OK; continuing with the installation..."
752 else
753 exit 0
754 fi
755 fi
756
757 if [[ $LocalKeys != 0 && ! $IsSecureBoot == "1" ]] ; then
758 echo ""
759 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
760 echo "but your computer does not appear to be running in Secure Boot mode. The"
761 echo "keys you generate will be useless unless you enable Secure Boot. You may"
762 echo "proceed with this installation, but before you do so, you may want to read"
763 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
764 echo ""
765 echo -n "Do you want to proceed with installation (Y/N)? "
766 ReadYesNo
767 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
768 echo "OK; continuing with the installation..."
769 else
770 exit 0
771 fi
772 fi
773
774 } # CheckSecureBoot()
775
776 # Check for the presence of locally-generated keys from a previous installation in
777 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
778 # openssl.
779 GenerateKeys() {
780 PrivateKey="$EtcKeysDir/$LocalKeysBase.key"
781 CertKey="$EtcKeysDir/$LocalKeysBase.crt"
782 DerKey="$EtcKeysDir/$LocalKeysBase.cer"
783 OpenSSL=`which openssl 2> /dev/null`
784
785 # Do the work only if one or more of the necessary keys is missing
786 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
787 # is also missing, this will fail. This could be improved.
788 if [[ ! -f "$PrivateKey" || ! -f "$CertKey" || ! -f "$DerKey" ]] ; then
789 echo "Generating a fresh set of local keys...."
790 mkdir -p "$EtcKeysDir"
791 chmod 0700 "$EtcKeysDir"
792 if [[ ! -x "$OpenSSL" ]] ; then
793 echo "Can't find openssl, which is required to create your private signing keys!"
794 echo "Aborting!"
795 exit 1
796 fi
797 if [[ -f "$PrivateKey" ]] ; then
798 echo "Backing up existing $PrivateKey"
799 cp -f "$PrivateKey" "$PrivateKey.backup" 2> /dev/null
800 fi
801 if [[ -f "$CertKey" ]] ; then
802 echo "Backing up existing $CertKey"
803 cp -f "$CertKey" "$CertKey.backup" 2> /dev/null
804 fi
805 if [[ -f "$DerKey" ]] ; then
806 echo "Backing up existing $DerKey"
807 cp -f "$DerKey" "$DerKey.backup" 2> /dev/null
808 fi
809 "$OpenSSL" req -new -x509 -newkey rsa:2048 -keyout "$PrivateKey" -out "$CertKey" \
810 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
811 "$OpenSSL" x509 -in "$CertKey" -out "$DerKey" -outform DER
812 chmod 0600 "$PrivateKey"
813 else
814 echo "Using existing local keys...."
815 fi
816 }
817
818 # Sign a single binary. Requires parameters:
819 # $1 = source file
820 # $2 = destination file
821 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
822 # appropriately.
823 # Aborts script on error
824 SignOneBinary() {
825 $SBSign --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1"
826 if [[ $? != 0 ]] ; then
827 echo "Problem signing the binary $1! Aborting!"
828 exit 1
829 fi
830 }
831
832 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
833 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
834 # not, try to generate new keys and store them in $EtcKeysDir.
835 ReSignBinaries() {
836 SBSign=`which sbsign 2> /dev/null`
837 echo "Found sbsign at $SBSign"
838 TempDir="/tmp/refind_local"
839 if [[ ! -x "$SBSign" ]] ; then
840 echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
841 echo "Aborting!"
842 exit 1
843 fi
844 GenerateKeys
845 mkdir -p "$TempDir/drivers_x64"
846 cp "$RefindDir/refind.conf-sample $TempDir" 2> /dev/null
847 cp "$ThisDir/refind.conf-sample $TempDir" 2> /dev/null
848 cp "$RefindDir/refind_ia32.efi $TempDir" 2> /dev/null
849 cp -a "$RefindDir/drivers_ia32 $TempDir" 2> /dev/null
850 cp -a "$ThisDir/drivers_ia32 $TempDir" 2> /dev/null
851 SignOneBinary "$RefindDir/refind_x64.efi" "$TempDir/refind_x64.efi"
852 SaveIFS=$IFS
853 IFS=$(echo -en "\n\b")
854 for Driver in `ls "$RefindDir"/drivers_x64/*.efi "$ThisDir"/drivers_x64/*.efi 2> /dev/null` ; do
855 TempName=`basename "$Driver"`
856 SignOneBinary "$Driver" "$TempDir/drivers_x64/$TempName"
857 done
858 IFS=$SaveIFS
859 RefindDir="$TempDir"
860 DeleteRefindDir=1
861 } # ReSignBinaries()
862
863 # Locate and mount an ESP, if possible, based on parted output.
864 # Should be called only if /boot/efi is NOT an acceptable ESP.
865 # Sets InstallDir to the mounted ESP's path ($RootDir/boot/efi)
866 # and EspFilesystem the filesystem (always "vfat")
867 FindLinuxESP() {
868 echo "The ESP doesn't seem to be mounted! Trying to find it...."
869 local Drive
870 local PartNum
871 local TableType
872 local DmStatus
873 local SkipIt
874 local Dmraid
875 for Drive in `ls /dev/[sh]d?` ; do
876 SkipIt=0
877 Dmraid=`which dmraid 2> /dev/null`
878 if [ -x "$Dmraid" ] ; then
879 DmStatus=`dmraid -r | grep $Drive`
880 if [ -n "$DmStatus" ] ; then
881 echo "$Drive seems to be part of a RAID array; skipping!"
882 SkipIt=1
883 fi
884 fi
885 TableType=`parted $Drive print -m -s 2>/dev/null | awk -F: '$1 == "'$Drive'" { print $6 }'`
886 if [[ $TableType == 'gpt' && $SkipIt == 0 ]] ; then # read only GPT disks that aren't part of dmraid array
887 PartNum=`LANG=C parted $Drive print -m -s 2>/dev/null | awk -F: '$7 ~ "(^boot| boot)" { print $1 }' | head -n 1`
888 if [ "$PartNum" -eq "$PartNum" ] 2> /dev/null ; then
889 InstallDir="$RootDir/boot/efi"
890 mkdir -p $InstallDir
891 mount $Drive$PartNum $InstallDir
892 EspFilesystem=`grep "$Drive$PartNum.*/boot/efi" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3`
893 if [[ $EspFilesystem != 'vfat' ]] ; then
894 umount $InstallDir
895 else
896 echo "Mounting ESP at $InstallDir"
897 break;
898 fi
899 fi # $PartNum -eq $PartNum
900 fi # TableType
901 done
902 } # FindLinuxESP()
903
904 # Identifies the ESP's location (/boot or /boot/efi, or these locations under
905 # the directory specified by --root); aborts if the ESP isn't mounted at
906 # either location.
907 # Sets InstallDir to the ESP mount point.
908 FindMountedESP() {
909 mount /boot &> /dev/null
910 mount /boot/efi &> /dev/null
911 EspLine=`df "$RootDir/boot/efi" 2> /dev/null | grep boot/efi`
912 if [[ ! -n "$EspLine" ]] ; then
913 EspLine=`df "$RootDir"/boot | grep boot`
914 fi
915 InstallDir=`echo $EspLine | cut -d " " -f 6`
916
917 if [[ -n "$InstallDir" ]] ; then
918 EspFilesystem=`grep -w "$InstallDir" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3`
919 fi
920 if [[ $EspFilesystem != 'vfat' ]] ; then
921 FindLinuxESP
922 fi
923 if [[ $EspFilesystem != 'vfat' ]] ; then
924 echo "$RootDir/$InstallDir doesn't seem to be on a VFAT filesystem. The ESP must be"
925 echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
926 exit 1
927 fi
928 echo "ESP was found at $InstallDir using $EspFilesystem"
929 } # FindMountedESP
930
931 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
932 # If this fails, sets Problems=1
933 AddBootEntry() {
934 local PartNum
935 InstallIt="0"
936 Efibootmgr=`which efibootmgr 2> /dev/null`
937 if [[ "$Efibootmgr" ]] ; then
938 InstallDisk=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
939 PartNum=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
940 EntryFilename="$TargetDir/$Refind"
941 EfiEntryFilename=`echo ${EntryFilename//\//\\\}`
942 EfiEntryFilename2=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
943 ExistingEntry=`"$Efibootmgr" -v | grep -i "$EfiEntryFilename2"`
944
945 if [[ "$ExistingEntry" ]] ; then
946 ExistingEntryBootNum=`echo "$ExistingEntry" | cut -c 5-8`
947 FirstBoot=`"$Efibootmgr" | grep BootOrder | cut -c 12-15`
948 if [[ "$ExistingEntryBootNum" != "$FirstBoot" ]] ; then
949 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
950 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
951 echo "manager. If this is NOT what you want, you should use efibootmgr to"
952 echo "manually adjust your EFI's boot order."
953 "$Efibootmgr" -b $ExistingEntryBootNum -B &> /dev/null
954 InstallIt="1"
955 fi
956 else
957 InstallIt="1"
958 fi
959
960 if [[ $InstallIt == "1" ]] ; then
961 echo "Installing it!"
962 "$Efibootmgr" -c -l "$EfiEntryFilename" -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev/null
963 if [[ $? != 0 ]] ; then
964 EfibootmgrProblems=1
965 Problems=1
966 fi
967 fi
968
969 else # efibootmgr not found
970 EfibootmgrProblems=1
971 Problems=1
972 fi
973
974 if [[ $EfibootmgrProblems ]] ; then
975 echo
976 echo "ALERT: There were problems running the efibootmgr program! You may need to"
977 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
978 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
979 echo
980 else
981 echo "rEFInd has been set as the default boot manager."
982 fi
983 } # AddBootEntry()
984
985 # Create a minimal/sample refind_linux.conf file in /boot.
986 GenerateRefindLinuxConf() {
987 if [[ -f "$RLConfFile" ]] ; then
988 echo "Existing $RLConfFile found; not overwriting."
989 else
990 echo "Creating $RLConfFile; edit it to adjust kernel options."
991 if [[ -f "$RootDir/etc/default/grub" ]] ; then
992 # We want the default options used by the distribution, stored here....
993 source "$RootDir/etc/default/grub"
994 echo "Setting default boot options based on $RootDir/etc/default/grub"
995 fi
996 RootFS=`df "$RootDir" | grep dev | cut -f 1 -d " "`
997 StartOfDevname=`echo "$RootFS" | cut -b 1-7`
998 if [[ "$StartOfDevname" == "/dev/sd" || "$StartOfDevName" == "/dev/hd" ]] ; then
999 # Identify root filesystem by UUID rather than by device node, if possible
1000 Uuid=`blkid -o export -s UUID "$RootFS" 2> /dev/null | grep UUID=`
1001 if [[ -n $Uuid ]] ; then
1002 RootFS="$Uuid"
1003 fi
1004 fi
1005 DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
1006 echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
1007 echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
1008 echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
1009 fi
1010 }
1011
1012 # Controls rEFInd installation under Linux.
1013 # Sets Problems=1 if something goes wrong.
1014 InstallOnLinux() {
1015 if [[ "$TargetDir" == "/System/Library/CoreServices" ]] ; then
1016 echo "You may not use the --ownhfs option under Linux! Aborting!"
1017 exit 1
1018 fi
1019 echo "Installing rEFInd on Linux...."
1020 modprobe efivars &> /dev/null
1021 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
1022 MountDefaultTarget
1023 else
1024 FindMountedESP
1025 DetermineTargetDir
1026 fi
1027 CpuType=`uname -m`
1028 if [[ $CpuType == 'x86_64' ]] ; then
1029 Platform="EFI64"
1030 elif [[ ($CpuType == 'i386' || $CpuType == 'i486' || $CpuType == 'i586' || $CpuType == 'i686') ]] ; then
1031 Platform="EFI32"
1032 # If we're in EFI mode, do some sanity checks, and alert the user or even
1033 # abort. Not in BIOS mode, though, since that could be used on an emergency
1034 # disc to try to recover a troubled Linux installation.
1035 if [[ -d /sys/firmware/efi ]] ; then
1036 if [[ "$ShimSource" != "none" && "$TargetDir" != "/BOOT/EFI" ]] ; then
1037 echo ""
1038 echo "CAUTION: shim does not currently supports 32-bit systems, so you should not"
1039 echo "use the --shim option to install on such systems. Aborting!"
1040 echo ""
1041 exit 1
1042 fi
1043 echo
1044 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
1045 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
1046 echo "on a 64-bit computer, you should manually install the 64-bit version of"
1047 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
1048 echo "you're positive you want to continue with this installation, answer 'Y'"
1049 echo "to the following question..."
1050 echo
1051 echo -n "Are you sure you want to continue (Y/N)? "
1052 ReadYesNo
1053 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
1054 echo "OK; continuing with the installation..."
1055 else
1056 exit 0
1057 fi
1058 fi # in EFI mode
1059 else
1060 echo "Unknown CPU type '$CpuType'; aborting!"
1061 exit 1
1062 fi
1063
1064 if [[ $LocalKeys == 1 ]] ; then
1065 ReSignBinaries
1066 fi
1067
1068 CheckSecureBoot
1069 CopyRefindFiles
1070 if [[ "$TargetDir" != "/EFI/BOOT" && "$TargetDir" != "/EFI/Microsoft/Boot" ]] ; then
1071 AddBootEntry
1072 GenerateRefindLinuxConf
1073 fi
1074 } # InstallOnLinux()
1075
1076 #
1077 # The main part of the script. Sets a few environment variables,
1078 # performs a few startup checks, and then calls functions to
1079 # install under OS X or Linux, depending on the detected platform.
1080 #
1081 OSName=`uname -s`
1082 GetParams "$@"
1083 ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
1084 RefindDir="$ThisDir/refind"
1085 ThisScript="$ThisDir/`basename $0`"
1086 if [[ `whoami` != "root" ]] ; then
1087 echo "Not running as root; attempting to elevate privileges via sudo...."
1088 sudo "$ThisScript" "$@"
1089 if [[ $? != 0 ]] ; then
1090 echo "This script must be run as root (or using sudo). Exiting!"
1091 exit 1
1092 else
1093 exit 0
1094 fi
1095 fi
1096 CheckForFiles
1097 if [[ $OSName == 'Darwin' ]] ; then
1098 if [[ "$ShimSource" != "none" ]] ; then
1099 echo "The --shim option is not supported on OS X! Exiting!"
1100 exit 1
1101 fi
1102 if [[ "$LocalKeys" != 0 ]] ; then
1103 echo "The --localkeys option is not supported on OS X! Exiting!"
1104 exit 1
1105 fi
1106 InstallOnOSX $1
1107 elif [[ $OSName == 'Linux' ]] ; then
1108 InstallOnLinux
1109 else
1110 echo "Running on unknown OS; aborting!"
1111 if [[ "$InstallToEspOnMac" == 0 ]] ; then
1112 echo "The --notesp option is not supported on Linux! Exiting!"
1113 exit 1
1114 fi
1115 fi
1116
1117 if [[ $Problems ]] ; then
1118 echo
1119 echo "ALERT:"
1120 echo "Installation has completed, but problems were detected. Review the output for"
1121 echo "error messages and take corrective measures as necessary. You may need to"
1122 echo "re-run this script or install manually before rEFInd will work."
1123 echo
1124 else
1125 echo
1126 echo "Installation has completed successfully."
1127 echo
1128 fi
1129
1130 if [[ $UnmountEsp == '1' ]] ; then
1131 echo "Unmounting install dir"
1132 umount $InstallDir
1133 fi
1134
1135 if [[ "$InstallDir" == /tmp/refind_install ]] ; then
1136 # sleep 5
1137 rmdir "$InstallDir"
1138 fi