]>
code.delx.au - refind/blob - install.sh
3 # Linux/MacOS X script to install rEFInd
7 # ./install.sh [options]
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
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.
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.
32 # 0.6.8 -- Bug fix: ESP scan now uses "uniq".
33 # 0.6.6 -- Bug fix: Upgrade drivers when installed to EFI/BOOT. Also enable
34 # copying shim.efi and MokManager.efi over themselves.
35 # 0.6.4 -- Copies ext2 driver rather than ext4 driver for ext2/3fs
36 # 0.6.3 -- Support for detecting rEFInd in EFI/BOOT and EFI/Microsoft/Boot
37 # directories & for installing to EFI/BOOT in BIOS mode
38 # 0.6.2-1 -- Added --yes option & tweaked key-copying for use with RPM install script
39 # 0.6.1 -- Added --root option; minor bug fixes
40 # 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option;
41 # changed default driver installation behavior in Linux to install
42 # the driver needed to read /boot (if available)
43 # 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
44 # 0.5.1.1 -- Fixed bug that caused script failure under OS X
45 # 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
47 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
48 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
49 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
50 # 0.4.1 -- Added check for rEFItBlesser in OS X
51 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
52 # 0.3.2.1 -- Check for presence of source files; aborts if not present
53 # 0.3.2 -- Initial version
55 # Note: install.sh version numbers match those of the rEFInd package
56 # with which they first appeared.
60 LocalKeysBase
="refind_local"
63 TargetX64
="refind_x64.efi"
64 TargetIA32
="refind_ia32.efi"
70 # Functions used by both OS X and Linux....
75 if [[ $OSName == "Linux" ]] ; then
76 # Install the driver required to read /boot, if it's available
81 while [[ $# -gt 0 ]]; do
83 --esp |
--ESP) InstallToEspOnMac
=1
85 --usedefault) TargetDir
=/EFI
/BOOT
87 TargetX64
="bootx64.efi"
88 TargetIA32
="bootia32.efi"
94 --localkeys) LocalKeys
=1
99 --drivers |
--alldrivers) InstallDrivers
="all"
101 --nodrivers) InstallDrivers
="none"
105 * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} ]"
106 echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]"
107 echo " [--localkeys] [--yes]"
113 if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then
114 echo "You may use --esp OR --usedefault, but not both! Aborting!"
117 if [[ $RootDir != '/' && $TargetDir == '/EFI/BOOT' ]] ; then
118 echo "You may use --usedefault OR --root, but not both! Aborting!"
121 if [[ $RootDir != '/' && $InstallToEspOnMac == 1 ]] ; then
122 echo "You may use --root OR --esp, but not both! Aborting!"
126 RLConfFile
="$RootDir/boot/refind_linux.conf"
127 EtcKeysDir
="$RootDir/etc/refind.d/keys"
130 # Get a yes/no response from the user and place it in the YesNo variable.
131 # If the AlwaysYes variable is set to 1, skip the user input and set "Y"
132 # in the YesNo variable.
134 if [[ $AlwaysYes == 1 ]] ; then
142 # Abort if the rEFInd files can't be found.
143 # Also sets $ConfFile to point to the configuration file,
144 # $IconsDir to point to the icons directory, and
145 # $ShimSource to the source of the shim.efi file (if necessary).
147 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
148 # is found, even on the wrong platform. This is because the platform
149 # hasn't yet been determined. This could obviously be improved, but it
150 # would mean restructuring lots more code....
151 if [[ ! -f $RefindDir/refind_ia32.efi
&& ! -f $RefindDir/refind_x64.efi
]] ; then
152 echo "The rEFInd binary file is missing! Aborting installation!"
156 if [[ -f $RefindDir/refind.conf-sample
]] ; then
157 ConfFile
=$RefindDir/refind.conf-sample
158 elif [[ -f $ThisDir/refind.conf-sample
]] ; then
159 ConfFile
=$ThisDir/refind.conf-sample
161 echo "The sample configuration file is missing! Aborting installation!"
165 if [[ -d $RefindDir/icons
]] ; then
166 IconsDir
=$RefindDir/icons
167 elif [[ -d $ThisDir/icons
]] ; then
168 IconsDir
=$ThisDir/icons
170 echo "The icons directory is missing! Aborting installation!"
174 if [[ $ShimSource != "none" ]] ; then
175 if [[ -f $ShimSource ]] ; then
176 TargetX64
="grubx64.efi"
177 MokManagerSource
=`dirname $ShimSource`/MokManager.efi
179 echo "The specified shim file, $ShimSource, doesn't exist!"
180 echo "Aborting installation!"
186 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
187 # available) to target.
189 cp -fb $ShimSource $InstallDir/$TargetDir/$TargetShim
190 if [[ $?
!= 0 ]] ; then
193 if [[ -f $MokManagerSource ]] ; then
194 cp -fb $MokManagerSource $InstallDir/$TargetDir/
196 if [[ $?
!= 0 ]] ; then
201 # Copy the public keys to the installation medium
203 if [[ $LocalKeys == 1 ]] ; then
204 mkdir
-p $InstallDir/$TargetDir/keys
/
205 cp $EtcKeysDir/$LocalKeysBase.cer
$InstallDir/$TargetDir/keys
/
206 cp $EtcKeysDir/$LocalKeysBase.crt
$InstallDir/$TargetDir/keys
/
208 # cp $ThisDir/refind.cer $InstallDir/$TargetDir/keys/
209 # cp $ThisDir/refind.crt $InstallDir/$TargetDir/keys/
213 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
214 # honoring the $InstallDrivers condition. Must be passed a suitable
215 # architecture code (ia32 or x64).
217 if [[ $InstallDrivers == "all" ]] ; then
218 mkdir
-p $InstallDir/$TargetDir/drivers_
$1
219 cp $RefindDir/drivers_
$1/*_
$1.efi
$InstallDir/$TargetDir/drivers_
$1/ 2> /dev
/null
220 cp $ThisDir/drivers_
$1/*_
$1.efi
$InstallDir/$TargetDir/drivers_
$1/ 2> /dev
/null
221 elif [[ $InstallDrivers == "boot" && -x `which blkid` ]] ; then
222 BootPart
=`df /boot | grep dev | cut -f 1 -d " "`
223 BootFS
=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
226 ext2 | ext3
) DriverType
="ext2"
227 # Could use ext4, but that can create unwanted entries from symbolic
228 # links in / to /boot/vmlinuz if a separate /boot partition is used.
230 ext4
) DriverType
="ext4"
232 reiserfs
) DriverType
="reiserfs"
234 hfsplus
) DriverType
="hfs"
238 if [[ -n $BootFS ]] ; then
239 echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
240 mkdir
-p $InstallDir/$TargetDir/drivers_
$1
241 cp $RefindDir/drivers_
$1/${DriverType}_
$1.efi
$InstallDir/$TargetDir/drivers_
$1/ 2> /dev
/null
242 cp $ThisDir/drivers_
$1/${DriverType}_
$1.efi
$InstallDir/$TargetDir/drivers_
$1/ 2> /dev
/null
247 # Copy the rEFInd files to the ESP or OS X root partition.
248 # Sets Problems=1 if any critical commands fail.
250 mkdir
-p $InstallDir/$TargetDir
251 if [[ $TargetDir == '/EFI/BOOT' ]] ; then
252 cp $RefindDir/refind_ia32.efi
$InstallDir/$TargetDir/$TargetIA32 2> /dev
/null
253 if [[ $?
!= 0 ]] ; then
254 echo "Note: IA32 (x86) binary not installed!"
256 cp $RefindDir/refind_x64.efi
$InstallDir/$TargetDir/$TargetX64 2> /dev
/null
257 if [[ $?
!= 0 ]] ; then
260 if [[ $ShimSource != "none" ]] ; then
261 TargetShim
="bootx64.efi"
264 if [[ $InstallDrivers == "all" ]] ; then
265 cp -r $RefindDir/drivers_
* $InstallDir/$TargetDir/ 2> /dev
/null
266 cp -r $ThisDir/drivers_
* $InstallDir/$TargetDir/ 2> /dev
/null
267 elif [[ $Upgrade == 1 ]] ; then
268 if [[ $Platform == 'EFI64' ]] ; then
276 elif [[ $Platform == 'EFI64' ||
$TargetDir == "/EFI/Microsoft/Boot" ]] ; then
277 cp $RefindDir/refind_x64.efi
$InstallDir/$TargetDir/$TargetX64
278 if [[ $?
!= 0 ]] ; then
282 Refind
="refind_x64.efi"
284 if [[ $ShimSource != "none" ]] ; then
285 if [[ $TargetShim == "default" ]] ; then
286 TargetShim
=`basename $ShimSource`
290 if [[ $LocalKeys == 0 ]] ; then
291 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
293 cp $ThisDir/keys
/refind.cer
$EtcKeysDir 2> /dev
/null
294 cp $ThisDir/keys
/refind.crt
$EtcKeysDir 2> /dev
/null
297 elif [[ $Platform == 'EFI32' ]] ; then
298 cp $RefindDir/refind_ia32.efi
$InstallDir/$TargetDir/$TargetIA32
299 if [[ $?
!= 0 ]] ; then
303 Refind
="refind_ia32.efi"
305 echo "Unknown platform! Aborting!"
308 echo "Copied rEFInd binary files"
310 if [[ -d $InstallDir/$TargetDir/icons
]] ; then
311 rm -rf $InstallDir/$TargetDir/icons-backup
&> /dev
/null
312 mv -f $InstallDir/$TargetDir/icons
$InstallDir/$TargetDir/icons-backup
313 echo "Notice: Backed up existing icons directory as icons-backup."
315 cp -r $IconsDir $InstallDir/$TargetDir
316 if [[ $?
!= 0 ]] ; then
319 mkdir
-p $InstallDir/$TargetDir/keys
320 cp -rf $ThisDir/keys
/*.
[cd]er
$InstallDir/$TargetDir/keys
/ 2> /dev
/null
321 cp -rf $EtcKeysDir/*.
[cd]er
$InstallDir/$TargetDir/keys
/ 2> /dev
/null
322 if [[ -f $InstallDir/$TargetDir/refind.conf
]] ; then
323 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
324 echo "to avoid overwriting your customizations."
326 cp -f $ConfFile $InstallDir/$TargetDir
327 if [[ $?
!= 0 ]] ; then
331 echo "Copying sample configuration file as refind.conf; edit this file to configure"
334 cp -f $ConfFile $InstallDir/$TargetDir/refind.conf
335 if [[ $?
!= 0 ]] ; then
339 if [[ $DeleteRefindDir == 1 ]] ; then
340 echo "Deleting the temporary directory $RefindDir"
343 } # CopyRefindFiles()
345 # Mount the partition the user specified with the --usedefault option
346 MountDefaultTarget
() {
347 InstallDir
=/tmp
/refind_install
349 if [[ $OSName == 'Darwin' ]] ; then
350 mount
-t msdos
$TargetPart $InstallDir
351 elif [[ $OSName == 'Linux' ]] ; then
352 mount
-t vfat
$TargetPart $InstallDir
354 if [[ $?
!= 0 ]] ; then
355 echo "Couldn't mount $TargetPart ! Aborting!"
360 } # MountDefaultTarget()
363 # A series of OS X support functions....
366 # Mount the ESP at /Volumes/ESP or determine its current mount
368 # Sets InstallDir to the ESP mount point
369 # Sets UnmountEsp if we mounted it
371 # Identify the ESP. Note: This returns the FIRST ESP found;
372 # if the system has multiple disks, this could be wrong!
373 Temp
=`diskutil list | grep " EFI "`
374 Esp
=/dev
/`echo $Temp | cut -f 5 -d ' '`
375 # If the ESP is mounted, use its current mount point....
376 Temp
=`df | grep $Esp`
377 InstallDir
=`echo $Temp | cut -f 6 -d ' '`
378 if [[ $InstallDir == '' ]] ; then
379 mkdir
/Volumes
/ESP
&> /dev
/null
380 mount
-t msdos
$Esp /Volumes
/ESP
381 if [[ $?
!= 0 ]] ; then
382 echo "Unable to mount ESP! Aborting!\n"
386 InstallDir
="/Volumes/ESP"
390 # Control the OS X installation.
391 # Sets Problems=1 if problems found during the installation.
393 echo "Installing rEFInd on OS X...."
394 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
396 elif [[ $InstallToEspOnMac == "1" ]] ; then
399 InstallDir
="$RootDir/"
401 echo "Installing rEFInd to the partition mounted at '$InstallDir'"
402 Platform
=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
404 if [[ $InstallToEspOnMac == "1" ]] ; then
405 bless
--mount $InstallDir --setBoot --file $InstallDir/$TargetDir/$Refind
406 elif [[ $TargetDir != "/EFI/BOOT" ]] ; then
407 bless
--setBoot --folder $InstallDir/$TargetDir --file $InstallDir/$TargetDir/$Refind
409 if [[ $?
!= 0 ]] ; then
412 if [[ -f /Library
/StartupItems
/rEFItBlesser ||
-d /Library
/StartupItems
/rEFItBlesser
]] ; then
414 echo "/Library/StartupItems/rEFItBlesser found!"
415 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
416 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
418 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
419 echo "Deleting /Library/StartupItems/rEFItBlesser..."
420 rm -r /Library
/StartupItems
/rEFItBlesser
422 echo "Not deleting rEFItBlesser."
426 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
427 echo "bless status with 'bless --info', since this is known to cause disk corruption"
428 echo "on some systems!!"
434 # Now a series of Linux support functions....
437 # Check for evidence that we're running in Secure Boot mode. If so, and if
438 # appropriate options haven't been set, warn the user and offer to abort.
439 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
440 # or --localkeys option, warn the user and offer to abort.
442 # FIXME: Although I checked the presence (and lack thereof) of the
443 # /sys/firmware/efi/vars/SecureBoot* files on my Secure Boot test system
444 # before releasing this script, I've since found that they are at least
445 # sometimes present when Secure Boot is absent. This means that the first
446 # test can produce false alarms. A better test is highly desirable.
448 VarFile
=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
449 if [[ -n $VarFile && $TargetDir != '/EFI/BOOT' && $ShimSource == "none" ]] ; then
451 echo "CAUTION: Your computer appears to support Secure Boot, but you haven't"
452 echo "specified a valid shim.efi file source. If you've disabled Secure Boot and"
453 echo "intend to leave it disabled, this is fine; but if Secure Boot is active, the"
454 echo "resulting installation won't boot. You can read more about this topic at"
455 echo "http://www.rodsbooks.com/refind/secureboot.html."
457 echo -n "Do you want to proceed with installation (Y/N)? "
459 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
460 echo "OK; continuing with the installation..."
466 if [[ $ShimSource != "none" && ! -n $VarFile ]] ; then
468 echo "You've specified installing using a shim.efi file, but your computer does not"
469 echo "appear to be running in Secure Boot mode. Although installing in this way"
470 echo "should work, it's unnecessarily complex. You may continue, but unless you"
471 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
472 echo "--shim option. You can read more about this topic at"
473 echo "http://www.rodsbooks.com/refind/secureboot.html."
475 echo -n "Do you want to proceed with installation (Y/N)? "
477 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
478 echo "OK; continuing with the installation..."
484 if [[ $LocalKeys != 0 && ! -n $VarFile ]] ; then
486 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
487 echo "but your computer does not appear to be running in Secure Boot mode. The"
488 echo "keys you generate will be useless unless you enable Secure Boot. You may"
489 echo "proceed with this installation, but before you do so, you may want to read"
490 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
492 echo -n "Do you want to proceed with installation (Y/N)? "
494 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
495 echo "OK; continuing with the installation..."
501 } # CheckSecureBoot()
503 # Check for the presence of locally-generated keys from a previous installation in
504 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
507 PrivateKey
=$EtcKeysDir/$LocalKeysBase.key
508 CertKey
=$EtcKeysDir/$LocalKeysBase.crt
509 DerKey
=$EtcKeysDir/$LocalKeysBase.cer
510 OpenSSL
=`which openssl 2> /dev/null`
512 # Do the work only if one or more of the necessary keys is missing
513 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
514 # is also missing, this will fail. This could be improved.
515 if [[ ! -f $PrivateKey ||
! -f $CertKey ||
! -f $DerKey ]] ; then
516 echo "Generating a fresh set of local keys...."
518 chmod 0700 $EtcKeysDir
519 if [[ ! -x $OpenSSL ]] ; then
520 echo "Can't find openssl, which is required to create your private signing keys!"
524 if [[ -f $PrivateKey ]] ; then
525 echo "Backing up existing $PrivateKey"
526 cp -f $PrivateKey $PrivateKey.backup
2> /dev
/null
528 if [[ -f $CertKey ]] ; then
529 echo "Backing up existing $CertKey"
530 cp -f $CertKey $CertKey.backup
2> /dev
/null
532 if [[ -f $DerKey ]] ; then
533 echo "Backing up existing $DerKey"
534 cp -f $DerKey $DerKey.backup
2> /dev
/null
536 $OpenSSL req
-new -x509 -newkey rsa
:2048 -keyout $PrivateKey -out $CertKey \
537 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
538 $OpenSSL x509
-in $CertKey -out $DerKey -outform DER
539 chmod 0600 $PrivateKey
541 echo "Using existing local keys...."
545 # Sign a single binary. Requires parameters:
547 # $2 = destination file
548 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
550 # Aborts script on error
552 $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
553 if [[ $?
!= 0 ]] ; then
554 echo "Problem signing the binary $1! Aborting!"
559 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
560 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
561 # not, try to generate new keys and store them in $EtcKeysDir.
563 SBSign
=`which sbsign 2> /dev/null`
564 echo "Found sbsign at $SBSign"
565 TempDir
="/tmp/refind_local"
566 if [[ ! -x $SBSign ]] ; then
567 echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
572 mkdir
-p $TempDir/drivers_x64
573 cp $RefindDir/refind.conf-sample
$TempDir 2> /dev
/null
574 cp $ThisDir/refind.conf-sample
$TempDir 2> /dev
/null
575 cp $RefindDir/refind_ia32.efi
$TempDir 2> /dev
/null
576 cp -a $RefindDir/drivers_ia32
$TempDir 2> /dev
/null
577 cp -a $ThisDir/drivers_ia32
$TempDir 2> /dev
/null
578 SignOneBinary
$RefindDir/refind_x64.efi
$TempDir/refind_x64.efi
579 for Driver
in `ls $RefindDir/drivers_x64/*.efi $ThisDir/drivers_x64/*.efi 2> /dev/null` ; do
580 TempName
=`basename $Driver`
581 SignOneBinary
$Driver $TempDir/drivers_x64
/$TempName
587 # Identifies the ESP's location (/boot or /boot/efi, or these locations under
588 # the directory specified by --root); aborts if the ESP isn't mounted at
590 # Sets InstallDir to the ESP mount point.
592 EspLine
=`df $RootDir/boot/efi 2> /dev/null | grep boot/efi`
593 if [[ ! -n $EspLine ]] ; then
594 EspLine
=`df $RootDir/boot | grep boot`
596 InstallDir
=`echo $EspLine | cut -d " " -f 6`
597 if [[ -n $InstallDir ]] ; then
598 EspFilesystem
=`grep $InstallDir /etc/mtab | uniq | cut -d " " -f 3`
600 if [[ $EspFilesystem != 'vfat' ]] ; then
601 echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be"
602 echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
605 echo "ESP was found at $InstallDir using $EspFilesystem"
608 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
609 # If this fails, sets Problems=1
612 Efibootmgr
=`which efibootmgr 2> /dev/null`
613 if [[ $Efibootmgr ]] ; then
614 InstallDisk
=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
615 PartNum
=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
616 EntryFilename
=$TargetDir/$Refind
617 EfiEntryFilename
=`echo ${EntryFilename//\//\\\}`
618 EfiEntryFilename2
=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
619 ExistingEntry
=`$Efibootmgr -v | grep -i $EfiEntryFilename2`
621 if [[ $ExistingEntry ]] ; then
622 ExistingEntryBootNum
=`echo $ExistingEntry | cut -c 5-8`
623 FirstBoot
=`$Efibootmgr | grep BootOrder | cut -c 12-15`
624 if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
625 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
626 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
627 echo "manager. If this is NOT what you want, you should use efibootmgr to"
628 echo "manually adjust your EFI's boot order."
629 $Efibootmgr -b $ExistingEntryBootNum -B &> /dev
/null
636 if [[ $InstallIt == "1" ]] ; then
637 echo "Installing it!"
638 $Efibootmgr -c -l $EfiEntryFilename -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev
/null
639 if [[ $?
!= 0 ]] ; then
645 else # efibootmgr not found
650 if [[ $EfibootmgrProblems ]] ; then
652 echo "ALERT: There were problems running the efibootmgr program! You may need to"
653 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
654 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
659 # Create a minimal/sample refind_linux.conf file in /boot.
660 GenerateRefindLinuxConf
() {
661 if [[ -f $RLConfFile ]] ; then
662 echo "Existing $RLConfFile found; not overwriting."
664 if [[ -f "$RootDir/etc/default/grub" ]] ; then
665 # We want the default options used by the distribution, stored here....
666 source "$RootDir/etc/default/grub"
668 RootFS
=`df $RootDir | grep dev | cut -f 1 -d " "`
669 StartOfDevname
=`echo $RootFS | cut -b 1-7`
670 if [[ $StartOfDevname == "/dev/sd" ||
$StartOfDevName == "/dev/hd" ]] ; then
671 # Identify root filesystem by UUID rather than by device node, if possible
672 Uuid
=`blkid -o export $RootFS 2> /dev/null | grep UUID=`
673 if [[ -n $Uuid ]] ; then
677 DefaultOptions
="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
678 echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
679 echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
680 echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
684 # Set varaibles for installation in EFI/BOOT directory
686 TargetDir
="/EFI/BOOT"
687 if [[ $ShimSource == "none" ]] ; then
688 TargetX64
="bootx64.efi"
689 TargetIA32
="bootia32.efi"
691 TargetX64
="grubx64.efi"
692 TargetIA32
="bootia32.efi"
693 TargetShim
="bootx64.efi"
695 } # SetFilenamesForBoot()
697 # Set variables for installation in EFI/Microsoft/Boot directory
699 TargetDir
="/EFI/Microsoft/Boot"
700 if [[ $ShimSource == "none" ]] ; then
701 TargetX64
="bootmgfw.efi"
703 TargetX64
="grubx64.efi"
704 TargetShim
="bootmgfw.efi"
708 # TargetDir defaults to /EFI/refind; however, this function adjusts it as follows:
709 # - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot,
710 # install to that directory under the suitable name; but DO NOT do this if
711 # refind.conf is also in /EFI/refind.
712 # - If booted in BIOS mode and the ESP lacks any other EFI files, install to
714 # - If booted in BIOS mode and there's no refind.conf file and there is a
715 # /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and
716 # install under that name, "hijacking" the Windows boot loader filename
717 DetermineTargetDir
() {
720 if [[ -f $InstallDir/EFI
/BOOT
/refind.conf
]] ; then
724 if [[ -f $InstallDir/EFI
/Microsoft
/Boot
/refind.conf
]] ; then
728 if [[ -f $InstallDir/EFI
/refind
/refind.conf
]] ; then
729 TargetDir
="/EFI/refind"
732 if [[ $Upgrade == 1 ]] ; then
733 echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it."
736 if [[ ! -d /sys
/firmware
/efi
&& $Upgrade == 0 ]] ; then # BIOS-mode
737 FoundEfiFiles
=`find $InstallDir/EFI/BOOT -name "*.efi" 2> /dev/null`
738 FoundConfFiles
=`find $InstallDir -name "refind\.conf" 2> /dev/null`
739 if [[ ! -n $FoundConfFiles && -f $InstallDir/EFI
/Microsoft
/Boot
/bootmgfw.efi
]] ; then
740 mv -n $InstallDir/EFI
/Microsoft
/Boot
/bootmgfw.efi
$InstallDir/EFI
/Microsoft
&> /dev
/null
742 echo "Running in BIOS mode with a suspected Windows installation; moving boot loader"
743 echo "files so as to install to $InstallDir$TargetDir."
744 elif [[ ! -n $FoundEfiFiles ]] ; then # In BIOS mode and no default loader; install as default loader
746 echo "Running in BIOS mode with no existing default boot loader; installing to"
747 echo $InstallDir$TargetDir
749 echo "Running in BIOS mode with an existing default boot loader; backing it up and"
750 echo "installing rEFInd in its place."
751 if [[ -d $InstallDir/EFI
/BOOT-rEFIndBackup
]] ; then
753 echo "Caution: An existing backup of a default boot loader exists! If the current"
754 echo "default boot loader and the backup are different boot loaders, the current"
755 echo "one will become inaccessible."
757 echo -n "Do you want to proceed with installation (Y/N)? "
759 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
760 echo "OK; continuing with the installation..."
765 mv -n $InstallDir/EFI
/BOOT
$InstallDir/EFI
/BOOT-rEFIndBackup
769 } # DetermineTargetDir()
771 # Controls rEFInd installation under Linux.
772 # Sets Problems=1 if something goes wrong.
774 echo "Installing rEFInd on Linux...."
775 modprobe efivars
&> /dev
/null
776 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
783 if [[ $CpuType == 'x86_64' ]] ; then
785 elif [[ ($CpuType == 'i386' ||
$CpuType == 'i486' ||
$CpuType == 'i586' ||
$CpuType == 'i686') ]] ; then
787 # If we're in EFI mode, do some sanity checks, and alert the user or even
788 # abort. Not in BIOS mode, though, since that could be used on an emergency
789 # disc to try to recover a troubled Linux installation.
790 if [[ -d /sys
/firmware
/efi
]] ; then
791 if [[ $ShimSource != "none" && $TargetDir != "/BOOT/EFI" ]] ; then
793 echo "CAUTION: Neither rEFInd nor shim currently supports 32-bit systems, so you"
794 echo "should not use the --shim option to install on such systems. Aborting!"
799 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
800 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
801 echo "on a 64-bit computer, you should manually install the 64-bit version of"
802 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
803 echo "you're positive you want to continue with this installation, answer 'Y'"
804 echo "to the following question..."
806 echo -n "Are you sure you want to continue (Y/N)? "
808 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
809 echo "OK; continuing with the installation..."
815 echo "Unknown CPU type '$CpuType'; aborting!"
819 if [[ $LocalKeys == 1 ]] ; then
825 if [[ $TargetDir != "/EFI/BOOT" && $TargetDir != "/EFI/Microsoft/Boot" ]] ; then
827 GenerateRefindLinuxConf
832 # The main part of the script. Sets a few environment variables,
833 # performs a few startup checks, and then calls functions to
834 # install under OS X or Linux, depending on the detected platform.
839 ThisDir
="$( cd -P "$
( dirname "${BASH_SOURCE[0]}" )" && pwd )"
840 RefindDir
="$ThisDir/refind"
841 ThisScript
="$ThisDir/`basename $0`"
842 if [[ `whoami` != "root" ]] ; then
843 echo "Not running as root; attempting to elevate privileges via sudo...."
844 sudo
$ThisScript "$@"
845 if [[ $?
!= 0 ]] ; then
846 echo "This script must be run as root (or using sudo). Exiting!"
853 if [[ $OSName == 'Darwin' ]] ; then
854 if [[ $ShimSource != "none" ]] ; then
855 echo "The --shim option is not supported on OS X! Exiting!"
858 if [[ $LocalKeys != 0 ]] ; then
859 echo "The --localkeys option is not supported on OS X! Exiting!"
863 elif [[ $OSName == 'Linux' ]] ; then
866 echo "Running on unknown OS; aborting!"
869 if [[ $Problems ]] ; then
872 echo "Installation has completed, but problems were detected. Review the output for"
873 echo "error messages and take corrective measures as necessary. You may need to"
874 echo "re-run this script or install manually before rEFInd will work."
878 echo "Installation has completed successfully."
882 if [[ $UnmountEsp ]] ; then
883 echo "Unmounting install dir"
887 if [[ $InstallDir == /tmp
/refind_install
]] ; then