]>
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 # "--root {dir}" to specify installation using the specified directory
16 # as the system's root
17 # "--alldrivers" to install all drivers along with regular files
18 # "--nodrivers" to suppress driver installation (default in Linux is
19 # driver used on /boot; --nodrivers is OS X default)
20 # "--shim {shimfile}" to install a shim.efi file for Secure Boot
21 # "--preloader" is synonymous with "--shim"
22 # "--localkeys" to re-sign x86-64 binaries with a locally-generated key
23 # "--yes" to assume a "yes" response to all prompts
25 # The "esp" option is valid only on Mac OS X; it causes
26 # installation to the EFI System Partition (ESP) rather than
27 # to the current OS X boot partition. Under Linux, this script
28 # installs to the ESP by default.
30 # This program is copyright (c) 2012 by Roderick W. Smith
31 # It is released under the terms of the GNU GPL, version 3,
32 # a copy of which should be included in the file COPYING.txt.
36 # 0.6.12 -- Added support for PreLoader as well as for shim
37 # 0.6.11 -- Improvements in script's ability to handle directories with spaces
39 # 0.6.9 -- Install gptsync on Macs
40 # 0.6.8 -- Bug fix: ESP scan now uses "uniq".
41 # 0.6.6 -- Bug fix: Upgrade drivers when installed to EFI/BOOT. Also enable
42 # copying shim.efi and MokManager.efi over themselves.
43 # 0.6.4 -- Copies ext2 driver rather than ext4 driver for ext2/3fs
44 # 0.6.3 -- Support for detecting rEFInd in EFI/BOOT and EFI/Microsoft/Boot
45 # directories & for installing to EFI/BOOT in BIOS mode
46 # 0.6.2-1 -- Added --yes option & tweaked key-copying for use with RPM install script
47 # 0.6.1 -- Added --root option; minor bug fixes
48 # 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option;
49 # changed default driver installation behavior in Linux to install
50 # the driver needed to read /boot (if available)
51 # 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
52 # 0.5.1.1 -- Fixed bug that caused script failure under OS X
53 # 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
55 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
56 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
57 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
58 # 0.4.1 -- Added check for rEFItBlesser in OS X
59 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
60 # 0.3.2.1 -- Check for presence of source files; aborts if not present
61 # 0.3.2 -- Initial version
63 # Note: install.sh version numbers match those of the rEFInd package
64 # with which they first appeared.
68 LocalKeysBase
="refind_local"
72 TargetX64
="refind_x64.efi"
73 TargetIA32
="refind_ia32.efi"
79 # Functions used by both OS X and Linux....
84 if [[ $OSName == "Linux" ]] ; then
85 # Install the driver required to read /boot, if it's available
90 while [[ $# -gt 0 ]]; do
92 --esp |
--ESP) InstallToEspOnMac
=1
94 --usedefault) TargetDir
=/EFI
/BOOT
96 TargetX64
="bootx64.efi"
97 TargetIA32
="bootia32.efi"
103 --localkeys) LocalKeys
=1
105 --shim |
--preloader) ShimSource
="$2"
106 ShimType
=`basename $ShimSource`
109 --drivers |
--alldrivers) InstallDrivers
="all"
111 --nodrivers) InstallDrivers
="none"
115 * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} ]"
116 echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]"
117 echo " [--localkeys] [--yes]"
123 if [[ $InstallToEspOnMac == 1 && "$TargetDir" == '/EFI/BOOT' ]] ; then
124 echo "You may use --esp OR --usedefault, but not both! Aborting!"
127 if [[ "$RootDir" != '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then
128 echo "You may use --usedefault OR --root, but not both! Aborting!"
131 if [[ "$RootDir" != '/' && $InstallToEspOnMac == 1 ]] ; then
132 echo "You may use --root OR --esp, but not both! Aborting!"
136 RLConfFile
="$RootDir/boot/refind_linux.conf"
137 EtcKeysDir
="$RootDir/etc/refind.d/keys"
140 # Get a yes/no response from the user and place it in the YesNo variable.
141 # If the AlwaysYes variable is set to 1, skip the user input and set "Y"
142 # in the YesNo variable.
144 if [[ $AlwaysYes == 1 ]] ; then
152 # Abort if the rEFInd files can't be found.
153 # Also sets $ConfFile to point to the configuration file,
154 # $IconsDir to point to the icons directory, and
155 # $ShimSource to the source of the shim.efi file (if necessary).
157 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
158 # is found, even on the wrong platform. This is because the platform
159 # hasn't yet been determined. This could obviously be improved, but it
160 # would mean restructuring lots more code....
161 if [[ ! -f "$RefindDir/refind_ia32.efi" && ! -f "$RefindDir/refind_x64.efi" ]] ; then
162 echo "The rEFInd binary file is missing! Aborting installation!"
166 if [[ -f "$RefindDir/refind.conf-sample" ]] ; then
167 ConfFile
="$RefindDir/refind.conf-sample"
168 elif [[ -f "$ThisDir/refind.conf-sample" ]] ; then
169 ConfFile
="$ThisDir/refind.conf-sample"
171 echo "The sample configuration file is missing! Aborting installation!"
175 if [[ -d "$RefindDir/icons" ]] ; then
176 IconsDir
="$RefindDir/icons"
177 elif [[ -d "$ThisDir/icons" ]] ; then
178 IconsDir
="$ThisDir/icons"
180 echo "The icons directory is missing! Aborting installation!"
184 if [[ "$ShimSource" != "none" ]] ; then
185 if [[ -f "$ShimSource" ]] ; then
186 if [[ $ShimType == "shimx64.efi" ||
$ShimType == "shim.efi" ]] ; then
187 TargetX64
="grubx64.efi"
188 MokManagerSource
=`dirname "$ShimSource"`/MokManager.efi
189 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
190 TargetX64
="loader.efi"
191 MokManagerSource
=`dirname "$ShimSource"`/HashTool.efi
193 echo "Unknown shim/PreBootloader filename: $ShimType!"
194 echo "Known filenames are shimx64.efi, shim.efi, and PreLoader.efi. Aborting!"
198 echo "The specified shim/PreBootloader file, $ShimSource, doesn't exist!"
199 echo "Aborting installation!"
205 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
206 # available) to target.
208 cp -fb "$ShimSource" "$InstallDir/$TargetDir/$TargetShim"
209 if [[ $?
!= 0 ]] ; then
212 if [[ -f "$MokManagerSource" ]] ; then
213 cp -fb "$MokManagerSource" "$InstallDir/$TargetDir/"
215 if [[ $?
!= 0 ]] ; then
220 # Copy the public keys to the installation medium
222 if [[ $LocalKeys == 1 ]] ; then
223 mkdir
-p "$InstallDir/$TargetDir/keys/"
224 cp "$EtcKeysDir/$LocalKeysBase.cer" "$InstallDir/$TargetDir/keys/"
225 cp "$EtcKeysDir/$LocalKeysBase.crt" "$InstallDir/$TargetDir/keys/"
229 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
230 # honoring the $InstallDrivers condition. Must be passed a suitable
231 # architecture code (ia32 or x64).
233 if [[ $InstallDrivers == "all" ]] ; then
234 mkdir
-p "$InstallDir/$TargetDir/drivers_$1"
235 cp "$ThisDir"/drivers_
$1/*_
$1.efi
"$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
236 cp "$RefindDir"/drivers_
$1/*_
$1.efi
"$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
237 elif [[ "$InstallDrivers" == "boot" && -x `which blkid` ]] ; then
238 BootPart
=`df /boot | grep dev | cut -f 1 -d " "`
239 BootFS
=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
242 ext2 | ext3
) DriverType
="ext2"
243 # Could use ext4, but that can create unwanted entries from symbolic
244 # links in / to /boot/vmlinuz if a separate /boot partition is used.
246 ext4
) DriverType
="ext4"
248 reiserfs
) DriverType
="reiserfs"
250 hfsplus
) DriverType
="hfs"
254 if [[ -n $BootFS ]] ; then
255 echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
256 mkdir
-p "$InstallDir/$TargetDir/drivers_$1"
257 cp "$ThisDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
258 cp "$RefindDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1"/ 2> /dev
/null
263 # Copy tools (currently only gptsync, and that only on Macs) to the EFI/tools
264 # directory on the ESP. Must be passed a suitable architecture code (ia32
267 mkdir
-p $InstallDir/EFI
/tools
268 if [[ $OSName == 'Darwin' ]] ; then
269 cp -f "$RefindDir/tools_$1/gptsync_$1.efi" "$InstallDir/EFI/tools/"
270 if [[ -f "$InstallDir/EFI/tools/gptsync.efi" ]] ; then
271 mv "$InstallDir/EFI/tools/gptsync.efi" "$InstallDir/EFI/tools/gptsync.efi-disabled"
272 echo "Found old gptsync.efi; disabling it by renaming it to gptsync.efi-disabled"
277 # Copy the rEFInd files to the ESP or OS X root partition.
278 # Sets Problems=1 if any critical commands fail.
280 mkdir
-p "$InstallDir/$TargetDir"
281 if [[ "$TargetDir" == '/EFI/BOOT' ]] ; then
282 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" 2> /dev
/null
283 if [[ $?
!= 0 ]] ; then
284 echo "Note: IA32 (x86) binary not installed!"
286 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64" 2> /dev
/null
287 if [[ $?
!= 0 ]] ; then
290 if [[ "$ShimSource" != "none" ]] ; then
291 TargetShim
="bootx64.efi"
294 if [[ $InstallDrivers == "all" ]] ; then
295 cp -r "$RefindDir"/drivers_
* "$InstallDir/$TargetDir/" 2> /dev
/null
296 cp -r "$ThisDir"/drivers_
* "$InstallDir/$TargetDir/" 2> /dev
/null
297 elif [[ $Upgrade == 1 ]] ; then
298 if [[ $Platform == 'EFI64' ]] ; then
308 elif [[ $Platform == 'EFI64' ||
$TargetDir == "/EFI/Microsoft/Boot" ]] ; then
309 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64"
310 if [[ $?
!= 0 ]] ; then
315 Refind
="refind_x64.efi"
317 if [[ "$ShimSource" != "none" ]] ; then
318 if [[ "$TargetShim" == "default" ]] ; then
319 TargetShim
=`basename "$ShimSource"`
323 if [[ $LocalKeys == 0 ]] ; then
324 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
325 mkdir
-p "$EtcKeysDir"
326 cp "$ThisDir/keys/refind.cer" "$EtcKeysDir" 2> /dev
/null
327 cp "$ThisDir/keys/refind.crt" "$EtcKeysDir" 2> /dev
/null
330 elif [[ $Platform == 'EFI32' ]] ; then
331 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32"
332 if [[ $?
!= 0 ]] ; then
337 Refind
="refind_ia32.efi"
339 echo "Unknown platform! Aborting!"
342 echo "Copied rEFInd binary files"
344 if [[ -d "$InstallDir/$TargetDir/icons" ]] ; then
345 rm -rf "$InstallDir/$TargetDir/icons-backup" &> /dev
/null
346 mv -f "$InstallDir/$TargetDir/icons" "$InstallDir/$TargetDir/icons-backup"
347 echo "Notice: Backed up existing icons directory as icons-backup."
349 cp -r "$IconsDir" "$InstallDir/$TargetDir"
350 if [[ $?
!= 0 ]] ; then
353 mkdir
-p "$InstallDir/$TargetDir/keys"
354 cp -rf "$ThisDir"/keys
/*.
[cd]er
"$InstallDir/$TargetDir/keys/" 2> /dev
/null
355 cp -rf "$EtcKeysDir"/*.
[cd]er
"$InstallDir/$TargetDir/keys/" 2> /dev
/null
356 if [[ -f "$InstallDir/$TargetDir/refind.conf" ]] ; then
357 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
358 echo "to avoid overwriting your customizations."
360 cp -f "$ConfFile" "$InstallDir/$TargetDir"
361 if [[ $?
!= 0 ]] ; then
365 echo "Copying sample configuration file as refind.conf; edit this file to configure"
368 cp -f "$ConfFile" "$InstallDir/$TargetDir/refind.conf"
369 if [[ $?
!= 0 ]] ; then
373 if [[ $DeleteRefindDir == 1 ]] ; then
374 echo "Deleting the temporary directory $RefindDir"
377 } # CopyRefindFiles()
379 # Mount the partition the user specified with the --usedefault option
380 MountDefaultTarget
() {
381 InstallDir
=/tmp
/refind_install
382 mkdir
-p "$InstallDir"
383 if [[ $OSName == 'Darwin' ]] ; then
384 mount
-t msdos
"$TargetPart" "$InstallDir"
385 elif [[ $OSName == 'Linux' ]] ; then
386 mount
-t vfat
"$TargetPart" "$InstallDir"
388 if [[ $?
!= 0 ]] ; then
389 echo "Couldn't mount $TargetPart ! Aborting!"
394 } # MountDefaultTarget()
397 # A series of OS X support functions....
400 # Mount the ESP at /Volumes/ESP or determine its current mount
402 # Sets InstallDir to the ESP mount point
403 # Sets UnmountEsp if we mounted it
405 # Identify the ESP. Note: This returns the FIRST ESP found;
406 # if the system has multiple disks, this could be wrong!
407 Temp
=`diskutil list | grep " EFI "`
408 Esp
=/dev
/`echo $Temp | cut -f 5 -d ' '`
409 # If the ESP is mounted, use its current mount point....
410 Temp
=`df | grep "$Esp"`
411 InstallDir
=`echo $Temp | cut -f 6 -d ' '`
412 if [[ "$InstallDir" == '' ]] ; then
413 mkdir
/Volumes
/ESP
&> /dev
/null
414 mount
-t msdos
"$Esp" /Volumes
/ESP
415 if [[ $?
!= 0 ]] ; then
416 echo "Unable to mount ESP! Aborting!\n"
420 InstallDir
="/Volumes/ESP"
424 # Control the OS X installation.
425 # Sets Problems=1 if problems found during the installation.
427 echo "Installing rEFInd on OS X...."
428 if [[ "$TargetDir" == "/EFI/BOOT" ]] ; then
430 elif [[ "$InstallToEspOnMac" == "1" ]] ; then
433 InstallDir
="$RootDir/"
435 echo "Installing rEFInd to the partition mounted at $InstallDir"
436 Platform
=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
438 if [[ $InstallToEspOnMac == "1" ]] ; then
439 bless
--mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind"
440 elif [[ "$TargetDir" != "/EFI/BOOT" ]] ; then
441 bless
--setBoot --folder "$InstallDir/$TargetDir" --file "$InstallDir/$TargetDir/$Refind"
443 if [[ $?
!= 0 ]] ; then
446 if [[ -f /Library
/StartupItems
/rEFItBlesser ||
-d /Library
/StartupItems
/rEFItBlesser
]] ; then
448 echo "/Library/StartupItems/rEFItBlesser found!"
449 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
450 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
452 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
453 echo "Deleting /Library/StartupItems/rEFItBlesser..."
454 rm -r /Library
/StartupItems
/rEFItBlesser
456 echo "Not deleting rEFItBlesser."
460 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
461 echo "bless status with 'bless --info', since this is known to cause disk corruption"
462 echo "on some systems!!"
468 # Now a series of Linux support functions....
471 # Check for evidence that we're running in Secure Boot mode. If so, and if
472 # appropriate options haven't been set, warn the user and offer to abort.
473 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
474 # or --localkeys option, warn the user and offer to abort.
476 # FIXME: Although I checked the presence (and lack thereof) of the
477 # /sys/firmware/efi/vars/SecureBoot* files on my Secure Boot test system
478 # before releasing this script, I've since found that they are at least
479 # sometimes present when Secure Boot is absent. This means that the first
480 # test can produce false alarms. A better test is highly desirable.
482 VarFile
=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
483 if [[ -n "$VarFile" && "$TargetDir" != '/EFI/BOOT' && "$ShimSource" == "none" ]] ; then
485 echo "CAUTION: Your computer appears to support Secure Boot, but you haven't"
486 echo "specified a valid shim.efi file source. If you've disabled Secure Boot and"
487 echo "intend to leave it disabled, this is fine; but if Secure Boot is active, the"
488 echo "resulting installation won't boot. You can read more about this topic at"
489 echo "http://www.rodsbooks.com/refind/secureboot.html."
491 echo -n "Do you want to proceed with installation (Y/N)? "
493 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
494 echo "OK; continuing with the installation..."
500 if [[ "$ShimSource" != "none" && ! -n "$VarFile" ]] ; then
502 echo "You've specified installing using a shim.efi file, but your computer does not"
503 echo "appear to be running in Secure Boot mode. Although installing in this way"
504 echo "should work, it's unnecessarily complex. You may continue, but unless you"
505 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
506 echo "--shim option. You can read more about this topic at"
507 echo "http://www.rodsbooks.com/refind/secureboot.html."
509 echo -n "Do you want to proceed with installation (Y/N)? "
511 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
512 echo "OK; continuing with the installation..."
518 if [[ $LocalKeys != 0 && ! -n "$VarFile" ]] ; then
520 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
521 echo "but your computer does not appear to be running in Secure Boot mode. The"
522 echo "keys you generate will be useless unless you enable Secure Boot. You may"
523 echo "proceed with this installation, but before you do so, you may want to read"
524 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
526 echo -n "Do you want to proceed with installation (Y/N)? "
528 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
529 echo "OK; continuing with the installation..."
535 } # CheckSecureBoot()
537 # Check for the presence of locally-generated keys from a previous installation in
538 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
541 PrivateKey
="$EtcKeysDir/$LocalKeysBase.key"
542 CertKey
="$EtcKeysDir/$LocalKeysBase.crt"
543 DerKey
="$EtcKeysDir/$LocalKeysBase.cer"
544 OpenSSL
=`which openssl 2> /dev/null`
546 # Do the work only if one or more of the necessary keys is missing
547 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
548 # is also missing, this will fail. This could be improved.
549 if [[ ! -f "$PrivateKey" ||
! -f "$CertKey" ||
! -f "$DerKey" ]] ; then
550 echo "Generating a fresh set of local keys...."
551 mkdir
-p "$EtcKeysDir"
552 chmod 0700 "$EtcKeysDir"
553 if [[ ! -x "$OpenSSL" ]] ; then
554 echo "Can't find openssl, which is required to create your private signing keys!"
558 if [[ -f "$PrivateKey" ]] ; then
559 echo "Backing up existing $PrivateKey"
560 cp -f "$PrivateKey" "$PrivateKey.backup" 2> /dev
/null
562 if [[ -f "$CertKey" ]] ; then
563 echo "Backing up existing $CertKey"
564 cp -f "$CertKey" "$CertKey.backup" 2> /dev
/null
566 if [[ -f "$DerKey" ]] ; then
567 echo "Backing up existing $DerKey"
568 cp -f "$DerKey" "$DerKey.backup" 2> /dev
/null
570 "$OpenSSL" req
-new -x509 -newkey rsa
:2048 -keyout "$PrivateKey" -out "$CertKey" \
571 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
572 "$OpenSSL" x509
-in "$CertKey" -out "$DerKey" -outform DER
573 chmod 0600 "$PrivateKey"
575 echo "Using existing local keys...."
579 # Sign a single binary. Requires parameters:
581 # $2 = destination file
582 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
584 # Aborts script on error
586 $SBSign --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1"
587 if [[ $?
!= 0 ]] ; then
588 echo "Problem signing the binary $1! Aborting!"
593 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
594 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
595 # not, try to generate new keys and store them in $EtcKeysDir.
597 SBSign
=`which sbsign 2> /dev/null`
598 echo "Found sbsign at $SBSign"
599 TempDir
="/tmp/refind_local"
600 if [[ ! -x "$SBSign" ]] ; then
601 echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
606 mkdir
-p "$TempDir/drivers_x64"
607 cp "$RefindDir/refind.conf-sample $TempDir" 2> /dev
/null
608 cp "$ThisDir/refind.conf-sample $TempDir" 2> /dev
/null
609 cp "$RefindDir/refind_ia32.efi $TempDir" 2> /dev
/null
610 cp -a "$RefindDir/drivers_ia32 $TempDir" 2> /dev
/null
611 cp -a "$ThisDir/drivers_ia32 $TempDir" 2> /dev
/null
612 SignOneBinary
"$RefindDir/refind_x64.efi" "$TempDir/refind_x64.efi"
614 IFS
=$
(echo -en "\n\b")
615 for Driver
in `ls "$RefindDir"/drivers_x64/*.efi "$ThisDir"/drivers_x64/*.efi 2> /dev/null` ; do
616 TempName
=`basename "$Driver"`
617 SignOneBinary
"$Driver" "$TempDir/drivers_x64/$TempName"
624 # Identifies the ESP's location (/boot or /boot/efi, or these locations under
625 # the directory specified by --root); aborts if the ESP isn't mounted at
627 # Sets InstallDir to the ESP mount point.
629 EspLine
=`df "$RootDir/boot/efi" 2> /dev/null | grep boot/efi`
630 if [[ ! -n "$EspLine" ]] ; then
631 EspLine
=`df "$RootDir"/boot | grep boot`
633 InstallDir
=`echo $EspLine | cut -d " " -f 6`
634 if [[ -n "$InstallDir" ]] ; then
635 EspFilesystem
=`grep "$InstallDir" /etc/mtab | uniq | cut -d " " -f 3`
637 echo "EspFilesystem is '$EspFilesystem'"
638 if [[ $EspFilesystem != 'vfat' ]] ; then
639 echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be"
640 echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
643 echo "ESP was found at $InstallDir using $EspFilesystem"
646 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
647 # If this fails, sets Problems=1
650 Efibootmgr
=`which efibootmgr 2> /dev/null`
651 if [[ "$Efibootmgr" ]] ; then
652 InstallDisk
=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
653 PartNum
=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
654 EntryFilename
="$TargetDir/$Refind"
655 EfiEntryFilename
=`echo ${EntryFilename//\//\\\}`
656 EfiEntryFilename2
=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
657 ExistingEntry
=`"$Efibootmgr" -v | grep -i "$EfiEntryFilename2"`
659 if [[ "$ExistingEntry" ]] ; then
660 ExistingEntryBootNum
=`echo "$ExistingEntry" | cut -c 5-8`
661 FirstBoot
=`"$Efibootmgr" | grep BootOrder | cut -c 12-15`
662 if [[ "$ExistingEntryBootNum" != "$FirstBoot" ]] ; then
663 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
664 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
665 echo "manager. If this is NOT what you want, you should use efibootmgr to"
666 echo "manually adjust your EFI's boot order."
667 "$Efibootmgr" -b $ExistingEntryBootNum -B &> /dev
/null
674 if [[ $InstallIt == "1" ]] ; then
675 echo "Installing it!"
676 "$Efibootmgr" -c -l "$EfiEntryFilename" -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev
/null
677 if [[ $?
!= 0 ]] ; then
683 else # efibootmgr not found
688 if [[ $EfibootmgrProblems ]] ; then
690 echo "ALERT: There were problems running the efibootmgr program! You may need to"
691 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
692 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
697 # Create a minimal/sample refind_linux.conf file in /boot.
698 GenerateRefindLinuxConf
() {
699 if [[ -f "$RLConfFile" ]] ; then
700 echo "Existing $RLConfFile found; not overwriting."
702 if [[ -f "$RootDir/etc/default/grub" ]] ; then
703 # We want the default options used by the distribution, stored here....
704 source "$RootDir/etc/default/grub"
706 RootFS
=`df "$RootDir" | grep dev | cut -f 1 -d " "`
707 StartOfDevname
=`echo "$RootFS" | cut -b 1-7`
708 if [[ "$StartOfDevname" == "/dev/sd" ||
"$StartOfDevName" == "/dev/hd" ]] ; then
709 # Identify root filesystem by UUID rather than by device node, if possible
710 Uuid
=`blkid -o export "$RootFS" 2> /dev/null | grep UUID=`
711 if [[ -n $Uuid ]] ; then
715 DefaultOptions
="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
716 echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
717 echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
718 echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
722 # Set varaibles for installation in EFI/BOOT directory
724 TargetDir
="/EFI/BOOT"
725 if [[ $ShimSource == "none" ]] ; then
726 TargetX64
="bootx64.efi"
727 TargetIA32
="bootia32.efi"
729 if [[ $ShimType == "shim.efi" ||
$ShimType == "shimx64.efi" ]] ; then
730 TargetX64
="grubx64.efi"
731 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
732 TargetX64
="loader.efi"
734 echo "Unknown shim/PreBootloader type: $ShimType"
738 TargetIA32
="bootia32.efi"
739 TargetShim
="bootx64.efi"
741 } # SetFilenamesForBoot()
743 # Set variables for installation in EFI/Microsoft/Boot directory
745 TargetDir
="/EFI/Microsoft/Boot"
746 if [[ $ShimSource == "none" ]] ; then
747 TargetX64
="bootmgfw.efi"
749 if [[ $ShimType == "shim.efi" ||
$ShimType == "shimx64.efi" ]] ; then
750 TargetX64
="grubx64.efi"
751 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
752 TargetX64
="loader.efi"
754 echo "Unknown shim/PreBootloader type: $ShimType"
758 TargetShim
="bootmgfw.efi"
762 # TargetDir defaults to /EFI/refind; however, this function adjusts it as follows:
763 # - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot,
764 # install to that directory under the suitable name; but DO NOT do this if
765 # refind.conf is also in /EFI/refind.
766 # - If booted in BIOS mode and the ESP lacks any other EFI files, install to
768 # - If booted in BIOS mode and there's no refind.conf file and there is a
769 # /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and
770 # install under that name, "hijacking" the Windows boot loader filename
771 DetermineTargetDir
() {
774 if [[ -f $InstallDir/EFI
/BOOT
/refind.conf
]] ; then
778 if [[ -f $InstallDir/EFI
/Microsoft
/Boot
/refind.conf
]] ; then
782 if [[ -f $InstallDir/EFI
/refind
/refind.conf
]] ; then
783 TargetDir
="/EFI/refind"
786 if [[ $Upgrade == 1 ]] ; then
787 echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it."
790 if [[ ! -d /sys
/firmware
/efi
&& $Upgrade == 0 ]] ; then # BIOS-mode
791 FoundEfiFiles
=`find "$InstallDir/EFI/BOOT" -name "*.efi" 2> /dev/null`
792 FoundConfFiles
=`find "$InstallDir" -name "refind\.conf" 2> /dev/null`
793 if [[ ! -n "$FoundConfFiles" && -f "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" ]] ; then
794 mv -n "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" "$InstallDir/EFI/Microsoft" &> /dev
/null
796 echo "Running in BIOS mode with a suspected Windows installation; moving boot loader"
797 echo "files so as to install to $InstallDir$TargetDir."
798 elif [[ ! -n "$FoundEfiFiles" ]] ; then # In BIOS mode and no default loader; install as default loader
800 echo "Running in BIOS mode with no existing default boot loader; installing to"
801 echo $InstallDir$TargetDir
803 echo "Running in BIOS mode with an existing default boot loader; backing it up and"
804 echo "installing rEFInd in its place."
805 if [[ -d "$InstallDir/EFI/BOOT-rEFIndBackup" ]] ; then
807 echo "Caution: An existing backup of a default boot loader exists! If the current"
808 echo "default boot loader and the backup are different boot loaders, the current"
809 echo "one will become inaccessible."
811 echo -n "Do you want to proceed with installation (Y/N)? "
813 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
814 echo "OK; continuing with the installation..."
819 mv -n "$InstallDir/EFI/BOOT" "$InstallDir/EFI/BOOT-rEFIndBackup"
823 } # DetermineTargetDir()
825 # Controls rEFInd installation under Linux.
826 # Sets Problems=1 if something goes wrong.
828 echo "Installing rEFInd on Linux...."
829 modprobe efivars
&> /dev
/null
830 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
837 if [[ $CpuType == 'x86_64' ]] ; then
839 elif [[ ($CpuType == 'i386' ||
$CpuType == 'i486' ||
$CpuType == 'i586' ||
$CpuType == 'i686') ]] ; then
841 # If we're in EFI mode, do some sanity checks, and alert the user or even
842 # abort. Not in BIOS mode, though, since that could be used on an emergency
843 # disc to try to recover a troubled Linux installation.
844 if [[ -d /sys
/firmware
/efi
]] ; then
845 if [[ "$ShimSource" != "none" && "$TargetDir" != "/BOOT/EFI" ]] ; then
847 echo "CAUTION: shim does not currently supports 32-bit systems, so you should not"
848 echo "use the --shim option to install on such systems. Aborting!"
853 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
854 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
855 echo "on a 64-bit computer, you should manually install the 64-bit version of"
856 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
857 echo "you're positive you want to continue with this installation, answer 'Y'"
858 echo "to the following question..."
860 echo -n "Are you sure you want to continue (Y/N)? "
862 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
863 echo "OK; continuing with the installation..."
869 echo "Unknown CPU type '$CpuType'; aborting!"
873 if [[ $LocalKeys == 1 ]] ; then
879 if [[ "$TargetDir" != "/EFI/BOOT" && "$TargetDir" != "/EFI/Microsoft/Boot" ]] ; then
881 GenerateRefindLinuxConf
886 # The main part of the script. Sets a few environment variables,
887 # performs a few startup checks, and then calls functions to
888 # install under OS X or Linux, depending on the detected platform.
893 ThisDir
="$( cd -P "$
( dirname "${BASH_SOURCE[0]}" )" && pwd )"
894 RefindDir
="$ThisDir/refind"
895 ThisScript
="$ThisDir/`basename $0`"
896 if [[ `whoami` != "root" ]] ; then
897 echo "Not running as root; attempting to elevate privileges via sudo...."
898 sudo
"$ThisScript" "$@"
899 if [[ $?
!= 0 ]] ; then
900 echo "This script must be run as root (or using sudo). Exiting!"
907 if [[ $OSName == 'Darwin' ]] ; then
908 if [[ "$ShimSource" != "none" ]] ; then
909 echo "The --shim option is not supported on OS X! Exiting!"
912 if [[ "$LocalKeys" != 0 ]] ; then
913 echo "The --localkeys option is not supported on OS X! Exiting!"
917 elif [[ $OSName == 'Linux' ]] ; then
920 echo "Running on unknown OS; aborting!"
923 if [[ $Problems ]] ; then
926 echo "Installation has completed, but problems were detected. Review the output for"
927 echo "error messages and take corrective measures as necessary. You may need to"
928 echo "re-run this script or install manually before rEFInd will work."
932 echo "Installation has completed successfully."
936 if [[ $UnmountEsp ]] ; then
937 echo "Unmounting install dir"
941 if [[ "$InstallDir" == /tmp
/refind_install
]] ; then