]>
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
14 # device (/dev/sdd1 or whatever) without registering with
16 # "--drivers" to install drivers along with regular files
18 # The "esp" option is valid only on Mac OS X; it causes
19 # installation to the EFI System Partition (ESP) rather than
20 # to the current OS X boot partition. Under Linux, this script
21 # installs to the ESP by default.
23 # This program is copyright (c) 2012 by Roderick W. Smith
24 # It is released under the terms of the GNU GPL, version 3,
25 # a copy of which should be included in the file COPYING.txt.
29 # 0.5.1 -- Added --shim option
30 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
31 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
32 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
33 # 0.4.1 -- Added check for rEFItBlesser in OS X
34 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
35 # 0.3.2.1 -- Check for presence of source files; aborts if not present
36 # 0.3.2 -- Initial version
38 # Note: install.sh version numbers match those of the rEFInd package
39 # with which they first appeared.
42 EtcKeysDir
=/etc
/refind.d
/keys
43 LocalKeysBase
="refind_local"
45 TargetX64
="refind_x64.efi"
46 TargetIA32
="refind_ia32.efi"
51 # Functions used by both OS X and Linux....
57 while [[ $# -gt 0 ]]; do
59 --esp |
--ESP) InstallToEspOnMac
=1
61 --usedefault) TargetDir
=/EFI
/BOOT
63 TargetX64
="bootx64.efi"
64 TargetIA32
="bootia32.efi"
70 --drivers) InstallDrivers
=1
72 --localkeys) LocalKeys
=1
74 * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--drivers] "
75 echo " [--localkeys] [--shim {shim-filename}]"
81 if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then
82 echo "You may use --esp OR --usedefault, but not both! Aborting!"
88 # Abort if the rEFInd files can't be found.
89 # Also sets $ConfFile to point to the configuration file,
90 # $IconsDir to point to the icons directory, and
91 # $ShimSource to the source of the shim.efi file (if necessary).
93 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
94 # is found, even on the wrong platform. This is because the platform
95 # hasn't yet been determined. This could obviously be improved, but it
96 # would mean restructuring lots more code....
97 if [[ ! -f $RefindDir/refind_ia32.efi
&& ! -f $RefindDir/refind_x64.efi
]] ; then
98 echo "The rEFInd binary file is missing! Aborting installation!"
102 if [[ -f $RefindDir/refind.conf-sample
]] ; then
103 ConfFile
=$RefindDir/refind.conf-sample
104 elif [[ -f $ThisDir/refind.conf-sample
]] ; then
105 ConfFile
=$ThisDir/refind.conf-sample
107 echo "The sample configuration file is missing! Aborting installation!"
111 if [[ -d $RefindDir/icons
]] ; then
112 IconsDir
=$RefindDir/icons
113 elif [[ -d $ThisDir/icons
]] ; then
114 IconsDir
=$ThisDir/icons
116 echo "The icons directory is missing! Aborting installation!"
120 if [[ $ShimSource != "none" ]] ; then
121 if [[ -f $ShimSource ]] ; then
122 TargetX64
="grubx64.efi"
123 MokManagerSource
=`dirname $ShimSource`/MokManager.efi
125 echo "The specified shim file, $ShimSource, doesn't exist!"
126 echo "Aborting installation!"
132 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
133 # available) to target.
135 cp $ShimSource $InstallDir/$TargetDir/$TargetShim
136 if [[ $?
!= 0 ]] ; then
139 if [[ -f $MokManagerSource ]] ; then
140 cp $MokManagerSource $InstallDir/$TargetDir/
142 if [[ $?
!= 0 ]] ; then
147 # Copy the public keys to the installation medium
149 if [[ $LocalKeys == 1 ]] ; then
150 cp $EtcKeysDir/$LocalKeysBase.cer
$InstallDir/$TargetDir
151 cp $EtcKeysDir/$LocalKeysBase.crt
$InstallDir/$TargetDir
153 cp $ThisDir/refind.cer
$InstallDir/$TargetDir
154 cp $ThisDir/refind.crt
$InstallDir/$TargetDir
158 # Copy the rEFInd files to the ESP or OS X root partition.
159 # Sets Problems=1 if any critical commands fail.
161 mkdir
-p $InstallDir/$TargetDir &> /dev
/null
162 if [[ $TargetDir == '/EFI/BOOT' ]] ; then
163 cp $RefindDir/refind_ia32.efi
$InstallDir/$TargetDir/$TargetIA32 2> /dev
/null
164 if [[ $?
!= 0 ]] ; then
165 echo "Note: IA32 (x86) binary not installed!"
167 cp $RefindDir/refind_x64.efi
$InstallDir/$TargetDir/$TargetX64 2> /dev
/null
168 if [[ $?
!= 0 ]] ; then
171 if [[ $ShimSource != "none" ]] ; then
172 TargetShim
="bootx64.efi"
175 if [[ $InstallDrivers == 1 ]] ; then
176 cp -r $RefindDir/drivers_
* $InstallDir/$TargetDir/
180 elif [[ $Platform == 'EFI32' ]] ; then
181 cp $RefindDir/refind_ia32.efi
$InstallDir/$TargetDir/$TargetIA32
182 if [[ $?
!= 0 ]] ; then
185 if [[ $InstallDrivers == 1 ]] ; then
186 mkdir
-p $InstallDir/$TargetDir/drivers_ia32
187 cp -r $RefindDir/drivers_ia32
/*_ia32.efi
$InstallDir/$TargetDir/drivers_ia32
/
189 Refind
="refind_ia32.efi"
190 elif [[ $Platform == 'EFI64' ]] ; then
191 cp $RefindDir/refind_x64.efi
$InstallDir/$TargetDir/$TargetX64
192 if [[ $?
!= 0 ]] ; then
195 if [[ $InstallDrivers == 1 ]] ; then
196 mkdir
-p $InstallDir/$TargetDir/drivers_x64
197 cp -r $RefindDir/drivers_x64
/*_x64.efi
$InstallDir/$TargetDir/drivers_x64
/
199 Refind
="refind_x64.efi"
201 if [[ $ShimSource != "none" ]] ; then
202 TargetShim
=`basename $ShimSource`
205 if [[ $LocalKeys == 0 ]] ; then
206 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
208 cp $ThisDir/refind.cer
$EtcKeysDir
209 cp $ThisDir/refind.crt
$EtcKeysDir
213 echo "Unknown platform! Aborting!"
216 echo "Copied rEFInd binary files"
218 if [[ -d $InstallDir/$TargetDir/icons
]] ; then
219 rm -rf $InstallDir/$TargetDir/icons-backup
&> /dev
/null
220 mv -f $InstallDir/$TargetDir/icons
$InstallDir/$TargetDir/icons-backup
221 echo "Notice: Backed up existing icons directory as icons-backup."
223 cp -r $IconsDir $InstallDir/$TargetDir
224 if [[ $?
!= 0 ]] ; then
227 if [[ -f $InstallDir/$TargetDir/refind.conf
]] ; then
228 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
229 echo "to avoid overwriting your customizations."
231 cp -f $ConfFile $InstallDir/$TargetDir
232 if [[ $?
!= 0 ]] ; then
236 echo "Copying sample configuration file as refind.conf; edit this file to configure"
239 cp -f $ConfFile $InstallDir/$TargetDir/refind.conf
240 if [[ $?
!= 0 ]] ; then
244 if [[ $DeleteRefindDir == 1 ]] ; then
245 echo "Deleting the temporary directory $RefindDir"
248 } # CopyRefindFiles()
250 # Mount the partition the user specified with the --usedefault option
251 MountDefaultTarget
() {
252 InstallDir
=/tmp
/refind_install
254 if [[ $OSName == 'Darwin' ]] ; then
255 mount
-t msdos
$TargetPart $InstallDir
256 elif [[ $OSName == 'Linux' ]] ; then
257 mount
-t vfat
$TargetPart $InstallDir
259 if [[ $?
!= 0 ]] ; then
260 echo "Couldn't mount $TargetPart ! Aborting!"
265 } # MountDefaultTarget()
268 # A series of OS X support functions....
271 # Mount the ESP at /Volumes/ESP or determine its current mount
273 # Sets InstallDir to the ESP mount point
274 # Sets UnmountEsp if we mounted it
276 # Identify the ESP. Note: This returns the FIRST ESP found;
277 # if the system has multiple disks, this could be wrong!
278 Temp
=`diskutil list | grep " EFI "`
279 Esp
=/dev
/`echo $Temp | cut -f 5 -d ' '`
280 # If the ESP is mounted, use its current mount point....
281 Temp
=`df | grep $Esp`
282 InstallDir
=`echo $Temp | cut -f 6 -d ' '`
283 if [[ $InstallDir == '' ]] ; then
284 mkdir
/Volumes
/ESP
&> /dev
/null
285 mount
-t msdos
$Esp /Volumes
/ESP
286 if [[ $?
!= 0 ]] ; then
287 echo "Unable to mount ESP! Aborting!\n"
291 InstallDir
="/Volumes/ESP"
295 # Control the OS X installation.
296 # Sets Problems=1 if problems found during the installation.
298 echo "Installing rEFInd on OS X...."
299 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
301 elif [[ $InstallToEspOnMac == "1" ]] ; then
306 echo "Installing rEFInd to the partition mounted at '$InstallDir'"
307 Platform
=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
309 if [[ $InstallToEspOnMac == "1" ]] ; then
310 bless
--mount $InstallDir --setBoot --file $InstallDir/$TargetDir/$Refind
311 elif [[ $TargetDir != "/EFI/BOOT" ]] ; then
312 bless
--setBoot --folder $InstallDir/$TargetDir --file $InstallDir/$TargetDir/$Refind
314 if [[ $?
!= 0 ]] ; then
317 if [[ -f /Library
/StartupItems
/rEFItBlesser ||
-d /Library
/StartupItems
/rEFItBlesser
]] ; then
319 echo "/Library/StartupItems/rEFItBlesser found!"
320 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
321 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
323 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
324 echo "Deleting /Library/StartupItems/rEFItBlesser..."
325 rm -r /Library
/StartupItems
/rEFItBlesser
327 echo "Not deleting rEFItBlesser."
331 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
332 echo "bless status with 'bless --info', since this is known to cause disk corruption"
333 echo "on some systems!!"
339 # Now a series of Linux support functions....
342 # Check for evidence that we're running in Secure Boot mode. If so, and if
343 # appropriate options haven't been set, warn the user and offer to abort.
344 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
345 # or --localkeys option, warn the user and offer to abort.
347 VarFile
=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
348 if [[ -n $VarFile && $TargetDir != '/EFI/BOOT' && $ShimSource == "none" ]] ; then
350 echo "CAUTION: The computer seems to have been booted with Secure Boot active, but"
351 echo "you haven't specified a valid shim.efi file source. The resulting installation"
352 echo "will not boot unless you disable Secure Boot. You may continue, but you should"
353 echo "consider using --shim to specify a working shim.efi file. You can read more"
354 echo "about this topic at http://www.rodsbooks.com/refind/secureboot.html."
356 echo -n "Do you want to proceed with installation (Y/N)? "
358 if [[ $ContYN == "Y" ||
$ContYN == "y" ]] ; then
359 echo "OK; continuing with the installation..."
365 if [[ $ShimSource != "none" && ! -n $VarFile ]] ; then
367 echo "You've specified installing using a shim.efi file, but your computer does not"
368 echo "appear to be running in Secure Boot mode. Although installing in this way"
369 echo "should work, it's unnecessarily complex. You may continue, but unless you"
370 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
371 echo "--shim option. You can read more about this topic at"
372 echo "http://www.rodsbooks.com/refind/secureboot.html."
374 echo -n "Do you want to proceed with installation (Y/N)? "
376 if [[ $ContYN == "Y" ||
$ContYN == "y" ]] ; then
377 echo "OK; continuing with the installation..."
383 if [[ $LocalKeys != 0 && ! -n $VarFile ]] ; then
385 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
386 echo "but your computer does not appear to be running in Secure Boot mode. The"
387 echo "keys you generate will be useless unless you enable Secure Boot. You may"
388 echo "proceed with this installation, but before you do so, you may want to read"
389 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
391 echo -n "Do you want to proceed with installation (Y/N)? "
393 if [[ $ContYN == "Y" ||
$ContYN == "y" ]] ; then
394 echo "OK; continuing with the installation..."
400 } # CheckSecureBoot()
402 # Check for the presence of locally-generated keys from a previous installation in
403 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
406 PrivateKey
=$EtcKeysDir/$LocalKeysBase.key
407 CertKey
=$EtcKeysDir/$LocalKeysBase.crt
408 DerKey
=$EtcKeysDir/$LocalKeysBase.cer
409 OpenSSL
=`which openssl 2> /dev/null`
411 # Do the work only if one or more of the necessary keys is missing
412 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
413 # is also missing, this will fail. This could be improved.
414 if [[ ! -f $PrivateKey ||
! -f $CertKey ||
! -f $DerKey ]] ; then
415 echo "Generating a fresh set of local keys...."
417 chmod 0700 $EtcKeysDir
418 if [[ ! -x $OpenSSL ]] ; then
419 echo "Can't find openssl, which is required to create your private signing keys!"
423 if [[ -f $PrivateKey ]] ; then
424 echo "Backing up existing $PrivateKey"
425 cp -f $PrivateKey $PrivateKey.backup
2> /dev
/null
427 if [[ -f $CertKey ]] ; then
428 echo "Backing up existing $CertKey"
429 cp -f $CertKey $CertKey.backup
2> /dev
/null
431 if [[ -f $DerKey ]] ; then
432 echo "Backing up existing $DerKey"
433 cp -f $DerKey $DerKey.backup
2> /dev
/null
435 $OpenSSL req
-new -x509 -newkey rsa
:2048 -keyout $PrivateKey -out $CertKey \
436 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
437 $OpenSSL x509
-in $CertKey -out $DerKey -outform DER
438 chmod 0600 $PrivateKey
440 echo "Using existing local keys...."
444 # Sign a single binary. Requires parameters:
446 # $2 = destination file
447 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
449 # Aborts script on error
451 if [[ $UseSBSign == 1 ]] ; then
452 $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
453 if [[ $?
!= 0 ]] ; then
454 echo "Problem signing the binary $1! Aborting!"
458 echo "PESign code not yet written; aborting!"
463 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
464 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
465 # not, try to generate new keys and store them in $EtcKeysDir.
467 SBSign
=`which sbsign 2> /dev/null`
468 TempDir
="/tmp/refind_local"
469 if [[ ! -x $SBSign ]] ; then
470 echo "Can't find either sbsign or pesign; one of these is required to sign rEFInd"
471 echo "with your own keys! Aborting!"
475 mkdir
-p $TempDir/drivers_x64
476 cp $RefindDir/refind.conf-sample
$TempDir
477 cp $RefindDir/refind_ia32.efi
$TempDir
478 cp -a $RefindDir/drivers_ia32
$TempDir
479 SignOneBinary
$RefindDir/refind_x64.efi
$TempDir/refind_x64.efi
480 for Driver
in `ls $RefindDir/drivers_x64/*.efi` ; do
481 TempName
=`basename $Driver`
482 SignOneBinary
$Driver $TempDir/drivers_x64
/$TempName
488 # Identifies the ESP's location (/boot or /boot/efi); aborts if
489 # the ESP isn't mounted at either location.
490 # Sets InstallDir to the ESP mount point.
492 EspLine
=`df /boot/efi | grep boot`
493 InstallDir
=`echo $EspLine | cut -d " " -f 6`
494 EspFilesystem
=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
495 if [[ $EspFilesystem != 'vfat' ]] ; then
496 echo "/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be mounted at"
497 echo "/boot or /boot/efi and it must be VFAT! Aborting!"
500 echo "ESP was found at $InstallDir using $EspFilesystem"
503 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
504 # If this fails, sets Problems=1
507 Efibootmgr
=`which efibootmgr 2> /dev/null`
508 if [[ $Efibootmgr ]] ; then
509 modprobe efivars
&> /dev
/null
510 InstallDisk
=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
511 PartNum
=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
512 EntryFilename
=$TargetDir/$Refind
513 EfiEntryFilename
=`echo ${EntryFilename//\//\\\}`
514 EfiEntryFilename2
=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
515 ExistingEntry
=`$Efibootmgr -v | grep $EfiEntryFilename2`
516 # NOTE: Below protects against duplicate entries, but only for non-Secure Boot
518 # TODO: Improve to detect & protect against duplicating a Secure Boot entry.
519 if [[ $ExistingEntry && $ShimSource == "none" ]] ; then
520 ExistingEntryBootNum
=`echo $ExistingEntry | cut -c 5-8`
521 FirstBoot
=`$Efibootmgr | grep BootOrder | cut -c 12-15`
522 if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
523 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
524 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
525 echo "manager. If this is NOT what you want, you should use efibootmgr to"
526 echo "manually adjust your EFI's boot order."
527 $Efibootmgr -b $ExistingEntryBootNum -B &> /dev
/null
533 if [[ $InstallIt == "1" ]] ; then
534 echo "Installing it!"
535 $Efibootmgr -c -l $EfiEntryFilename -L rEFInd
-d $InstallDisk -p $PartNum &> /dev
/null
536 if [[ $?
!= 0 ]] ; then
545 if [[ $EfibootmgrProblems ]] ; then
547 echo "ALERT: There were problems running the efibootmgr program! You may need to"
548 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
549 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
554 # Controls rEFInd installation under Linux.
555 # Sets Problems=1 if something goes wrong.
557 echo "Installing rEFInd on Linux...."
558 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
564 if [[ $CpuType == 'x86_64' ]] ; then
566 if [[ $LocalKeys == 1 ]] ; then
569 elif [[ $CpuType == 'i386' ||
$CpuType == 'i486' ||
$CpuType == 'i586' ||
$CpuType == 'i686' ]] ; then
570 if [[ $ShimSource != "none" && $TargetDir != "/BOOT/EFI" ]] ; then
572 echo "CAUTION: Neither rEFInd nor shim currently supports 32-bit systems, so you"
573 echo "should not use the --shim option to install on such systems. Aborting!"
579 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
580 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
581 echo "on a 64-bit computer, you should manually install the 64-bit version of"
582 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
583 echo "you're positive you want to continue with this installation, answer 'Y'"
584 echo "to the following question..."
586 echo -n "Are you sure you want to continue (Y/N)? "
588 if [[ $ContYN == "Y" ||
$ContYN == "y" ]] ; then
589 echo "OK; continuing with the installation..."
594 echo "Unknown CPU type '$CpuType'; aborting!"
599 if [[ $TargetDir != "/EFI/BOOT" ]] ; then
605 # The main part of the script. Sets a few environment variables,
606 # performs a few startup checks, and then calls functions to
607 # install under OS X or Linux, depending on the detected platform.
612 ThisDir
="$( cd -P "$
( dirname "${BASH_SOURCE[0]}" )" && pwd )"
613 RefindDir
="$ThisDir/refind"
614 ThisScript
="$ThisDir/`basename $0`"
615 if [[ `whoami` != "root" ]] ; then
616 echo "Not running as root; attempting to elevate privileges via sudo...."
617 sudo
$ThisScript $1 $2 $3 $4 $5 $6
618 if [[ $?
!= 0 ]] ; then
619 echo "This script must be run as root (or using sudo). Exiting!"
626 if [[ $OSName == 'Darwin' ]] ; then
627 if [[ $ShimDir != "none" ]] ; then
628 echo "The --shim option is not supported on OS X! Exiting!"
631 if [[ $LocalKeys != 0 ]] ; then
632 echo "The --localkeys option is not supported on OS X! Exiting!"
636 elif [[ $OSName == 'Linux' ]] ; then
639 echo "Running on unknown OS; aborting!"
642 if [[ $Problems ]] ; then
645 echo "Installation has completed, but problems were detected. Review the output for"
646 echo "error messages and take corrective measures as necessary. You may need to"
647 echo "re-run this script or install manually before rEFInd will work."
651 echo "Installation has completed successfully."
655 if [[ $UnmountEsp ]] ; then
656 echo "Unmounting install dir"
660 if [[ $InstallDir == /tmp
/refind_install
]] ; then