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