]> code.delx.au - refind/commitdiff
Install program now supports automatic Secure Boot installation.
authorsrs5694 <srs5694@users.sourceforge.net>
Mon, 10 Dec 2012 02:44:38 +0000 (21:44 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Mon, 10 Dec 2012 02:44:38 +0000 (21:44 -0500)
docs/refind/installing.html
install.sh

index f5acdfac17871e600ec16b7d8eeed44797750bc5..40c5f87cee13e369b9764c84f4189976137ab5ed 100644 (file)
@@ -99,7 +99,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <p class="sidebar"><b>Warning:</b> If you're using a Macintosh, you should run <tt>install.sh</tt> from Mac OS X rather than from Linux. If run from Linux, rEFInd is unlikely to be fully installed. Worse, it's conceivable that running <tt>install.sh</tt> from Linux will damage your firmware, requiring that it be re-flashed. The reason is that Apple uses non-standard methods to enable a boot loader, and the Linux functions in <tt>install.sh</tt> assume standard EFI installation methods.</p>
 
-<p>If you're using Linux or Mac OS X, the easiest way to install rEFInd is to use the <tt>install.sh</tt> script. This script automatically copies rEFInd's files to your ESP or other target location and makes changes to your firmware's NVRAM settings so that rEFInd will start the next time you boot. If you've booted to OS X or in EFI mode to Linux on a UEFI-based PC, <tt>install.sh</tt> will probably do the right thing, so you can get by with the quick instructions. If your setup is unusual, though, or if you want to create a USB flash drive with rEFInd on it, you should read the <a href="#extra_installsh">extra instructions</a> for this utility.</p>
+<p>If you're using Linux or Mac OS X, the easiest way to install rEFInd is to use the <tt>install.sh</tt> script. This script automatically copies rEFInd's files to your ESP or other target location and makes changes to your firmware's NVRAM settings so that rEFInd will start the next time you boot. If you've booted to OS X or in non-Secure-Boot EFI mode to Linux on a UEFI-based PC, <tt>install.sh</tt> will probably do the right thing, so you can get by with the quick instructions. If your setup is unusual, if your computer uses Secure Boot, or if you want to create a USB flash drive with rEFInd on it, you should read the <a href="#extra_installsh">extra instructions</a> for this utility.</p>
 
 <h3>Quick <tt>install.sh</tt> Instructions</h3>
 
@@ -113,7 +113,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 # <tt class="userinput">./install.sh</tt>
 Installing rEFInd on Linux....
 ESP was found at /boot/efi using vfat
-Copied rEFInd binary file refind_x64.efi
+Copied rEFInd binary files
 
 Copying sample configuration file as refind.conf; edit this file to configure
 rEFInd.
@@ -129,7 +129,7 @@ Not running as root; attempting to elevate privileges via sudo....
 Password:
 Installing rEFInd on OS X....
 Installing rEFInd to the partition mounted at '/'
-Copied rEFInd binary file refind_ia32.efi
+Copied rEFInd binary files
 
 Copying sample configuration file as refind.conf; edit this file to configure
 rEFInd.
@@ -164,14 +164,6 @@ Installation has completed successfully.</pre>
     the Terminal window. You'll need to press the Return or Enter key to
     run the script.</li>
 
-<li>Under OS X, passing the <tt>--esp</tt> option causes the script to
-    install rEFInd to the ESP. The script finds the first ESP that's
-    identified by the <tt>diskutil</tt> program and, if it's not already
-    mounted, mounts it to install rEFInd. Thus, it's conceivable that
-    <tt>install.sh</tt> will install rEFInd to the wrong partition if you
-    have multiple disks or if a disk has multiple ESPs. If you believe this
-    has happened, you may need to re-install manually.</li>
-
 <li>If you're using OS X 10.7's Whole Disk Encryption (WDE) feature, you
     <i>must</i> install rEFInd to the ESP, so the <tt>--esp</tt> option to
     <tt>install.sh</tt> is required. I'm still a little bit foggy about
@@ -203,28 +195,44 @@ Installation has completed successfully.</pre>
     though; because of the popularity of dual boots with Windows on Macs,
     the BIOS/legacy scans are enabled by default on Macs.</li>
 
-<li>Under both Linux and OS X, you can add the <tt>--drivers</tt> option to
-    have <tt>install.sh</tt> install all the filesystem drivers along with
-    the main rEFInd program. (The default is to <i>not</i> install any
-    drivers.)</li>
-
-<li>Under both Linux and OS X, you can add the <tt>--usedefault <tt
-    class="variable">devicepath</tt></tt> option to install rEFInd to the
-    specified device as <tt>EFI/BOOT/bootx64.efi</tt> and
-    <tt>EFI/BOOT/bootia32.efi</tt>. The specified device must be a valid
-    FAT partition. This option also tells the script to <i>not</i> make
-    changes to the computer's NVRAM. The idea is that you can easily create
-    a bootable USB flash drive with this option: Create a proper
-    FAT-formatted ESP on a disk (say, <tt>/dev/sdd1</tt>) and then type <tt
-    class="userinput">bash ./install --usedefault /dev/sdd1</tt> to turn
-    the disk into an emergency disk. This option can also be used to
-    install rEFInd to an ESP using the <a href="#naming">alternative naming
-    options</a> described later. This latter usage will result in a
-    bootable rEFInd only if no other OS has already created an NVRAM
-    variable pointing to itself.</li>
-
 </ul>
 
+<p>In addition to these quirks, you should be aware of some options that <tt>install.sh</tt> supports to enable you to customize your installation in various ways. The syntax for <tt>install.sh</tt> is as follows:</p>
+
+<pre class="listing">
+install.sh [--esp | --usedefault <tt class="variable">device-file</tt>] [--drivers] [--shim <tt class="variable">shim-filename</tt>] \
+           [--localkeys]
+</pre>
+
+<p>The details of the options are summarized in <a href="#table1">Table 1.</a> Using some of these options in unusual conditions can generate warnings and prompts to confirm your actions. In particular, using <tt>--shim</tt> or <tt>--localkeys</tt> when you're <i>not</i> booted in Secure Boot mode, or failing to use <tt>--shim</tt> when you <i>are</i> booted in Secure Boot mode, will generate a query and a request to confirm your installation. Consult the <a href="secureboot.html">Managing Secure Boot</a> page for more on this topic.</p>
+
+<table border="1" cellpadding="1" cellspacing="2" summary="Table 1: Options to <tt>install.sh</tt>"><a name="table1"><caption><b>Table 1: Options to <tt>install.sh</tt></b></caption></a>
+<tr>
+   <th>Option</th>
+   <th>Explanation</th>
+</tr>
+<tr>
+   <td><tt>--esp</tt></td>
+   <td>This option tells <tt>install.sh</tt> to install rEFInd to the ESP of your computer. This option is only useful on OS X; on Linux, installing to the ESP is the default, so <tt>--esp</tt> is implicit on Linux. Be aware that some users have reported sluggish boots when installing rEFInd to the ESP on Macs. Installing rEFInd anywhere but the ESP makes little sense on UEFI-based PCs, except for the partial exception of removable boot media, which you can prepare with <tt>--usedefault</tt>.</td>
+</tr>
+<tr>
+   <td><tt>--usedefault <tt class="variable">device-file</tt></tt></td>
+   <td>You can install rEFInd to a disk using the default/fallback filename of <tt>EFI/BOOT/bootx64.efi</tt> (and <tt>EFI/BOOT/bootia32.efi</tt>, if the 32-bit build is available) using this option. The <tt class="variable">device-file</tt> should be an <i>unmounted</i> ESP, or at least a FAT partition, as in <tt>--usedefault /dev/sdc1</tt>. Your computer's NVRAM entries will <i>not</i> be modified when installing in this way. The intent is that you can create a bootable USB flash drive or install rEFInd on a computer that tends to "forget" its NVRAM settings with this option. This option is mutually exclusive with <tt>--esp</tt>.</td>
+</tr>
+<tr>
+   <td><tt>--drivers</tt></td>
+   <td>Ordinarily <tt>install.sh</tt> does not install drivers; but when you specify this option, it does; it copies all the driver files for your architecture. You may want to remove unused driver files after you use this option, especially if your computer uses Secure Boot.</td>
+</tr>
+<tr>
+   <td><tt>--shim <tt class="variable">shim-filename</tt></tt></td>
+   <td>If you pass this option to <tt>install.sh</tt>, the script will copy the specified shim program file to the target directory, copy the <tt>MokManager.efi</tt> file from the shim program file's directory to the target directory, copy the 64-bit version of rEFInd as <tt>grubx64.efi</tt>, and register shim with the firmware. (If you also specify <tt>--usedefault</tt>, the NVRAM registration is skipped.) The intent is to simplify rEFInd installation on a computer that uses Secure Boot; when so set up, rEFInd will boot in Secure Boot mode, with one caveat: The first time you boot, MokManager will launch, and you must use it to locate and install a public key. This key file will be located in the rEFInd directory under the name <tt>refind.cer</tt>. Note that I'm not providing a shim binary myself, but you can download one from <a href="http://www.codon.org.uk/~mjg59/shim-signed/">here.</a> In the not-too-distant future, most distributions will provide their own shim programs, so you'll be able to point to them&mdash;for instance, in <tt>/boot/efi/EFI/redhat/shim.efi</tt>.</td>
+</tr>
+<tr>
+   <td><tt>--localkeys</tt></td>
+   <td>This option tells <tt>install.sh</tt> to generate a new Machine Owner Key (MOK), store it in <tt>/etc/refind.d/keys</tt> as <tt>refind_local.*</tt>, and re-sign all the 64-bit rEFInd binaries with this key before installing them. This is the preferable way to install rEFInd in Secure Boot mode, since it means your binaries will be signed locally rather than with my own key, which is used to sign many other users' binaries; however, this method requires that both the <tt>openssl</tt> and <tt>sbsign</tt> binaries be installed. The former is readily available in most distributions' repositories, but the latter is not, so this option is not the default.</td>
+</tr>
+</table>
+
 <p>In any event, you should peruse the script's output to ensure that everything looks OK. <tt>install.sh</tt> displays error messages when it encounters errors, such as if the ESP is mounted read-only or if you run out of disk space. You may need to correct such problems manually and re-run the script. In some cases you may need to fall back on manual installation, which gives you better control over details such as which partition to use for installation.</p>
 
 <a name="linux">
@@ -247,7 +255,7 @@ Filesystem     1K-blocks  Used Available Use% Mounted on
 
 <ol>
 
-<li>Type <tt><b>cp -r refind /boot/efi/EFI/</b></tt> from the <tt>refind-<i>version</i></tt> directory in which the <tt>refind</tt> directory exists. This copies all the files that rEFInd needs to work. Note that this includes <i>all</i> of rEFInd's drivers.</li>
+<li>Type <tt><b>cp -r refind /boot/efi/EFI/</b></tt> from the <tt>refind-<i>version</i></tt> directory in which the <tt>refind</tt> directory exists. This copies all the files that rEFInd needs to work. Note that this includes <i>all</i> of rEFInd's drivers. This command also copies the rEFInd binaries as signed by me; if you prefer to re-sign the binaries yourself, you'll have to do so before or during the copy operation, as described on the <a href="secureboot.html">Managing Secure Boot</a> page.</li>
 
 <li>Type <tt><b>cd /boot/efi/EFI/refind</b></tt> to change into rEFInd's new directory on the ESP.</li>
 
@@ -260,7 +268,7 @@ Filesystem     1K-blocks  Used Available Use% Mounted on
 <p class="sidebar"><b>Weird:</b> A <a href="http://mjg59.dreamwidth.org/20187.html">bug exists</a> in some Lenovo computers (and perhaps in some others, too) that causes the firmware's boot manager to refuse to boot any boot loader that doesn't have the name <tt>Windows Boot Manager</tt> or <tt>Red Hat Enterprise Linux</tt>. If you have such a system, you must pass one of those names (in quotes) rather than <tt>rEFInd</tt> to <tt>efibootmgr</tt> via its <tt>-L</tt> option. This bug was reported to Lenovo in mid-November 2012, so with any luck updated firmware without this bug will be available later this year or early in 2013. I can make no promises about this, though.</p>
 
 <a name="efibootmgr">
-<li>On a UEFI-based system, type <tt><b>efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd</b></tt> to add rEFInd to your EFI's list of available boot loaders, which it stores in NVRAM. Adjust the path to the binary as required if you install somewhere else. You may also need to include additional options if your ESP isn't on <tt>/dev/sda1</tt> or if your configuration is otherwise unusual; consult the <tt>efibootmgr</tt> man page for details. You may need to install this program on some systems; it's a standard part of most distributions' repositories.</li>
+<li>On a UEFI-based system, type <tt><b>efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd</b></tt> to add rEFInd to your EFI's list of available boot loaders, which it stores in NVRAM. Adjust the path to the binary as required if you install somewhere else. You may also need to include additional options if your ESP isn't on <tt>/dev/sda1</tt> or if your configuration is otherwise unusual; consult the <tt>efibootmgr</tt> man page for details. You may need to install this program on some systems; it's a standard part of most distributions' repositories. Also, if you're installing in Secure Boot mode, you must normally register <tt>shim.efi</tt> rather than the rEFInd binary, and rename <tt>refind_x64.efi</tt> to <tt>grubx64.efi</tt>.</li>
 </a>
 
 <li>If other boot loaders are already installed, you can use <tt>efibootmgr</tt> to adjust their boot order. For instance, <b><tt>efibootmgr -o 3,7,2</tt></b> sets the firmware to try boot loader #3 first, followed by #7, followed by #2. (The program should have displayed a list of boot loaders when you added yours in the preceding step.) Place rEFInd's number first to set it as the default boot program.</li>
index e21022422343c2cfa881bb9cee764f593426b3c4..76fc27bda90f683532ff073fc4e964a38d8115b3 100755 (executable)
@@ -26,6 +26,7 @@
 #
 # Revision history:
 #
+# 0.5.1   -- Added --shim option
 # 0.5.0   -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
 # 0.4.5   -- Fixed check for rEFItBlesser in OS X
 # 0.4.2   -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
 
 TargetDir=/EFI/refind
 EtcKeysDir=/etc/refind.d/keys
-SBModeInstall=0
+LocalKeysBase="refind_local"
+ShimSource="none"
+TargetX64="refind_x64.efi"
+TargetIA32="refind_ia32.efi"
+LocalKeys=0
+DeleteRefindDir=0
 
 #
 # Functions used by both OS X and Linux....
@@ -54,13 +60,21 @@ GetParams() {
               ;;
          --usedefault) TargetDir=/EFI/BOOT
               TargetPart=$2
+              TargetX64="bootx64.efi"
+              TargetIA32="bootia32.efi"
+              shift
+              ;;
+         --shim) ShimSource=$2
               shift
               ;;
          --drivers) InstallDrivers=1
               ;;
