]> code.delx.au - refind/blob - install.sh
New "textmode" option to set the text-mode video mode. Also bug fixes.
[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 # "--esp" to install to the ESP rather than to the system's root
11 # filesystem. This is the default on 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 # "--alldrivers" to install all drivers along with regular files
16 # "--nodrivers" to suppress driver installation (default in Linux is
17 # driver used on /boot; --nodrivers is OS X default)
18 # "--shim {shimfile}" to install a shim.efi file for Secure Boot
19 # "--localkeys" to re-sign x86-64 binaries with a locally-generated key
20 #
21 # The "esp" option is valid only on Mac OS X; it causes
22 # installation to the EFI System Partition (ESP) rather than
23 # to the current OS X boot partition. Under Linux, this script
24 # installs to the ESP by default.
25 #
26 # This program is copyright (c) 2012 by Roderick W. Smith
27 # It is released under the terms of the GNU GPL, version 3,
28 # a copy of which should be included in the file COPYING.txt.
29 #
30 # Revision history:
31 #
32 # 0.5.2 -- Changed --drivers to --alldrivers and added --nodrivers option;
33 # changed default driver installation behavior in Linux to install
34 # the driver needed to read /boot (if available)
35 # 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
36 # 0.5.1.1 -- Fixed bug that caused script failure under OS X
37 # 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
38 # in /boot
39 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
40 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
41 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
42 # 0.4.1 -- Added check for rEFItBlesser in OS X
43 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
44 # 0.3.2.1 -- Check for presence of source files; aborts if not present
45 # 0.3.2 -- Initial version
46 #
47 # Note: install.sh version numbers match those of the rEFInd package
48 # with which they first appeared.
49
50 TargetDir=/EFI/refind
51 EtcKeysDir=/etc/refind.d/keys
52 LocalKeysBase="refind_local"
53 RLConfFile="/boot/refind_linux.conf"
54 ShimSource="none"
55 TargetX64="refind_x64.efi"
56 TargetIA32="refind_ia32.efi"
57 LocalKeys=0
58 DeleteRefindDir=0
59
60 #
61 # Functions used by both OS X and Linux....
62 #
63
64 GetParams() {
65 InstallToEspOnMac=0
66 if [[ $OSName == "Linux" ]] ; then
67 # Install the driver required to read /boot, if it's available
68 InstallDrivers="boot"
69 else
70 InstallDrivers="none"
71 fi
72 while [[ $# -gt 0 ]]; do
73 case $1 in
74 --esp | --ESP) InstallToEspOnMac=1
75 ;;
76 --usedefault) TargetDir=/EFI/BOOT
77 TargetPart=$2
78 TargetX64="bootx64.efi"
79 TargetIA32="bootia32.efi"
80 shift
81 ;;
82 --localkeys) LocalKeys=1
83 ;;
84 --shim) ShimSource=$2
85 shift
86 ;;
87 --drivers | --alldrivers) InstallDrivers="all"
88 ;;
89 --nodrivers) InstallDrivers="none"
90 ;;
91 * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--nodrivers | --alldrivers] "
92 echo " [--shim {shim-filename}] [--localkeys]"
93 exit 1
94 esac
95 shift
96 done
97 if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then
98 echo "You may use --esp OR --usedefault, but not both! Aborting!"
99 exit 1
100 fi
101 # exit 1
102 } # GetParams()
103
104 # Abort if the rEFInd files can't be found.
105 # Also sets $ConfFile to point to the configuration file,
106 # $IconsDir to point to the icons directory, and
107 # $ShimSource to the source of the shim.efi file (if necessary).
108 CheckForFiles() {
109 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
110 # is found, even on the wrong platform. This is because the platform
111 # hasn't yet been determined. This could obviously be improved, but it
112 # would mean restructuring lots more code....
113 if [[ ! -f $RefindDir/refind_ia32.efi && ! -f $RefindDir/refind_x64.efi ]] ; then
114 echo "The rEFInd binary file is missing! Aborting installation!"
115 exit 1
116 fi
117
118 if [[ -f $RefindDir/refind.conf-sample ]] ; then
119 ConfFile=$RefindDir/refind.conf-sample
120 elif [[ -f $ThisDir/refind.conf-sample ]] ; then
121 ConfFile=$ThisDir/refind.conf-sample
122 else
123 echo "The sample configuration file is missing! Aborting installation!"
124 exit 1
125 fi
126
127 if [[ -d $RefindDir/icons ]] ; then
128 IconsDir=$RefindDir/icons
129 elif [[ -d $ThisDir/icons ]] ; then
130 IconsDir=$ThisDir/icons
131 else
132 echo "The icons directory is missing! Aborting installation!"
133 exit 1
134 fi
135
136 if [[ $ShimSource != "none" ]] ; then
137 if [[ -f $ShimSource ]] ; then
138 TargetX64="grubx64.efi"
139 MokManagerSource=`dirname $ShimSource`/MokManager.efi
140 else
141 echo "The specified shim file, $ShimSource, doesn't exist!"
142 echo "Aborting installation!"
143 exit 1
144 fi
145 fi
146 } # CheckForFiles()
147
148 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
149 # available) to target.
150 CopyShimFiles() {
151 cp $ShimSource $InstallDir/$TargetDir/$TargetShim
152 if [[ $? != 0 ]] ; then
153 Problems=1
154 fi
155 if [[ -f $MokManagerSource ]] ; then
156 cp $MokManagerSource $InstallDir/$TargetDir/
157 fi
158 if [[ $? != 0 ]] ; then
159 Problems=1
160 fi
161 } # CopyShimFiles()
162
163 # Copy the public keys to the installation medium
164 CopyKeys() {
165 if [[ $LocalKeys == 1 ]] ; then
166 cp $EtcKeysDir/$LocalKeysBase.cer $InstallDir/$TargetDir
167 cp $EtcKeysDir/$LocalKeysBase.crt $InstallDir/$TargetDir
168 else
169 cp $ThisDir/refind.cer $InstallDir/$TargetDir
170 cp $ThisDir/refind.crt $InstallDir/$TargetDir
171 fi
172 } # CopyKeys()
173
174 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
175 # honoring the $InstallDrivers condition. Must be passed a suitable
176 # architecture code (ia32 or x64).
177 CopyDrivers() {
178 if [[ $InstallDrivers == "all" ]] ; then
179 mkdir -p $InstallDir/$TargetDir/drivers_$1
180 cp $RefindDir/drivers_$1/*_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
181 cp $ThisDir/drivers_$1/*_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
182 elif [[ $InstallDrivers == "boot" && -x `which blkid` ]] ; then
183 BootPart=`df /boot | grep dev | cut -f 1 -d " "`
184 BootFS=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
185 DriverType=""
186 case $BootFS in
187 ext2 | ext3) DriverType="ext2"
188 ;;
189 reiserfs) DriverType="reiserfs"
190 ;;
191 hfsplus) DriverType="hfs"
192 ;;
193 esac
194 if [[ -n $BootFS ]] ; then
195 echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
196 mkdir -p $InstallDir/$TargetDir/drivers_$1
197 cp $RefindDir/drivers_$1/${DriverType}_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
198 cp $ThisDir/drivers_$1/${DriverType}_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
199 fi
200 fi
201 }
202
203 # Copy the rEFInd files to the ESP or OS X root partition.
204 # Sets Problems=1 if any critical commands fail.
205 CopyRefindFiles() {
206 mkdir -p $InstallDir/$TargetDir &> /dev/null
207 if [[ $TargetDir == '/EFI/BOOT' ]] ; then
208 cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/$TargetIA32 2> /dev/null
209 if [[ $? != 0 ]] ; then
210 echo "Note: IA32 (x86) binary not installed!"
211 fi
212 cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/$TargetX64 2> /dev/null
213 if [[ $? != 0 ]] ; then
214 Problems=1
215 fi
216 if [[ $ShimSource != "none" ]] ; then
217 TargetShim="bootx64.efi"
218 CopyShimFiles
219 fi
220 if [[ $InstallDrivers == "all" ]] ; then
221 cp -r $RefindDir/drivers_* $InstallDir/$TargetDir/ 2> /dev/null
222 cp -r $ThisDir/drivers_* $InstallDir/$TargetDir/ 2> /dev/null
223 fi
224 Refind=""
225 CopyKeys
226 elif [[ $Platform == 'EFI32' ]] ; then
227 cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/$TargetIA32
228 if [[ $? != 0 ]] ; then
229 Problems=1
230 fi
231 CopyDrivers ia32
232 Refind="refind_ia32.efi"
233 elif [[ $Platform == 'EFI64' ]] ; then
234 cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/$TargetX64
235 if [[ $? != 0 ]] ; then
236 Problems=1
237 fi
238 CopyDrivers x64
239 Refind="refind_x64.efi"
240 CopyKeys
241 if [[ $ShimSource != "none" ]] ; then
242 TargetShim=`basename $ShimSource`
243 CopyShimFiles
244 Refind=$TargetShim
245 if [[ $LocalKeys == 0 ]] ; then
246 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
247 mkdir -p $EtcKeysDir
248 cp $ThisDir/refind.cer $EtcKeysDir
249 cp $ThisDir/refind.crt $EtcKeysDir
250 fi
251 fi
252 else
253 echo "Unknown platform! Aborting!"
254 exit 1
255 fi
256 echo "Copied rEFInd binary files"
257 echo ""
258 if [[ -d $InstallDir/$TargetDir/icons ]] ; then
259 rm -rf $InstallDir/$TargetDir/icons-backup &> /dev/null
260 mv -f $InstallDir/$TargetDir/icons $InstallDir/$TargetDir/icons-backup
261 echo "Notice: Backed up existing icons directory as icons-backup."
262 fi
263 cp -r $IconsDir $InstallDir/$TargetDir
264 if [[ $? != 0 ]] ; then
265 Problems=1
266 fi
267 if [[ -f $InstallDir/$TargetDir/refind.conf ]] ; then
268 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
269 echo "to avoid overwriting your customizations."
270 echo ""
271 cp -f $ConfFile $InstallDir/$TargetDir
272 if [[ $? != 0 ]] ; then
273 Problems=1
274 fi
275 else
276 echo "Copying sample configuration file as refind.conf; edit this file to configure"
277 echo "rEFInd."
278 echo ""
279 cp -f $ConfFile $InstallDir/$TargetDir/refind.conf
280 if [[ $? != 0 ]] ; then
281 Problems=1
282 fi
283 fi
284 if [[ $DeleteRefindDir == 1 ]] ; then
285 echo "Deleting the temporary directory $RefindDir"
286 rm -r $RefindDir
287 fi
288 } # CopyRefindFiles()
289
290 # Mount the partition the user specified with the --usedefault option
291 MountDefaultTarget() {
292 InstallDir=/tmp/refind_install
293 mkdir -p $InstallDir
294 if [[ $OSName == 'Darwin' ]] ; then
295 mount -t msdos $TargetPart $InstallDir
296 elif [[ $OSName == 'Linux' ]] ; then
297 mount -t vfat $TargetPart $InstallDir
298 fi
299 if [[ $? != 0 ]] ; then
300 echo "Couldn't mount $TargetPart ! Aborting!"
301 rmdir $InstallDir
302 exit 1
303 fi
304 UnmountEsp=1
305 } # MountDefaultTarget()
306
307 #
308 # A series of OS X support functions....
309 #
310
311 # Mount the ESP at /Volumes/ESP or determine its current mount
312 # point.
313 # Sets InstallDir to the ESP mount point
314 # Sets UnmountEsp if we mounted it
315 MountOSXESP() {
316 # Identify the ESP. Note: This returns the FIRST ESP found;
317 # if the system has multiple disks, this could be wrong!
318 Temp=`diskutil list | grep " EFI "`
319 Esp=/dev/`echo $Temp | cut -f 5 -d ' '`
320 # If the ESP is mounted, use its current mount point....
321 Temp=`df | grep $Esp`
322 InstallDir=`echo $Temp | cut -f 6 -d ' '`
323 if [[ $InstallDir == '' ]] ; then
324 mkdir /Volumes/ESP &> /dev/null
325 mount -t msdos $Esp /Volumes/ESP
326 if [[ $? != 0 ]] ; then
327 echo "Unable to mount ESP! Aborting!\n"
328 exit 1
329 fi
330 UnmountEsp=1
331 InstallDir="/Volumes/ESP"
332 fi
333 } # MountOSXESP()
334
335 # Control the OS X installation.
336 # Sets Problems=1 if problems found during the installation.
337 InstallOnOSX() {
338 echo "Installing rEFInd on OS X...."
339 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
340 MountDefaultTarget
341 elif [[ $InstallToEspOnMac == "1" ]] ; then
342 MountOSXESP
343 else
344 InstallDir="/"
345 fi
346 echo "Installing rEFInd to the partition mounted at '$InstallDir'"
347 Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
348 CopyRefindFiles
349 if [[ $InstallToEspOnMac == "1" ]] ; then
350 bless --mount $InstallDir --setBoot --file $InstallDir/$TargetDir/$Refind
351 elif [[ $TargetDir != "/EFI/BOOT" ]] ; then
352 bless --setBoot --folder $InstallDir/$TargetDir --file $InstallDir/$TargetDir/$Refind
353 fi
354 if [[ $? != 0 ]] ; then
355 Problems=1
356 fi
357 if [[ -f /Library/StartupItems/rEFItBlesser || -d /Library/StartupItems/rEFItBlesser ]] ; then
358 echo
359 echo "/Library/StartupItems/rEFItBlesser found!"
360 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
361 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
362 read YesNo
363 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
364 echo "Deleting /Library/StartupItems/rEFItBlesser..."
365 rm -r /Library/StartupItems/rEFItBlesser
366 else
367 echo "Not deleting rEFItBlesser."
368 fi
369 fi
370 echo
371 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
372 echo "bless status with 'bless --info', since this is known to cause disk corruption"
373 echo "on some systems!!"
374 echo
375 } # InstallOnOSX()
376
377
378 #
379 # Now a series of Linux support functions....
380 #
381
382 # Check for evidence that we're running in Secure Boot mode. If so, and if
383 # appropriate options haven't been set, warn the user and offer to abort.
384 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
385 # or --localkeys option, warn the user and offer to abort.
386 CheckSecureBoot() {
387 VarFile=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
388 if [[ -n $VarFile && $TargetDir != '/EFI/BOOT' && $ShimSource == "none" ]] ; then
389 echo ""
390 echo "CAUTION: The computer seems to have been booted with Secure Boot active, but"
391 echo "you haven't specified a valid shim.efi file source. The resulting installation"
392 echo "will not boot unless you disable Secure Boot. You may continue, but you should"
393 echo "consider using --shim to specify a working shim.efi file. You can read more"
394 echo "about this topic at http://www.rodsbooks.com/refind/secureboot.html."
395 echo ""
396 echo -n "Do you want to proceed with installation (Y/N)? "
397 read ContYN
398 if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
399 echo "OK; continuing with the installation..."
400 else
401 exit 0
402 fi
403 fi
404
405 if [[ $ShimSource != "none" && ! -n $VarFile ]] ; then
406 echo ""
407 echo "You've specified installing using a shim.efi file, but your computer does not"
408 echo "appear to be running in Secure Boot mode. Although installing in this way"
409 echo "should work, it's unnecessarily complex. You may continue, but unless you"
410 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
411 echo "--shim option. You can read more about this topic at"
412 echo "http://www.rodsbooks.com/refind/secureboot.html."
413 echo ""
414 echo -n "Do you want to proceed with installation (Y/N)? "
415 read ContYN
416 if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
417 echo "OK; continuing with the installation..."
418 else
419 exit 0
420 fi
421 fi
422
423 if [[ $LocalKeys != 0 && ! -n $VarFile ]] ; then
424 echo ""
425 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
426 echo "but your computer does not appear to be running in Secure Boot mode. The"
427 echo "keys you generate will be useless unless you enable Secure Boot. You may"
428 echo "proceed with this installation, but before you do so, you may want to read"
429 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
430 echo ""
431 echo -n "Do you want to proceed with installation (Y/N)? "
432 read ContYN
433 if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
434 echo "OK; continuing with the installation..."
435 else
436 exit 0
437 fi
438 fi
439
440 } # CheckSecureBoot()
441
442 # Check for the presence of locally-generated keys from a previous installation in
443 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
444 # openssl.
445 GenerateKeys() {
446 PrivateKey=$EtcKeysDir/$LocalKeysBase.key
447 CertKey=$EtcKeysDir/$LocalKeysBase.crt
448 DerKey=$EtcKeysDir/$LocalKeysBase.cer
449 OpenSSL=`which openssl 2> /dev/null`
450
451 # Do the work only if one or more of the necessary keys is missing
452 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
453 # is also missing, this will fail. This could be improved.
454 if [[ ! -f $PrivateKey || ! -f $CertKey || ! -f $DerKey ]] ; then
455 echo "Generating a fresh set of local keys...."
456 mkdir -p $EtcKeysDir
457 chmod 0700 $EtcKeysDir
458 if [[ ! -x $OpenSSL ]] ; then
459 echo "Can't find openssl, which is required to create your private signing keys!"
460 echo "Aborting!"
461 exit 1
462 fi
463 if [[ -f $PrivateKey ]] ; then
464 echo "Backing up existing $PrivateKey"
465 cp -f $PrivateKey $PrivateKey.backup 2> /dev/null
466 fi
467 if [[ -f $CertKey ]] ; then
468 echo "Backing up existing $CertKey"
469 cp -f $CertKey $CertKey.backup 2> /dev/null
470 fi
471 if [[ -f $DerKey ]] ; then
472 echo "Backing up existing $DerKey"
473 cp -f $DerKey $DerKey.backup 2> /dev/null
474 fi
475 $OpenSSL req -new -x509 -newkey rsa:2048 -keyout $PrivateKey -out $CertKey \
476 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
477 $OpenSSL x509 -in $CertKey -out $DerKey -outform DER
478 chmod 0600 $PrivateKey
479 else
480 echo "Using existing local keys...."
481 fi
482 }
483
484 # Sign a single binary. Requires parameters:
485 # $1 = source file
486 # $2 = destination file
487 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
488 # appropriately.
489 # Aborts script on error
490 SignOneBinary() {
491 $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
492 if [[ $? != 0 ]] ; then
493 echo "Problem signing the binary $1! Aborting!"
494 exit 1
495 fi
496 }
497
498 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
499 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
500 # not, try to generate new keys and store them in $EtcKeysDir.
501 ReSignBinaries() {
502 SBSign=`which sbsign 2> /dev/null`
503 echo "Found sbsign at $SBSign"
504 TempDir="/tmp/refind_local"
505 if [[ ! -x $SBSign ]] ; then
506 echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
507 echo "Aborting!"
508 exit 1
509 fi
510 GenerateKeys
511 mkdir -p $TempDir/drivers_x64
512 cp $RefindDir/refind.conf-sample $TempDir 2> /dev/null
513 cp $ThisDir/refind.conf-sample $TempDir 2> /dev/null
514 cp $RefindDir/refind_ia32.efi $TempDir
515 cp -a $RefindDir/drivers_ia32 $TempDir 2> /dev/null
516 cp -a $ThisDir/drivers_ia32 $TempDir 2> /dev/null
517 SignOneBinary $RefindDir/refind_x64.efi $ThisDir/refind_x64.efi
518 for Driver in `ls $RefindDir/drivers_x64/*.efi $ThisDir/drivers_x64/*.efi 2> /dev/null` ; do
519 TempName=`basename $Driver`
520 SignOneBinary $Driver $TempDir/drivers_x64/$TempName
521 done
522 RefindDir=$TempDir
523 DeleteRefindDir=1
524 }
525
526 # Identifies the ESP's location (/boot or /boot/efi); aborts if
527 # the ESP isn't mounted at either location.
528 # Sets InstallDir to the ESP mount point.
529 FindLinuxESP() {
530 EspLine=`df /boot/efi | grep boot`
531 InstallDir=`echo $EspLine | cut -d " " -f 6`
532 EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
533 if [[ $EspFilesystem != 'vfat' ]] ; then
534 echo "/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be mounted at"
535 echo "/boot or /boot/efi and it must be VFAT! Aborting!"
536 exit 1
537 fi
538 echo "ESP was found at $InstallDir using $EspFilesystem"
539 } # MountLinuxESP
540
541 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
542 # If this fails, sets Problems=1
543 AddBootEntry() {
544 InstallIt="0"
545 Efibootmgr=`which efibootmgr 2> /dev/null`
546 if [[ $Efibootmgr ]] ; then
547 modprobe efivars &> /dev/null
548 InstallDisk=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
549 PartNum=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
550 EntryFilename=$TargetDir/$Refind
551 EfiEntryFilename=`echo ${EntryFilename//\//\\\}`
552 EfiEntryFilename2=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
553 ExistingEntry=`$Efibootmgr -v | grep $EfiEntryFilename2`
554 # NOTE: Below protects against duplicate entries, but only for non-Secure Boot
555 # installations.
556 # TODO: Improve to detect & protect against duplicating a Secure Boot entry.
557 if [[ $ExistingEntry && $ShimSource == "none" ]] ; then
558 ExistingEntryBootNum=`echo $ExistingEntry | cut -c 5-8`
559 FirstBoot=`$Efibootmgr | grep BootOrder | cut -c 12-15`
560 if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
561 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
562 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
563 echo "manager. If this is NOT what you want, you should use efibootmgr to"
564 echo "manually adjust your EFI's boot order."
565 $Efibootmgr -b $ExistingEntryBootNum -B &> /dev/null
566 InstallIt="1"
567 fi
568 else
569 InstallIt="1"
570 fi
571 if [[ $InstallIt == "1" ]] ; then
572 echo "Installing it!"
573 $Efibootmgr -c -l $EfiEntryFilename -L rEFInd -d $InstallDisk -p $PartNum &> /dev/null
574 if [[ $? != 0 ]] ; then
575 EfibootmgrProblems=1
576 Problems=1
577 fi
578 fi
579 else
580 EfibootmgrProblems=1
581 Problems=1
582 fi
583 if [[ $EfibootmgrProblems ]] ; then
584 echo
585 echo "ALERT: There were problems running the efibootmgr program! You may need to"
586 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
587 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
588 echo
589 fi
590 } # AddBootEntry()
591
592 # Create a minimal/sample refind_linux.conf file in /boot.
593 GenerateRefindLinuxConf() {
594 if [[ ! -f $RLConfFile ]] ; then
595 if [[ -f /etc/default/grub ]] ; then
596 # We want the default options used by the distribution, stored here....
597 source /etc/default/grub
598 fi
599 RootFS=`df / | grep dev | cut -f 1 -d " "`
600 StartOfDevname=`echo $RootFS | cut -b 1-7`
601 if [[ $StartOfDevname == "/dev/sd" || $StartOfDevName == "/dev/hd" ]] ; then
602 # Identify root filesystem by UUID rather than by device node, if possible
603 Uuid=`blkid -o export $RootFS 2> /dev/null | grep UUID=`
604 if [[ -n $Uuid ]] ; then
605 RootFS=$Uuid
606 fi
607 fi
608 DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
609 echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
610 echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
611 echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
612 fi
613 }
614
615 # Controls rEFInd installation under Linux.
616 # Sets Problems=1 if something goes wrong.
617 InstallOnLinux() {
618 echo "Installing rEFInd on Linux...."
619 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
620 MountDefaultTarget
621 else
622 FindLinuxESP
623 fi
624 CpuType=`uname -m`
625 if [[ $CpuType == 'x86_64' ]] ; then
626 Platform="EFI64"
627 if [[ $LocalKeys == 1 ]] ; then
628 ReSignBinaries
629 fi
630 elif [[ $CpuType == 'i386' || $CpuType == 'i486' || $CpuType == 'i586' || $CpuType == 'i686' ]] ; then
631 if [[ $ShimSource != "none" && $TargetDir != "/BOOT/EFI" ]] ; then
632 echo ""
633 echo "CAUTION: Neither rEFInd nor shim currently supports 32-bit systems, so you"
634 echo "should not use the --shim option to install on such systems. Aborting!"
635 echo ""
636 exit 1
637 fi
638 Platform="EFI32"
639 echo
640 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
641 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
642 echo "on a 64-bit computer, you should manually install the 64-bit version of"
643 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
644 echo "you're positive you want to continue with this installation, answer 'Y'"
645 echo "to the following question..."
646 echo
647 echo -n "Are you sure you want to continue (Y/N)? "
648 read ContYN
649 if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
650 echo "OK; continuing with the installation..."
651 else
652 exit 0
653 fi
654 else
655 echo "Unknown CPU type '$CpuType'; aborting!"
656 exit 1
657 fi
658 CheckSecureBoot
659 CopyRefindFiles
660 if [[ $TargetDir != "/EFI/BOOT" ]] ; then
661 AddBootEntry
662 GenerateRefindLinuxConf
663 fi
664 } # InstallOnLinux()
665
666 #
667 # The main part of the script. Sets a few environment variables,
668 # performs a few startup checks, and then calls functions to
669 # install under OS X or Linux, depending on the detected platform.
670 #
671
672 OSName=`uname -s`
673 GetParams $@
674 ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
675 RefindDir="$ThisDir/refind"
676 ThisScript="$ThisDir/`basename $0`"
677 if [[ `whoami` != "root" ]] ; then
678 echo "Not running as root; attempting to elevate privileges via sudo...."
679 sudo $ThisScript "$@"
680 if [[ $? != 0 ]] ; then
681 echo "This script must be run as root (or using sudo). Exiting!"
682 exit 1
683 else
684 exit 0
685 fi
686 fi
687 CheckForFiles
688 if [[ $OSName == 'Darwin' ]] ; then
689 if [[ $ShimSource != "none" ]] ; then
690 echo "The --shim option is not supported on OS X! Exiting!"
691 exit 1
692 fi
693 if [[ $LocalKeys != 0 ]] ; then
694 echo "The --localkeys option is not supported on OS X! Exiting!"
695 exit 1
696 fi
697 InstallOnOSX $1
698 elif [[ $OSName == 'Linux' ]] ; then
699 InstallOnLinux
700 else
701 echo "Running on unknown OS; aborting!"
702 fi
703
704 if [[ $Problems ]] ; then
705 echo
706 echo "ALERT:"
707 echo "Installation has completed, but problems were detected. Review the output for"
708 echo "error messages and take corrective measures as necessary. You may need to"
709 echo "re-run this script or install manually before rEFInd will work."
710 echo
711 else
712 echo
713 echo "Installation has completed successfully."
714 echo
715 fi
716
717 if [[ $UnmountEsp ]] ; then
718 echo "Unmounting install dir"
719 umount $InstallDir
720 fi
721
722 if [[ $InstallDir == /tmp/refind_install ]] ; then
723 # sleep 5
724 rmdir $InstallDir
725 fi