]>
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 # "--ownhfs {devicefile}" to install to an HFS+ volume that's NOT currently
16 # an OS X boot volume.
17 # "--root {dir}" to specify installation using the specified directory
18 # as the system's root
19 # "--alldrivers" to install all drivers along with regular files
20 # "--nodrivers" to suppress driver installation (default in Linux is
21 # driver used on /boot; --nodrivers is OS X default)
22 # "--shim {shimfile}" to install a shim.efi file for Secure Boot
23 # "--preloader" is synonymous with "--shim"
24 # "--localkeys" to re-sign x86-64 binaries with a locally-generated key
25 # "--yes" to assume a "yes" response to all prompts
27 # The "esp" option is valid only on Mac OS X; it causes
28 # installation to the EFI System Partition (ESP) rather than
29 # to the current OS X boot partition. Under Linux, this script
30 # installs to the ESP by default.
32 # This program is copyright (c) 2012 by Roderick W. Smith
33 # It is released under the terms of the GNU GPL, version 3,
34 # a copy of which should be included in the file COPYING.txt.
38 # 0.7.6 -- Added --ownhfs {device-filename} option
39 # 0.7.5 -- Fixed bug when installing to ESP on recent versions of OS X
40 # 0.7.2 -- Fixed code that could be confused by use of autofs to mount the ESP
41 # 0.7.0 -- Added support for the new Btrfs driver
42 # 0.6.12 -- Added support for PreLoader as well as for shim
43 # 0.6.11 -- Improvements in script's ability to handle directories with spaces
45 # 0.6.9 -- Install gptsync on Macs
46 # 0.6.8 -- Bug fix: ESP scan now uses "uniq".
47 # 0.6.6 -- Bug fix: Upgrade drivers when installed to EFI/BOOT. Also enable
48 # copying shim.efi and MokManager.efi over themselves.
49 # 0.6.4 -- Copies ext2 driver rather than ext4 driver for ext2/3fs
50 # 0.6.3 -- Support for detecting rEFInd in EFI/BOOT and EFI/Microsoft/Boot
51 # directories & for installing to EFI/BOOT in BIOS mode
52 # 0.6.2-1 -- Added --yes option & tweaked key-copying for use with RPM install script
53 # 0.6.1 -- Added --root option; minor bug fixes
54 # 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option;
55 # changed default driver installation behavior in Linux to install
56 # the driver needed to read /boot (if available)
57 # 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
58 # 0.5.1.1 -- Fixed bug that caused script failure under OS X
59 # 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
61 # 0.5.0 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
62 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
63 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
64 # 0.4.1 -- Added check for rEFItBlesser in OS X
65 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
66 # 0.3.2.1 -- Check for presence of source files; aborts if not present
67 # 0.3.2 -- Initial version
69 # Note: install.sh version numbers match those of the rEFInd package
70 # with which they first appeared.
74 LocalKeysBase
="refind_local"
78 TargetX64
="refind_x64.efi"
79 TargetIA32
="refind_ia32.efi"
85 # Functions used by both OS X and Linux....
90 if [[ $OSName == "Linux" ]] ; then
91 # Install the driver required to read /boot, if it's available
96 while [[ $# -gt 0 ]]; do
98 --esp |
--ESP) InstallToEspOnMac
=1
102 TargetDir
=/System
/Library
/CoreServices
105 --usedefault) TargetDir
=/EFI
/BOOT
107 TargetX64
="bootx64.efi"
108 TargetIA32
="bootia32.efi"
114 --localkeys) LocalKeys
=1
116 --shim |
--preloader) ShimSource
="$2"
117 ShimType
=`basename $ShimSource`
120 --drivers |
--alldrivers) InstallDrivers
="all"
122 --nodrivers) InstallDrivers
="none"
126 * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} |"
127 echo " --ownhfs {device-file} ]"
128 echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]"
129 echo " [--localkeys] [--yes]"
135 if [[ $InstallToEspOnMac == 1 && "$TargetDir" == '/EFI/BOOT' ]] ; then
136 echo "You may use --esp OR --usedefault, but not both! Aborting!"
139 if [[ "$RootDir" != '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then
140 echo "You may use --usedefault OR --root, but not both! Aborting!"
143 if [[ "$RootDir" != '/' && $InstallToEspOnMac == 1 ]] ; then
144 echo "You may use --root OR --esp, but not both! Aborting!"
147 if [[ "$TargetDir" != '/System/Library/CoreServices' && "$OwnHfs" == '1' ]] ; then
148 echo "If you use --ownhfs, you may NOT use --usedefault! Aborting!"
152 RLConfFile
="$RootDir/boot/refind_linux.conf"
153 EtcKeysDir
="$RootDir/etc/refind.d/keys"
156 # Get a yes/no response from the user and place it in the YesNo variable.
157 # If the AlwaysYes variable is set to 1, skip the user input and set "Y"
158 # in the YesNo variable.
160 if [[ $AlwaysYes == 1 ]] ; then
168 # Abort if the rEFInd files can't be found.
169 # Also sets $ConfFile to point to the configuration file,
170 # $IconsDir to point to the icons directory, and
171 # $ShimSource to the source of the shim.efi file (if necessary).
173 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
174 # is found, even on the wrong platform. This is because the platform
175 # hasn't yet been determined. This could obviously be improved, but it
176 # would mean restructuring lots more code....
177 if [[ ! -f "$RefindDir/refind_ia32.efi" && ! -f "$RefindDir/refind_x64.efi" ]] ; then
178 echo "The rEFInd binary file is missing! Aborting installation!"
182 if [[ -f "$RefindDir/refind.conf-sample" ]] ; then
183 ConfFile
="$RefindDir/refind.conf-sample"
184 elif [[ -f "$ThisDir/refind.conf-sample" ]] ; then
185 ConfFile
="$ThisDir/refind.conf-sample"
187 echo "The sample configuration file is missing! Aborting installation!"
191 if [[ -d "$RefindDir/icons" ]] ; then
192 IconsDir
="$RefindDir/icons"
193 elif [[ -d "$ThisDir/icons" ]] ; then
194 IconsDir
="$ThisDir/icons"
196 echo "The icons directory is missing! Aborting installation!"
200 if [[ "$ShimSource" != "none" ]] ; then
201 if [[ -f "$ShimSource" ]] ; then
202 if [[ $ShimType == "shimx64.efi" ||
$ShimType == "shim.efi" ]] ; then
203 TargetX64
="grubx64.efi"
204 MokManagerSource
=`dirname "$ShimSource"`/MokManager.efi
205 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
206 TargetX64
="loader.efi"
207 MokManagerSource
=`dirname "$ShimSource"`/HashTool.efi
209 echo "Unknown shim/PreBootloader filename: $ShimType!"
210 echo "Known filenames are shimx64.efi, shim.efi, and PreLoader.efi. Aborting!"
214 echo "The specified shim/PreBootloader file, $ShimSource, doesn't exist!"
215 echo "Aborting installation!"
221 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
222 # available) to target.
224 cp -fb "$ShimSource" "$InstallDir/$TargetDir/$TargetShim"
225 if [[ $?
!= 0 ]] ; then
228 if [[ -f "$MokManagerSource" ]] ; then
229 cp -fb "$MokManagerSource" "$InstallDir/$TargetDir/"
231 if [[ $?
!= 0 ]] ; then
236 # Copy the public keys to the installation medium
238 if [[ $LocalKeys == 1 ]] ; then
239 mkdir
-p "$InstallDir/$TargetDir/keys/"
240 cp "$EtcKeysDir/$LocalKeysBase.cer" "$InstallDir/$TargetDir/keys/"
241 cp "$EtcKeysDir/$LocalKeysBase.crt" "$InstallDir/$TargetDir/keys/"
245 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
246 # honoring the $InstallDrivers condition. Must be passed a suitable
247 # architecture code (ia32 or x64).
249 if [[ $InstallDrivers == "all" ]] ; then
250 mkdir
-p "$InstallDir/$TargetDir/drivers_$1"
251 cp "$ThisDir"/drivers_
$1/*_
$1.efi
"$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
252 cp "$RefindDir"/drivers_
$1/*_
$1.efi
"$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
253 elif [[ "$InstallDrivers" == "boot" && -x `which blkid` ]] ; then
254 BootPart
=`df /boot | grep dev | cut -f 1 -d " "`
255 BootFS
=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
258 ext2 | ext3
) DriverType
="ext2"
259 # Could use ext4, but that can create unwanted entries from symbolic
260 # links in / to /boot/vmlinuz if a separate /boot partition is used.
262 ext4
) DriverType
="ext4"
264 reiserfs
) DriverType
="reiserfs"
266 btrfs
) DriverType
="btrfs"
268 hfsplus
) DriverType
="hfs"
272 if [[ -n $BootFS ]] ; then
273 echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
274 mkdir
-p "$InstallDir/$TargetDir/drivers_$1"
275 cp "$ThisDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1/" 2> /dev
/null
276 cp "$RefindDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1"/ 2> /dev
/null
281 # Copy tools (currently only gptsync, and that only on Macs) to the EFI/tools
282 # directory on the ESP. Must be passed a suitable architecture code (ia32
285 mkdir
-p $InstallDir/EFI
/tools
286 if [[ $OSName == 'Darwin' ]] ; then
287 cp -f "$RefindDir/tools_$1/gptsync_$1.efi" "$InstallDir/EFI/tools/"
288 if [[ -f "$InstallDir/EFI/tools/gptsync.efi" ]] ; then
289 mv "$InstallDir/EFI/tools/gptsync.efi" "$InstallDir/EFI/tools/gptsync.efi-disabled"
290 echo "Found old gptsync.efi; disabling it by renaming it to gptsync.efi-disabled"
295 # Copy the rEFInd files to the ESP or OS X root partition.
296 # Sets Problems=1 if any critical commands fail.
298 mkdir
-p "$InstallDir/$TargetDir"
299 if [[ "$TargetDir" == '/EFI/BOOT' ]] ; then
300 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" 2> /dev
/null
301 if [[ $?
!= 0 ]] ; then
302 echo "Note: IA32 (x86) binary not installed!"
304 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64" 2> /dev
/null
305 if [[ $?
!= 0 ]] ; then
308 if [[ "$ShimSource" != "none" ]] ; then
309 TargetShim
="bootx64.efi"
312 if [[ $InstallDrivers == "all" ]] ; then
313 cp -r "$RefindDir"/drivers_
* "$InstallDir/$TargetDir/" 2> /dev
/null
314 cp -r "$ThisDir"/drivers_
* "$InstallDir/$TargetDir/" 2> /dev
/null
315 elif [[ $Upgrade == 1 ]] ; then
316 if [[ $Platform == 'EFI64' ]] ; then
326 elif [[ $Platform == 'EFI64' ||
$TargetDir == "/EFI/Microsoft/Boot" ]] ; then
327 cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64"
328 if [[ $?
!= 0 ]] ; then
333 Refind
="refind_x64.efi"
335 if [[ "$ShimSource" != "none" ]] ; then
336 if [[ "$TargetShim" == "default" ]] ; then
337 TargetShim
=`basename "$ShimSource"`
341 if [[ $LocalKeys == 0 ]] ; then
342 echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
343 mkdir
-p "$EtcKeysDir"
344 cp "$ThisDir/keys/refind.cer" "$EtcKeysDir" 2> /dev
/null
345 cp "$ThisDir/keys/refind.crt" "$EtcKeysDir" 2> /dev
/null
348 if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then
349 SetupMacHfs
$TargetX64
351 elif [[ $Platform == 'EFI32' ]] ; then
352 cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32"
353 if [[ $?
!= 0 ]] ; then
358 Refind
="refind_ia32.efi"
359 if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then
360 SetupMacHfs
$TargetIA32
363 echo "Unknown platform! Aborting!"
366 echo "Copied rEFInd binary files"
368 if [[ -d "$InstallDir/$TargetDir/icons" ]] ; then
369 rm -rf "$InstallDir/$TargetDir/icons-backup" &> /dev
/null
370 mv -f "$InstallDir/$TargetDir/icons" "$InstallDir/$TargetDir/icons-backup"
371 echo "Notice: Backed up existing icons directory as icons-backup."
373 cp -r "$IconsDir" "$InstallDir/$TargetDir"
374 if [[ $?
!= 0 ]] ; then
377 mkdir
-p "$InstallDir/$TargetDir/keys"
378 cp -rf "$ThisDir"/keys
/*.
[cd]er
"$InstallDir/$TargetDir/keys/" 2> /dev
/null
379 cp -rf "$EtcKeysDir"/*.
[cd]er
"$InstallDir/$TargetDir/keys/" 2> /dev
/null
380 if [[ -f "$InstallDir/$TargetDir/refind.conf" ]] ; then
381 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
382 echo "to avoid overwriting your customizations."
384 cp -f "$ConfFile" "$InstallDir/$TargetDir"
385 if [[ $?
!= 0 ]] ; then
389 echo "Copying sample configuration file as refind.conf; edit this file to configure"
392 cp -f "$ConfFile" "$InstallDir/$TargetDir/refind.conf"
393 if [[ $?
!= 0 ]] ; then
397 if [[ $DeleteRefindDir == 1 ]] ; then
398 echo "Deleting the temporary directory $RefindDir"
401 } # CopyRefindFiles()
403 # Mount the partition the user specified with the --usedefault or --ownhfs option
404 MountDefaultTarget
() {
405 InstallDir
=/tmp
/refind_install
406 mkdir
-p "$InstallDir"
408 if [[ $OSName == 'Darwin' ]] ; then
409 if [[ $OwnHfs == '1' ]] ; then
410 Temp
=`diskutil info "$TargetPart" | grep "Mount Point"`
411 InstallDir
=`echo $Temp | cut -f 3-30 -d ' '`
412 if [[ $InstallDir == '' ]] ; then
413 InstallDir
=/tmp
/refind_install
414 mount
-t hfs
"$TargetPart" "$InstallDir"
419 mount
-t msdos
"$TargetPart" "$InstallDir"
421 elif [[ $OSName == 'Linux' ]] ; then
422 mount
-t vfat
"$TargetPart" "$InstallDir"
424 if [[ $?
!= 0 ]] ; then
425 echo "Couldn't mount $TargetPart ! Aborting!"
429 echo "UnmountEsp = $UnmountEsp"
430 } # MountDefaultTarget()
433 # A series of OS X support functions....
436 # Mount the ESP at /Volumes/ESP or determine its current mount
438 # Sets InstallDir to the ESP mount point
439 # Sets UnmountEsp if we mounted it
441 # Identify the ESP. Note: This returns the FIRST ESP found;
442 # if the system has multiple disks, this could be wrong!
443 Temp
=`diskutil list | grep " EFI " | grep -o 'disk.*'`
444 Esp
=/dev
/`echo $Temp`
445 # If the ESP is mounted, use its current mount point....
446 Temp
=`df -P | grep "$Esp"`
447 InstallDir
=`echo $Temp | cut -f 6 -d ' '`
448 if [[ "$InstallDir" == '' ]] ; then
449 mkdir
/Volumes
/ESP
&> /dev
/null
450 mount
-t msdos
"$Esp" /Volumes
/ESP
451 if [[ $?
!= 0 ]] ; then
452 echo "Unable to mount ESP! Aborting!\n"
456 InstallDir
="/Volumes/ESP"
460 # Set up for booting from Mac HFS+ volume that boots rEFInd in MJG's way
461 # (http://mjg59.dreamwidth.org/7468.html)
462 # Must be passed the original rEFInd binary filename (without a path).
464 if [[ -s "$InstallDir/mach_kernel" ]] ; then
465 echo "Attempt to install rEFInd to a partition with a /mach_kernel file! Aborting!"
468 cp -n "$InstallDir/$TargetDir/boot.efi" "$InstallDir/$TargetDir/boot.efi-backup" &> /dev
/null
469 ln -f "$InstallDir/$TargetDir/$1" "$InstallDir/$TargetDir/boot.efi"
470 touch "$InstallDir/mach_kernel"
471 cp -n "$RefindDir/icons/os_refind.icns" "$InstallDir/.VolumeIcon.icns" &> /dev
/null
472 rm "$InstallDir/$TargetDir/SystemVersion.plist" &> /dev
/null
473 cat - << ENDOFHERE >> "$InstallDir/$TargetDir/SystemVersion.plist"
474 <xml version="1.0" encoding="UTF-8"?>
475 <plist version="1.0">
477 <key>ProductBuildVersion</key>
479 <key>ProductName</key>
480 <string>rEFInd</string>
481 <key>ProductVersion</key>
482 <string>0.7.6</string>
488 # Control the OS X installation.
489 # Sets Problems=1 if problems found during the installation.
491 echo "Installing rEFInd on OS X...."
492 if [[ "$TargetDir" == "/EFI/BOOT" ||
"$OwnHfs" == '1' ]] ; then
494 elif [[ "$InstallToEspOnMac" == "1" ]] ; then
497 InstallDir
="$RootDir/"
499 echo "Installing rEFInd to the partition mounted at $InstallDir"
500 Platform
=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
502 if [[ $InstallToEspOnMac == "1" ]] ; then
503 bless
--mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind"
504 elif [[ "$TargetDir" != "/EFI/BOOT" ]] ; then
505 bless
--setBoot --folder "$InstallDir/$TargetDir" --file "$InstallDir/$TargetDir/$Refind"
507 if [[ $?
!= 0 ]] ; then
510 if [[ -f /Library
/StartupItems
/rEFItBlesser ||
-d /Library
/StartupItems
/rEFItBlesser
]] ; then
512 echo "/Library/StartupItems/rEFItBlesser found!"
513 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
514 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
516 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
517 echo "Deleting /Library/StartupItems/rEFItBlesser..."
518 rm -r /Library
/StartupItems
/rEFItBlesser
520 echo "Not deleting rEFItBlesser."
524 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
525 echo "bless status with 'bless --info', since this is known to cause disk corruption"
526 echo "on some systems!!"
532 # Now a series of Linux support functions....
535 # Check for evidence that we're running in Secure Boot mode. If so, and if
536 # appropriate options haven't been set, warn the user and offer to abort.
537 # If we're NOT in Secure Boot mode but the user HAS specified the --shim
538 # or --localkeys option, warn the user and offer to abort.
540 # FIXME: Although I checked the presence (and lack thereof) of the
541 # /sys/firmware/efi/vars/SecureBoot* files on my Secure Boot test system
542 # before releasing this script, I've since found that they are at least
543 # sometimes present when Secure Boot is absent. This means that the first
544 # test can produce false alarms. A better test is highly desirable.
546 VarFile
=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
547 if [[ -n "$VarFile" && "$TargetDir" != '/EFI/BOOT' && "$ShimSource" == "none" ]] ; then
549 echo "CAUTION: Your computer appears to support Secure Boot, but you haven't"
550 echo "specified a valid shim.efi file source. If you've disabled Secure Boot and"
551 echo "intend to leave it disabled, this is fine; but if Secure Boot is active, the"
552 echo "resulting installation won't boot. You can read more about this topic at"
553 echo "http://www.rodsbooks.com/refind/secureboot.html."
555 echo -n "Do you want to proceed with installation (Y/N)? "
557 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
558 echo "OK; continuing with the installation..."
564 if [[ "$ShimSource" != "none" && ! -n "$VarFile" ]] ; then
566 echo "You've specified installing using a shim.efi file, but your computer does not"
567 echo "appear to be running in Secure Boot mode. Although installing in this way"
568 echo "should work, it's unnecessarily complex. You may continue, but unless you"
569 echo "plan to enable Secure Boot, you should consider stopping and omitting the"
570 echo "--shim option. You can read more about this topic at"
571 echo "http://www.rodsbooks.com/refind/secureboot.html."
573 echo -n "Do you want to proceed with installation (Y/N)? "
575 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
576 echo "OK; continuing with the installation..."
582 if [[ $LocalKeys != 0 && ! -n "$VarFile" ]] ; then
584 echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
585 echo "but your computer does not appear to be running in Secure Boot mode. The"
586 echo "keys you generate will be useless unless you enable Secure Boot. You may"
587 echo "proceed with this installation, but before you do so, you may want to read"
588 echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
590 echo -n "Do you want to proceed with installation (Y/N)? "
592 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
593 echo "OK; continuing with the installation..."
599 } # CheckSecureBoot()
601 # Check for the presence of locally-generated keys from a previous installation in
602 # $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
605 PrivateKey
="$EtcKeysDir/$LocalKeysBase.key"
606 CertKey
="$EtcKeysDir/$LocalKeysBase.crt"
607 DerKey
="$EtcKeysDir/$LocalKeysBase.cer"
608 OpenSSL
=`which openssl 2> /dev/null`
610 # Do the work only if one or more of the necessary keys is missing
611 # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
612 # is also missing, this will fail. This could be improved.
613 if [[ ! -f "$PrivateKey" ||
! -f "$CertKey" ||
! -f "$DerKey" ]] ; then
614 echo "Generating a fresh set of local keys...."
615 mkdir
-p "$EtcKeysDir"
616 chmod 0700 "$EtcKeysDir"
617 if [[ ! -x "$OpenSSL" ]] ; then
618 echo "Can't find openssl, which is required to create your private signing keys!"
622 if [[ -f "$PrivateKey" ]] ; then
623 echo "Backing up existing $PrivateKey"
624 cp -f "$PrivateKey" "$PrivateKey.backup" 2> /dev
/null
626 if [[ -f "$CertKey" ]] ; then
627 echo "Backing up existing $CertKey"
628 cp -f "$CertKey" "$CertKey.backup" 2> /dev
/null
630 if [[ -f "$DerKey" ]] ; then
631 echo "Backing up existing $DerKey"
632 cp -f "$DerKey" "$DerKey.backup" 2> /dev
/null
634 "$OpenSSL" req
-new -x509 -newkey rsa
:2048 -keyout "$PrivateKey" -out "$CertKey" \
635 -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
636 "$OpenSSL" x509
-in "$CertKey" -out "$DerKey" -outform DER
637 chmod 0600 "$PrivateKey"
639 echo "Using existing local keys...."
643 # Sign a single binary. Requires parameters:
645 # $2 = destination file
646 # Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
648 # Aborts script on error
650 $SBSign --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1"
651 if [[ $?
!= 0 ]] ; then
652 echo "Problem signing the binary $1! Aborting!"
657 # Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
658 # key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
659 # not, try to generate new keys and store them in $EtcKeysDir.
661 SBSign
=`which sbsign 2> /dev/null`
662 echo "Found sbsign at $SBSign"
663 TempDir
="/tmp/refind_local"
664 if [[ ! -x "$SBSign" ]] ; then
665 echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
670 mkdir
-p "$TempDir/drivers_x64"
671 cp "$RefindDir/refind.conf-sample $TempDir" 2> /dev
/null
672 cp "$ThisDir/refind.conf-sample $TempDir" 2> /dev
/null
673 cp "$RefindDir/refind_ia32.efi $TempDir" 2> /dev
/null
674 cp -a "$RefindDir/drivers_ia32 $TempDir" 2> /dev
/null
675 cp -a "$ThisDir/drivers_ia32 $TempDir" 2> /dev
/null
676 SignOneBinary
"$RefindDir/refind_x64.efi" "$TempDir/refind_x64.efi"
678 IFS
=$
(echo -en "\n\b")
679 for Driver
in `ls "$RefindDir"/drivers_x64/*.efi "$ThisDir"/drivers_x64/*.efi 2> /dev/null` ; do
680 TempName
=`basename "$Driver"`
681 SignOneBinary
"$Driver" "$TempDir/drivers_x64/$TempName"
688 # Identifies the ESP's location (/boot or /boot/efi, or these locations under
689 # the directory specified by --root); aborts if the ESP isn't mounted at
691 # Sets InstallDir to the ESP mount point.
693 EspLine
=`df "$RootDir/boot/efi" 2> /dev/null | grep boot/efi`
694 if [[ ! -n "$EspLine" ]] ; then
695 EspLine
=`df "$RootDir"/boot | grep boot`
697 InstallDir
=`echo $EspLine | cut -d " " -f 6`
698 if [[ -n "$InstallDir" ]] ; then
699 EspFilesystem
=`grep "$InstallDir" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3`
701 if [[ $EspFilesystem != 'vfat' ]] ; then
702 echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be"
703 echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
706 echo "ESP was found at $InstallDir using $EspFilesystem"
709 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
710 # If this fails, sets Problems=1
713 Efibootmgr
=`which efibootmgr 2> /dev/null`
714 if [[ "$Efibootmgr" ]] ; then
715 InstallDisk
=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
716 PartNum
=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
717 EntryFilename
="$TargetDir/$Refind"
718 EfiEntryFilename
=`echo ${EntryFilename//\//\\\}`
719 EfiEntryFilename2
=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
720 ExistingEntry
=`"$Efibootmgr" -v | grep -i "$EfiEntryFilename2"`
722 if [[ "$ExistingEntry" ]] ; then
723 ExistingEntryBootNum
=`echo "$ExistingEntry" | cut -c 5-8`
724 FirstBoot
=`"$Efibootmgr" | grep BootOrder | cut -c 12-15`
725 if [[ "$ExistingEntryBootNum" != "$FirstBoot" ]] ; then
726 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
727 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
728 echo "manager. If this is NOT what you want, you should use efibootmgr to"
729 echo "manually adjust your EFI's boot order."
730 "$Efibootmgr" -b $ExistingEntryBootNum -B &> /dev
/null
737 if [[ $InstallIt == "1" ]] ; then
738 echo "Installing it!"
739 "$Efibootmgr" -c -l "$EfiEntryFilename" -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev
/null
740 if [[ $?
!= 0 ]] ; then
746 else # efibootmgr not found
751 if [[ $EfibootmgrProblems ]] ; then
753 echo "ALERT: There were problems running the efibootmgr program! You may need to"
754 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
755 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
758 echo "rEFInd has been set as the default boot manager."
762 # Create a minimal/sample refind_linux.conf file in /boot.
763 GenerateRefindLinuxConf
() {
764 if [[ -f "$RLConfFile" ]] ; then
765 echo "Existing $RLConfFile found; not overwriting."
767 echo "Creating $RLConfFile; edit it to adjust kernel options."
768 if [[ -f "$RootDir/etc/default/grub" ]] ; then
769 # We want the default options used by the distribution, stored here....
770 source "$RootDir/etc/default/grub"
771 echo "Setting default boot options based on $RootDir/etc/default/grub"
773 RootFS
=`df "$RootDir" | grep dev | cut -f 1 -d " "`
774 StartOfDevname
=`echo "$RootFS" | cut -b 1-7`
775 if [[ "$StartOfDevname" == "/dev/sd" ||
"$StartOfDevName" == "/dev/hd" ]] ; then
776 # Identify root filesystem by UUID rather than by device node, if possible
777 Uuid
=`blkid -o export "$RootFS" 2> /dev/null | grep UUID=`
778 if [[ -n $Uuid ]] ; then
782 DefaultOptions
="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
783 echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
784 echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
785 echo "\"Boot without EFI storage paranoia\" \"ro root=$RootFS $DefaultOptions efi_no_storage_paranoia\"" >> $RLConfFile
786 echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
790 # Set varaibles for installation in EFI/BOOT directory
792 TargetDir
="/EFI/BOOT"
793 if [[ $ShimSource == "none" ]] ; then
794 TargetX64
="bootx64.efi"
795 TargetIA32
="bootia32.efi"
797 if [[ $ShimType == "shim.efi" ||
$ShimType == "shimx64.efi" ]] ; then
798 TargetX64
="grubx64.efi"
799 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
800 TargetX64
="loader.efi"
802 echo "Unknown shim/PreBootloader type: $ShimType"
806 TargetIA32
="bootia32.efi"
807 TargetShim
="bootx64.efi"
809 } # SetFilenamesForBoot()
811 # Set variables for installation in EFI/Microsoft/Boot directory
813 TargetDir
="/EFI/Microsoft/Boot"
814 if [[ $ShimSource == "none" ]] ; then
815 TargetX64
="bootmgfw.efi"
817 if [[ $ShimType == "shim.efi" ||
$ShimType == "shimx64.efi" ]] ; then
818 TargetX64
="grubx64.efi"
819 elif [[ $ShimType == "preloader.efi" ||
$ShimType == "PreLoader.efi" ]] ; then
820 TargetX64
="loader.efi"
822 echo "Unknown shim/PreBootloader type: $ShimType"
826 TargetShim
="bootmgfw.efi"
830 # TargetDir defaults to /EFI/refind; however, this function adjusts it as follows:
831 # - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot,
832 # install to that directory under the suitable name; but DO NOT do this if
833 # refind.conf is also in /EFI/refind.
834 # - If booted in BIOS mode and the ESP lacks any other EFI files, install to
836 # - If booted in BIOS mode and there's no refind.conf file and there is a
837 # /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and
838 # install under that name, "hijacking" the Windows boot loader filename
839 DetermineTargetDir
() {
842 if [[ -f $InstallDir/EFI
/BOOT
/refind.conf
]] ; then
846 if [[ -f $InstallDir/EFI
/Microsoft
/Boot
/refind.conf
]] ; then
850 if [[ -f $InstallDir/EFI
/refind
/refind.conf
]] ; then
851 TargetDir
="/EFI/refind"
854 if [[ $Upgrade == 1 ]] ; then
855 echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it."
858 if [[ ! -d /sys
/firmware
/efi
&& $Upgrade == 0 ]] ; then # BIOS-mode
859 FoundEfiFiles
=`find "$InstallDir/EFI/BOOT" -name "*.efi" 2> /dev/null`
860 FoundConfFiles
=`find "$InstallDir" -name "refind\.conf" 2> /dev/null`
861 if [[ ! -n "$FoundConfFiles" && -f "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" ]] ; then
862 mv -n "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" "$InstallDir/EFI/Microsoft" &> /dev
/null
864 echo "Running in BIOS mode with a suspected Windows installation; moving boot loader"
865 echo "files so as to install to $InstallDir$TargetDir."
866 elif [[ ! -n "$FoundEfiFiles" ]] ; then # In BIOS mode and no default loader; install as default loader
868 echo "Running in BIOS mode with no existing default boot loader; installing to"
869 echo $InstallDir$TargetDir
871 echo "Running in BIOS mode with an existing default boot loader; backing it up and"
872 echo "installing rEFInd in its place."
873 if [[ -d "$InstallDir/EFI/BOOT-rEFIndBackup" ]] ; then
875 echo "Caution: An existing backup of a default boot loader exists! If the current"
876 echo "default boot loader and the backup are different boot loaders, the current"
877 echo "one will become inaccessible."
879 echo -n "Do you want to proceed with installation (Y/N)? "
881 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
882 echo "OK; continuing with the installation..."
887 mv -n "$InstallDir/EFI/BOOT" "$InstallDir/EFI/BOOT-rEFIndBackup"
891 } # DetermineTargetDir()
893 # Controls rEFInd installation under Linux.
894 # Sets Problems=1 if something goes wrong.
896 if [[ "$TargetDir" == "/System/Library/CoreServices" ]] ; then
897 echo "You may not use the --ownhfs option under Linux! Aborting!"
900 echo "Installing rEFInd on Linux...."
901 modprobe efivars
&> /dev
/null
902 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
909 if [[ $CpuType == 'x86_64' ]] ; then
911 elif [[ ($CpuType == 'i386' ||
$CpuType == 'i486' ||
$CpuType == 'i586' ||
$CpuType == 'i686') ]] ; then
913 # If we're in EFI mode, do some sanity checks, and alert the user or even
914 # abort. Not in BIOS mode, though, since that could be used on an emergency
915 # disc to try to recover a troubled Linux installation.
916 if [[ -d /sys
/firmware
/efi
]] ; then
917 if [[ "$ShimSource" != "none" && "$TargetDir" != "/BOOT/EFI" ]] ; then
919 echo "CAUTION: shim does not currently supports 32-bit systems, so you should not"
920 echo "use the --shim option to install on such systems. Aborting!"
925 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
926 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
927 echo "on a 64-bit computer, you should manually install the 64-bit version of"
928 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
929 echo "you're positive you want to continue with this installation, answer 'Y'"
930 echo "to the following question..."
932 echo -n "Are you sure you want to continue (Y/N)? "
934 if [[ $YesNo == "Y" ||
$YesNo == "y" ]] ; then
935 echo "OK; continuing with the installation..."
941 echo "Unknown CPU type '$CpuType'; aborting!"
945 if [[ $LocalKeys == 1 ]] ; then
951 if [[ "$TargetDir" != "/EFI/BOOT" && "$TargetDir" != "/EFI/Microsoft/Boot" ]] ; then
953 GenerateRefindLinuxConf
958 # The main part of the script. Sets a few environment variables,
959 # performs a few startup checks, and then calls functions to
960 # install under OS X or Linux, depending on the detected platform.
965 ThisDir
="$( cd -P "$
( dirname "${BASH_SOURCE[0]}" )" && pwd )"
966 RefindDir
="$ThisDir/refind"
967 ThisScript
="$ThisDir/`basename $0`"
968 if [[ `whoami` != "root" ]] ; then
969 echo "Not running as root; attempting to elevate privileges via sudo...."
970 sudo
"$ThisScript" "$@"
971 if [[ $?
!= 0 ]] ; then
972 echo "This script must be run as root (or using sudo). Exiting!"
979 if [[ $OSName == 'Darwin' ]] ; then
980 if [[ "$ShimSource" != "none" ]] ; then
981 echo "The --shim option is not supported on OS X! Exiting!"
984 if [[ "$LocalKeys" != 0 ]] ; then
985 echo "The --localkeys option is not supported on OS X! Exiting!"
989 elif [[ $OSName == 'Linux' ]] ; then
992 echo "Running on unknown OS; aborting!"
995 if [[ $Problems ]] ; then
998 echo "Installation has completed, but problems were detected. Review the output for"
999 echo "error messages and take corrective measures as necessary. You may need to"
1000 echo "re-run this script or install manually before rEFInd will work."
1004 echo "Installation has completed successfully."
1008 if [[ $UnmountEsp == '1' ]] ; then
1009 echo "Unmounting install dir"
1013 if [[ "$InstallDir" == /tmp
/refind_install
]] ; then