-         * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--drivers]"
-              echo "Aborting!"
-              exit 1
+         --localkeys) LocalKeys=1
+              ;;
+         * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--drivers] "
+             echo "         [--localkeys] [--shim {shim-filename}]"
+             echo "Aborting!"
+             exit 1
       esac
       shift
    done
@@ -72,8 +86,9 @@ GetParams() {
 } # GetParams()
 
 # Abort if the rEFInd files can't be found.
-# Also sets $ConfFile to point to the configuration file, and
-# $IconsDir to point to the icons directory
+# Also sets $ConfFile to point to the configuration file,
+# $IconsDir to point to the icons directory, and
+# $ShimSource to the source of the shim.efi file (if necessary).
 CheckForFiles() {
    # Note: This check is satisfied if EITHER the 32- or the 64-bit version
    # is found, even on the wrong platform. This is because the platform
@@ -99,30 +114,71 @@ CheckForFiles() {
       IconsDir=$ThisDir/icons
    else
       echo "The icons directory is missing! Aborting installation!"
+      exit 1
+   fi
+
+   if [[ $ShimSource != "none" ]] ; then
+      if [[ -f $ShimSource ]] ; then
+         TargetX64="grubx64.efi"
+         MokManagerSource=`dirname $ShimSource`/MokManager.efi
+      else
+         echo "The specified shim file, $ShimSource, doesn't exist!"
+         echo "Aborting installation!"
+         exit 1
+      fi
    fi
 } # CheckForFiles()
 
+# Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
+# available) to target.
+CopyShimFiles() {
+   cp $ShimSource $InstallDir/$TargetDir/$TargetShim
+   if [[ $? != 0 ]] ; then
+      Problems=1
+   fi
+   if [[ -f $MokManagerSource ]] ; then
+      cp $MokManagerSource $InstallDir/$TargetDir/
+   fi
+   if [[ $? != 0 ]] ; then
+      Problems=1
+   fi
+} # CopyShimFiles()
+
+# Copy the public keys to the installation medium
+CopyKeys() {
+   if [[ $LocalKeys == 1 ]] ; then
+      cp $EtcKeysDir/$LocalKeysBase.cer $InstallDir/$TargetDir
+      cp $EtcKeysDir/$LocalKeysBase.crt $InstallDir/$TargetDir
+   else
+      cp $ThisDir/refind.cer $InstallDir/$TargetDir
+      cp $ThisDir/refind.crt $InstallDir/$TargetDir
+   fi
+} # CopyKeys()
+
 # Copy the rEFInd files to the ESP or OS X root partition.
 # Sets Problems=1 if any critical commands fail.
 CopyRefindFiles() {
    mkdir -p $InstallDir/$TargetDir &> /dev/null
    if [[ $TargetDir == '/EFI/BOOT' ]] ; then
-      cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/bootia32.efi 2> /dev/null
+      cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/$TargetIA32 2> /dev/null
       if [[ $? != 0 ]] ; then
          echo "Note: IA32 (x86) binary not installed!"
       fi
-      cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/bootx64.efi 2> /dev/null
+      cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/$TargetX64 2> /dev/null
       if [[ $? != 0 ]] ; then
          Problems=1
       fi
+      if [[ $ShimSource != "none" ]] ; then
+         TargetShim="bootx64.efi"
+         CopyShimFiles
+      fi
       if [[ $InstallDrivers == 1 ]] ; then
          cp -r $RefindDir/drivers_* $InstallDir/$TargetDir/
       fi
       Refind=""
-      cp $ThisDir/refind.cer $InstallDir/$TargetDir
-      cp $ThisDir/refind.crt $InstallDir/$TargetDir
+      CopyKeys
    elif [[ $Platform == 'EFI32' ]] ; then
-      cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir
+      cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/$TargetIA32
       if [[ $? != 0 ]] ; then
          Problems=1
       fi
@@ -132,7 +188,7 @@ CopyRefindFiles() {
       fi
       Refind="refind_ia32.efi"
    elif [[ $Platform == 'EFI64' ]] ; then
-      cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir
+      cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/$TargetX64
       if [[ $? != 0 ]] ; then
          Problems=1
       fi
@@ -141,19 +197,23 @@ CopyRefindFiles() {
          cp -r $RefindDir/drivers_x64/*_x64.efi $InstallDir/$TargetDir/drivers_x64/
       fi
       Refind="refind_x64.efi"
-      cp $ThisDir/refind.cer $InstallDir/$TargetDir
-      cp $ThisDir/refind.crt $InstallDir/$TargetDir
-      if [[ $SBModeInstall == 1 ]] ; then
-         echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
-         mkdir -p $EtcKeysDir
-         cp $ThisDir/refind.cer $EtcKeysDir
-         cp $ThisDir/refind.crt $EtcKeysDir
+      CopyKeys
+      if [[ $ShimSource != "none" ]] ; then
+         TargetShim=`basename $ShimSource`
+         CopyShimFiles
+         Refind=$TargetShim
+         if [[ $LocalKeys == 0 ]] ; then
+            echo "Storing copies of rEFInd Secure Boot public keys in $EtcKeysDir"
+            mkdir -p $EtcKeysDir
+            cp $ThisDir/refind.cer $EtcKeysDir
+            cp $ThisDir/refind.crt $EtcKeysDir
+         fi
       fi
    else
       echo "Unknown platform! Aborting!"
       exit 1
    fi
-   echo "Copied rEFInd binary file $Refind"
+   echo "Copied rEFInd binary files"
    echo ""
    if [[ -d $InstallDir/$TargetDir/icons ]] ; then
       rm -rf $InstallDir/$TargetDir/icons-backup &> /dev/null
@@ -166,7 +226,7 @@ CopyRefindFiles() {
    fi
    if [[ -f $InstallDir/$TargetDir/refind.conf ]] ; then
       echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
-      echo "to avoid collision."
+      echo "to avoid overwriting your customizations."
       echo ""
       cp -f $ConfFile $InstallDir/$TargetDir
       if [[ $? != 0 ]] ; then
@@ -181,6 +241,10 @@ CopyRefindFiles() {
          Problems=1
       fi
    fi
+   if [[ $DeleteRefindDir == 1 ]] ; then
+      echo "Deleting the temporary directory $RefindDir"
+      rm -r $RefindDir
+   fi
 } # CopyRefindFiles()
 
 # Mount the partition the user specified with the --usedefault option
@@ -275,21 +339,19 @@ InstallOnOSX() {
 # Now a series of Linux support functions....
 #
 
-# Check for evidence that we're running in Secure Boot mode. If so, warn the
-# user and confirm installation.
-# TODO: Perform a reasonable Secure Boot installation.
+# Check for evidence that we're running in Secure Boot mode. If so, and if
+# appropriate options haven't been set, warn the user and offer to abort.
+# If we're NOT in Secure Boot mode but the user HAS specified the --shim
+# or --localkeys option, warn the user and offer to abort.
 CheckSecureBoot() {
-   VarFile=`ls -ld /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
-   if [[ -n $VarFile  && $TargetDir != '/EFI/BOOT' ]] ; then
+   VarFile=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
+   if [[ -n $VarFile  && $TargetDir != '/EFI/BOOT' && $ShimSource == "none" ]] ; then
       echo ""
-      echo "CAUTION: The computer seems to have been booted with Secure Boot active."
-      echo "Although rEFInd, when installed in conjunction with the shim boot loader, can"
-      echo "work on a Secure Boot computer, this installation script doesn't yet support"
-      echo "direct installation in a way that will work on such a computer. You may"
-      echo "proceed with installation with this script, but if you intend to boot with"
-      echo "Secure Boot active, you must then reconfigure your boot programs to add shim"
-      echo "to the process. Alternatively, you may terminate this script and do a manual"
-      echo "installation, as described at http://www.rodsbooks.com/refind/secureboot.html."
+      echo "CAUTION: The computer seems to have been booted with Secure Boot active, but"
+      echo "you haven't specified a valid shim.efi file source. The resulting installation"
+      echo "will not boot unless you disable Secure Boot. You may continue, but you should"
+      echo "consider using --shim to specify a working shim.efi file. You can read more"
+      echo "about this topic at http://www.rodsbooks.com/refind/secureboot.html."
       echo ""
       echo -n "Do you want to proceed with installation (Y/N)? "
       read ContYN
@@ -297,9 +359,130 @@ CheckSecureBoot() {
          echo "OK; continuing with the installation..."
       else
          exit 0
-      SBModeInstall=1
       fi
    fi
+
+   if [[ $ShimSource != "none" && ! -n $VarFile ]] ; then
+      echo ""
+      echo "You've specified installing using a shim.efi file, but your computer does not"
+      echo "appear to be running in Secure Boot mode. Although installing in this way"
+      echo "should work, it's unnecessarily complex. You may continue, but unless you"
+      echo "plan to enable Secure Boot, you should consider stopping and omitting the"
+      echo "--shim option. You can read more about this topic at"
+      echo "http://www.rodsbooks.com/refind/secureboot.html."
+      echo ""
+      echo -n "Do you want to proceed with installation (Y/N)? "
+      read ContYN
+      if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
+         echo "OK; continuing with the installation..."
+      else
+         exit 0
+      fi
+   fi
+
+   if [[ $LocalKeys != 0 && ! -n $VarFile ]] ; then
+      echo ""
+      echo "You've specified re-signing your rEFInd binaries with locally-generated keys,"
+      echo "but your computer does not appear to be running in Secure Boot mode. The"
+      echo "keys you generate will be useless unless you enable Secure Boot. You may"
+      echo "proceed with this installation, but before you do so, you may want to read"
+      echo "more about it at http://www.rodsbooks.com/refind/secureboot.html."
+      echo ""
+      echo -n "Do you want to proceed with installation (Y/N)? "
+      read ContYN
+      if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
+         echo "OK; continuing with the installation..."
+      else
+         exit 0
+      fi
+   fi
+
+} # CheckSecureBoot()
+
+# Check for the presence of locally-generated keys from a previous installation in
+# $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
+# openssl.
+GenerateKeys() {
+   PrivateKey=$EtcKeysDir/$LocalKeysBase.key
+   CertKey=$EtcKeysDir/$LocalKeysBase.crt
+   DerKey=$EtcKeysDir/$LocalKeysBase.cer
+   OpenSSL=`which openssl 2> /dev/null`
+
+   # Do the work only if one or more of the necessary keys is missing
+   # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
+   # is also missing, this will fail. This could be improved.
+   if [[ ! -f $PrivateKey || ! -f $CertKey || ! -f $DerKey ]] ; then
+      echo "Generating a fresh set of local keys...."
+      mkdir -p $EtcKeysDir
+      chmod 0700 $EtcKeysDir
+      if [[ ! -x $OpenSSL ]] ; then
+         echo "Can't find openssl, which is required to create your private signing keys!"
+         echo "Aborting!"
+         exit 1
+      fi
+      if [[ -f $PrivateKey ]] ; then
+         echo "Backing up existing $PrivateKey"
+         cp -f $PrivateKey $PrivateKey.backup 2> /dev/null
+      fi
+      if [[ -f $CertKey ]] ; then
+         echo "Backing up existing $CertKey"
+         cp -f $CertKey $CertKey.backup 2> /dev/null
+      fi
+      if [[ -f $DerKey ]] ; then
+         echo "Backing up existing $DerKey"
+         cp -f $DerKey $DerKey.backup 2> /dev/null
+      fi
+      $OpenSSL req -new -x509 -newkey rsa:2048 -keyout $PrivateKey -out $CertKey \
+                   -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
+      $OpenSSL x509 -in $CertKey -out $DerKey -outform DER
+      chmod 0600 $PrivateKey
+   else
+      echo "Using existing local keys...."
+   fi
+}
+
+# Sign a single binary. Requires parameters:
+#   $1 = source file
+#   $2 = destination file
+# Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
+# appropriately.
+# Aborts script on error
+SignOneBinary() {
+   if [[ $UseSBSign == 1 ]] ; then
+      $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
+      if [[ $? != 0 ]] ; then
+         echo "Problem signing the binary $1! Aborting!"
+         exit 1
+      fi
+   else
+      echo "PESign code not yet written; aborting!"
+      exit 1
+   fi
+}
+
+# Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
+# key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
+# not, try to generate new keys and store them in $EtcKeysDir.
+ReSignBinaries() {
+   SBSign=`which sbsign 2> /dev/null`
+   TempDir="/tmp/refind_local"
+   if [[ ! -x $SBSign ]] ; then
+      echo "Can't find either sbsign or pesign; one of these is required to sign rEFInd"
+      echo "with your own keys! Aborting!"
+      exit 1
+   fi
+   GenerateKeys
+   mkdir -p $TempDir/drivers_x64
+   cp $RefindDir/refind.conf-sample $TempDir
+   cp $RefindDir/refind_ia32.efi $TempDir
+   cp -a $RefindDir/drivers_ia32 $TempDir
+   SignOneBinary $RefindDir/refind_x64.efi $TempDir/refind_x64.efi
+   for Driver in `ls $RefindDir/drivers_x64/*.efi` ; do
+      TempName=`basename $Driver`
+      SignOneBinary $Driver $TempDir/drivers_x64/$TempName
+   done
+   RefindDir=$TempDir
+   DeleteRefindDir=1
 }
 
 # Identifies the ESP's location (/boot or /boot/efi); aborts if
@@ -330,7 +513,10 @@ AddBootEntry() {
       EfiEntryFilename=`echo ${EntryFilename//\//\\\}`
       EfiEntryFilename2=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
       ExistingEntry=`$Efibootmgr -v | grep $EfiEntryFilename2`
-      if [[ $ExistingEntry ]] ; then
+      # NOTE: Below protects against duplicate entries, but only for non-Secure Boot
+      # installations.
+      # TODO: Improve to detect & protect against duplicating a Secure Boot entry.
+      if [[ $ExistingEntry && $ShimSource == "none" ]] ; then
          ExistingEntryBootNum=`echo $ExistingEntry | cut -c 5-8`
          FirstBoot=`$Efibootmgr | grep BootOrder | cut -c 12-15`
          if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
@@ -339,7 +525,7 @@ AddBootEntry() {
             echo "manager. If this is NOT what you want, you should use efibootmgr to"
             echo "manually adjust your EFI's boot order."
             $Efibootmgr -b $ExistingEntryBootNum -B &> /dev/null
-           InstallIt="1"
+            InstallIt="1"
          fi
       else
          InstallIt="1"
@@ -377,7 +563,17 @@ InstallOnLinux() {
    CpuType=`uname -m`
    if [[ $CpuType == 'x86_64' ]] ; then
       Platform="EFI64"
+      if [[ $LocalKeys == 1 ]] ; then
+         ReSignBinaries
+      fi
    elif [[ $CpuType == 'i386' || $CpuType == 'i486' || $CpuType == 'i586' || $CpuType == 'i686' ]] ; then
+      if [[ $ShimSource != "none" && $TargetDir != "/BOOT/EFI" ]] ; then
+         echo ""
+         echo "CAUTION: Neither rEFInd nor shim currently supports 32-bit systems, so you"
+         echo "should not use the --shim option to install on such systems. Aborting!"
+         echo ""
+         exit 1
+      fi
       Platform="EFI32"
       echo
       echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
@@ -416,10 +612,9 @@ OSName=`uname -s`
 ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 RefindDir="$ThisDir/refind"
 ThisScript="$ThisDir/`basename $0`"
-CheckForFiles
 if [[ `whoami` != "root" ]] ; then
    echo "Not running as root; attempting to elevate privileges via sudo...."
-   sudo $ThisScript $1 $2 $3
+   sudo $ThisScript $1 $2 $3 $4 $5 $6
    if [[ $? != 0 ]] ; then
       echo "This script must be run as root (or using sudo). Exiting!"
       exit 1
@@ -427,7 +622,16 @@ if [[ `whoami` != "root" ]] ; then
       exit 0
    fi
 fi
+CheckForFiles
 if [[ $OSName == 'Darwin' ]] ; then
+   if [[ $ShimDir != "none" ]] ; then
+      echo "The --shim option is not supported on OS X! Exiting!"
+      exit 1
+   fi
+   if [[ $LocalKeys != 0 ]] ; then
+      echo "The --localkeys option is not supported on OS X! Exiting!"
+      exit 1
+   fi
    InstallOnOSX $1
 elif [[ $OSName == 'Linux' ]] ; then
    InstallOnLinux