]> code.delx.au - refind/blobdiff - install.sh
Further tweaks to spoof_osx_version feature.
[refind] / install.sh
index 93b4cdea8241fef03e7010075eb0253bf7e042ad..99896f29769c821a5694305a9b74cf3f5c1eadc6 100755 (executable)
@@ -22,6 +22,7 @@
 #    "--shim {shimfile}" to install a shim.efi file for Secure Boot
 #    "--preloader" is synonymous with "--shim"
 #    "--localkeys" to re-sign x86-64 binaries with a locally-generated key
+#    "--keepname" to keep refind_x64.efi name as such even when using shim
 #    "--yes" to assume a "yes" response to all prompts
 #
 # The "esp" option is valid only on Mac OS X; it causes
 # to the current OS X boot partition. Under Linux, this script
 # installs to the ESP by default.
 #
-# This program is copyright (c) 2012-2014 by Roderick W. Smith
+# This program is copyright (c) 2012-2015 by Roderick W. Smith
 # It is released under the terms of the GNU GPL, version 3,
 # a copy of which should be included in the file COPYING.txt.
 #
 # Revision history:
 #
+# 0.9.3   -- Enable running under OS X's recovery system.
+# 0.9.2   -- Added --keepname option.
+# 0.8.7   -- Better detection of Secure Boot mode & fixed errors when copying
+#            Shim & MokManager files over themselves; fixed bug that caused
+#            inappropriate installation to EFI/BOOT/bootx64.efi
+# 0.8.6   -- Fixed bugs that caused misidentification of ESP on disks with
+#            partition numbers over 10 on OS X and misidentification of mount
+#            point if already-mounted ESP had space in path.
 # 0.8.5   -- Refinement/cleanup of new OS X ESP-as-default policy
 # 0.8.4   -- OS X default changed to install to ESP under /EFI/BOOT
 # 0.7.9   -- Fixed bug that caused errors if dmraid utility not installed
@@ -79,6 +88,7 @@ TargetDir=/EFI/refind
 LocalKeysBase="refind_local"
 ShimSource="none"
 ShimType="none"
+KeepName=0
 TargetShim="default"
 TargetX64="refind_x64.efi"
 TargetIA32="refind_ia32.efi"
@@ -122,6 +132,8 @@ GetParams() {
               ShimType=`basename $ShimSource`
               shift
               ;;
+         --keepname) KeepName=1
+              ;;
          --drivers | --alldrivers) InstallDrivers="all"
               ;;
          --nodrivers) InstallDrivers="none"
@@ -129,9 +141,9 @@ GetParams() {
          --yes) AlwaysYes=1
               ;;
          * ) echo "Usage: $0 [--notesp | --usedefault {device-file} | --root {dir} |"
-             echo "                     --ownhfs {device-file} ]"
-             echo "                  [--nodrivers | --alldrivers] [--shim {shim-filename}]"
-             echo "                  [--localkeys] [--yes]"
+             echo "                     --ownhfs {device-file} ] [--keepname]"
+             echo "                  [--nodrivers | --alldrivers]"
+             echo "                  [--localkeys] [--keepname] [--yes]"
              exit 1
       esac
       shift
@@ -148,6 +160,19 @@ GetParams() {
       echo "If you use --ownhfs, you may NOT use --usedefault! Aborting!"
       exit 1
    fi
+   if [[ "$KeepName" == 1 && "$ShimSource" == "none" ]] ; then
+      echo "The --keepname option is meaningful only in conjunction with --shim"
+      echo "or --preloader! Aborting!"
+      exit 1
+   fi
+   if [[ "$KeepName" == 1 && "$OSTYPE" != "linux-gnu" ]] ; then
+      echo "The --keepname option is valid only under Linux! Aborting!"
+      exit 1
+   fi
+   if [[ "$KeepName" == 1 && "$TargetDir" != "/EFI/BOOT" ]] ; then
+      echo "The --keepname option is incompatible with --usedefault! Aborting!"
+      exit 1
+   fi
    RLConfFile="$RootDir/boot/refind_linux.conf"
    EtcKeysDir="$RootDir/etc/refind.d/keys"
 } # GetParams()
@@ -196,6 +221,7 @@ CheckForFiles() {
       exit 1
    fi
 
+   echo "ShimSource is $ShimSource"
    if [[ "$ShimSource" != "none" ]] ; then
       if [[ -f "$ShimSource" ]] ; then
          if [[ $ShimType == "shimx64.efi" || $ShimType == "shim.efi" ]] ; then
@@ -220,15 +246,24 @@ CheckForFiles() {
 # Helper for CopyRefindFiles; copies shim files (including MokManager, if it's
 # available) to target.
 CopyShimFiles() {
-   cp -fb "$ShimSource" "$InstallDir/$TargetDir/$TargetShim"
-   if [[ $? != 0 ]] ; then
-      Problems=1
-   fi
-   if [[ -f "$MokManagerSource" ]] ; then
-      cp -fb "$MokManagerSource" "$InstallDir/$TargetDir/"
+   local inode1=`ls -i "$ShimSource" 2> /dev/null | cut -f 1 -d " "`
+   local inode2=`ls -i "$InstallDir/$TargetDir/$TargetShim" 2> /dev/null | cut -f 1 -d " "`
+   if [[ $inode1 != $inode2 ]] ; then
+      cp -fb "$ShimSource" "$InstallDir/$TargetDir/$TargetShim"
+      if [[ $? != 0 ]] ; then
+         Problems=1
+      fi
    fi
-   if [[ $? != 0 ]] ; then
-      Problems=1
+   inode1=`ls -i "$MokManagerSource" 2> /dev/null | cut -f 1 -d " "`
+   local TargetMMName=`basename $MokManagerSource`
+   inode2=`ls -i "$InstallDir/$TargetDir/$TargetMMName" 2> /dev/null | cut -f 1 -d " "`
+   if [[ $inode1 != $inode2 ]] ; then
+      if [[ -f "$MokManagerSource" ]] ; then
+         cp -fb "$MokManagerSource" "$InstallDir/$TargetDir/"
+      fi
+      if [[ $? != 0 ]] ; then
+         Problems=1
+      fi
    fi
 } # CopyShimFiles()
 
@@ -260,6 +295,10 @@ SetVarsForBoot() {
       TargetIA32="bootia32.efi"
       TargetShim="bootx64.efi"
    fi
+   if [[ $KeepName == 1 ]] ; then
+      echo "Installation is to /EFI/BOOT, which is incompatible with --keepname! Aborting!"
+      exit 1
+   fi
 } # SetVarsForBoot()
 
 # Set variables for installation in EFI/Microsoft/Boot directory
@@ -267,6 +306,7 @@ SetVarsForMsBoot() {
    TargetDir="/EFI/Microsoft/Boot"
    if [[ $ShimSource == "none" ]] ; then
       TargetX64="bootmgfw.efi"
+      TargetIA32="bootmgfw.efi"
    else
       if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then
          TargetX64="grubx64.efi"
@@ -279,6 +319,11 @@ SetVarsForMsBoot() {
       fi
       TargetShim="bootmgfw.efi"
    fi
+   if [[ $KeepName == 1 ]] ; then
+      echo "Installation is to /EFI/Microsoft/Boot, which is incompatible with --keepname!"
+      echo "Aborting!"
+      exit 1
+   fi
 } # SetVarsForMsBoot()
 
 # TargetDir defaults to /EFI/refind; however, this function adjusts it as follows:
@@ -293,17 +338,17 @@ SetVarsForMsBoot() {
 DetermineTargetDir() {
    Upgrade=0
 
-   if [[ -f $InstallDir/EFI/BOOT/refind.conf ]] ; then
+   if [[ -f $InstallDir/EFI/BOOT/refind.conf && ! -f $InstallDir/EFI/refind/refind.conf ]] ; then
       SetVarsForBoot
       Upgrade=1
    fi
-   if [[ -f $InstallDir/EFI/Microsoft/Boot/refind.conf ]] ; then
+   if [[ -f $InstallDir/EFI/Microsoft/Boot/refind.conf && ! -f $InstallDir/EFI/refind/refind.conf ]] ; then
       SetVarsForMsBoot
       Upgrade=1
    fi
    if [[ -f $InstallDir/EFI/refind/refind.conf ]] ; then
       TargetDir="/EFI/refind"
-      if [[ "$OSName" == 'Darwin' ]] ; then
+      if [[ $ShimSource == "none" || $KeepName == 1 ]] ; then
          TargetX64="refind_x64.efi"
          TargetIA32="refind_ia32.efi"
       fi
@@ -313,7 +358,7 @@ DetermineTargetDir() {
       echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it."
    fi
 
-   if [[ ! -d /sys/firmware/efi && ! $OSName == 'Darwin' && $Upgrade == 0 ]] ; then     # BIOS-mode
+   if [[ ! -d /sys/firmware/efi && ! $OSTYPE == darwin* && $Upgrade == 0 ]] ; then     # BIOS-mode
       FoundEfiFiles=`find "$InstallDir/EFI/BOOT" -name "*.efi" 2> /dev/null`
       FoundConfFiles=`find "$InstallDir" -name "refind\.conf" 2> /dev/null`
       if [[ ! -n "$FoundConfFiles" && -f "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" ]] ; then
@@ -353,26 +398,29 @@ DetermineTargetDir() {
 SetBootFS() {
    local Blkid
 
-   Blkid=`which blkid 2> /dev/null`
    BootFS=""
-   if [[ $OSName == 'Linux' && -x "$Blkid" ]] ; then
-      BootPart=`df /boot | grep dev | cut -f 1 -d " "`
-      BootFS=`$Blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
-   fi
-   if [[ $OSName == 'Darwin' ]] ; then
-      # 0FC63DAF-8483-4772-8E79-3D69D8477DE4 = Linux filesystem
-      # BC13C2FF-59E6-4262-A352-B275FD6F7172 = Freedesktop $boot partition
-      # 933AC7E1-2EB4-4F13-B844-0E14E2AEF915 = Freedesktop Linux /home
-      # E6D6D379-F507-44C2-A23C-238F2A3DF928 = Linux LVM
-      # A19D880F-05FC-4D3B-A006-743F0F84911E = Linux RAID
-      # 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F = Linux swap
-      Temp=$(diskutil list | grep -i '0FC63DAF-8483-4772-8E79-3D69D8477DE4\|BC13C2FF-59E6-4262-A352-B275FD6F7172\|933AC7E1-2EB4-4F13-B844-0E14E2AEF915\|E6D6D379-F507-44C2-A23C-238F2A3DF928\|A19D880F-05FC-4D3B-A006-743F0F84911E\|0657FD6D-A4AB-43C4-84E5-0933C84B4F4F\|Linux')
-      BootFS=""
-      if [[ -n $Temp ]] ; then
-         echo "Found suspected Linux partition(s); installing ext4fs driver."
-         BootFS="ext4"
-      fi
-   fi
+   case "$OSTYPE" in
+      linux-gnu)
+           if command -v blkid 2>/dev/null; then
+              BootPart=`df /boot | grep dev | cut -f 1 -d " "`
+              BootFS=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
+           fi
+           ;;
+      darwin*)
+           # 0FC63DAF-8483-4772-8E79-3D69D8477DE4 = Linux filesystem
+           # BC13C2FF-59E6-4262-A352-B275FD6F7172 = Freedesktop $boot partition
+           # 933AC7E1-2EB4-4F13-B844-0E14E2AEF915 = Freedesktop Linux /home
+           # E6D6D379-F507-44C2-A23C-238F2A3DF928 = Linux LVM
+           # A19D880F-05FC-4D3B-A006-743F0F84911E = Linux RAID
+           # 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F = Linux swap
+           Temp=$(diskutil list | grep -i '0FC63DAF-8483-4772-8E79-3D69D8477DE4\|BC13C2FF-59E6-4262-A352-B275FD6F7172\|933AC7E1-2EB4-4F13-B844-0E14E2AEF915\|E6D6D379-F507-44C2-A23C-238F2A3DF928\|A19D880F-05FC-4D3B-A006-743F0F84911E\|0657FD6D-A4AB-43C4-84E5-0933C84B4F4F\|Linux')
+           BootFS=""
+           if [[ -n $Temp ]] ; then
+              echo "Found suspected Linux partition(s); installing ext4fs driver."
+              BootFS="ext4"
+           fi
+           ;;
+   esac
 } # SetBootFS()
 
 # Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
@@ -399,6 +447,8 @@ CopyDrivers() {
               ;;
          hfsplus) DriverType="hfs"
               ;;
+         ntfs) DriverType="ntfs"
+              ;;
          *) BootFS=""
       esac
       if [[ -n $BootFS ]] ; then
@@ -415,7 +465,7 @@ CopyDrivers() {
 # or x64).
 CopyTools() {
    mkdir -p "$InstallDir/EFI/tools"
-   if [[ $OSName == 'Darwin' ]] ; then
+   if [[ $OSTYPE == darwin* ]] ; then
       cp -f "$RefindDir/tools_$1/gptsync_$1.efi" "$InstallDir/EFI/tools/"
       if [[ -f "$InstallDir/EFI/tools/gptsync.efi" ]] ; then
          mv "$InstallDir/EFI/tools/gptsync.efi" "$InstallDir/EFI/tools/gptsync.efi-disabled"
@@ -542,7 +592,7 @@ MountDefaultTarget() {
    InstallDir=/tmp/refind_install
    mkdir -p "$InstallDir"
    UnmountEsp=1
-   if [[ $OSName == 'Darwin' ]] ; then
+   if [[ $OSTYPE == darwin* ]] ; then
       if [[ $OwnHfs == '1' ]] ; then
          Temp=`diskutil info "$TargetPart" | grep "Mount Point"`
          InstallDir=`echo $Temp | cut -f 3-30 -d ' '`
@@ -555,7 +605,7 @@ MountDefaultTarget() {
       else
          mount -t msdos "$TargetPart" "$InstallDir"
       fi
-   elif [[ $OSName == 'Linux' ]] ; then
+   elif [[ $OSTYPE == linux-gnu ]] ; then
       mount -t vfat "$TargetPart" "$InstallDir"
    fi
    if [[ $? != 0 ]] ; then
@@ -597,8 +647,8 @@ MountOSXESP() {
    fi
    Esp=/dev/`echo $Temp`
    # If the ESP is mounted, use its current mount point....
-   Temp=`df -P | grep "$Esp"`
-   InstallDir=`echo $Temp | cut -f 6 -d ' '`
+   Temp=`df -P | grep "$Esp "`
+   InstallDir=`echo $Temp | cut -f 6- -d ' '`
    if [[ "$InstallDir" == '' ]] ; then
       mkdir /Volumes/ESP &> /dev/null
       mount -t msdos "$Esp" /Volumes/ESP
@@ -639,7 +689,7 @@ SetupMacHfs() {
         <key>ProductName</key>
         <string>rEFInd</string>
         <key>ProductVersion</key>
-        <string>0.7.6</string>
+        <string>0.9.2</string>
 </dict>
 </plist>
 ENDOFHERE
@@ -661,7 +711,7 @@ InstallOnOSX() {
    Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
    CopyRefindFiles
    if [[ $InstallToEspOnMac == "1" ]] ; then
-      bless --mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind"
+      bless --mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind" --shortform
    elif [[ "$TargetDir" != "/EFI/BOOT" ]] ; then
       bless --setBoot --folder "$InstallDir/$TargetDir" --file "$InstallDir/$TargetDir/$Refind"
    fi
@@ -697,20 +747,18 @@ InstallOnOSX() {
 # 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.
-#
-# FIXME: Although I checked the presence (and lack thereof) of the
-# /sys/firmware/efi/vars/SecureBoot* files on my Secure Boot test system
-# before releasing this script, I've since found that they are at least
-# sometimes present when Secure Boot is absent. This means that the first
-# test can produce false alarms. A better test is highly desirable.
 CheckSecureBoot() {
-   VarFile=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null`
-   if [[ -n "$VarFile" && "$TargetDir" != '/EFI/BOOT' && "$ShimSource" == "none" ]] ; then
+   local IsSecureBoot
+   if [[ -f /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data ]] ; then
+      IsSecureBoot=`od -An -t u1 /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data | tr -d '[[:space:]]'`
+   else
+      IsSecureBoot="0"
+   fi
+   if [[ $IsSecureBoot == "1" && "$TargetDir" != '/EFI/BOOT' && "$ShimSource" == "none" ]] ; then
       echo ""
-      echo "CAUTION: Your computer appears to support Secure Boot, but you haven't"
-      echo "specified a valid shim.efi file source. If you've disabled Secure Boot and"
-      echo "intend to leave it disabled, this is fine; but if Secure Boot is active, the"
-      echo "resulting installation won't boot. You can read more about this topic at"
+      echo "CAUTION: Your computer appears to be booted with Secure Boot, but you haven't"
+      echo "specified a valid shim.efi file source. Chances are you should re-run with"
+      echo "the --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)? "
@@ -722,7 +770,7 @@ CheckSecureBoot() {
       fi
    fi
 
-   if [[ "$ShimSource" != "none" && ! -n "$VarFile" ]] ; then
+   if [[ "$ShimSource" != "none" && ! $IsSecureBoot == "1" ]] ; 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"
@@ -740,7 +788,7 @@ CheckSecureBoot() {
       fi
    fi
 
-   if [[ $LocalKeys != 0 && ! -n "$VarFile" ]] ; then
+   if [[ $LocalKeys != 0 && ! $IsSecureBoot == "1" ]] ; 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"
@@ -918,7 +966,6 @@ FindMountedESP() {
 # If this fails, sets Problems=1
 AddBootEntry() {
    local PartNum
-   InstallIt="0"
    Efibootmgr=`which efibootmgr 2> /dev/null`
    if [[ "$Efibootmgr" ]] ; then
       InstallDisk=`grep "$InstallDir" /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
@@ -936,20 +983,20 @@ AddBootEntry() {
             echo "manager. The boot order is being adjusted to make rEFInd the default boot"
             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"
          fi
-      else
-         InstallIt="1"
+         "$Efibootmgr" -b $ExistingEntryBootNum -B &> /dev/null
       fi
 
-      if [[ $InstallIt == "1" ]] ; then
-         echo "Installing it!"
+      echo "Installing it!"
+      if [[ "$KeepName" == 0 ]] ; then
          "$Efibootmgr" -c -l "$EfiEntryFilename" -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev/null
-         if [[ $? != 0 ]] ; then
-            EfibootmgrProblems=1
-            Problems=1
-         fi
+      else
+         "$Efibootmgr" -c -l "$EfiEntryFilename" -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum \
+                       -u "$TargetShim $TargetX64" &> /dev/null
+      fi
+      if [[ $? != 0 ]] ; then
+         EfibootmgrProblems=1
+         Problems=1
       fi
 
    else # efibootmgr not found
@@ -1064,14 +1111,12 @@ InstallOnLinux() {
 # performs a few startup checks, and then calls functions to
 # install under OS X or Linux, depending on the detected platform.
 #
-OSName=`uname -s`
 GetParams "$@"
-ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ThisDir="$( cd -P "${BASH_SOURCE%/*}" && pwd )"
 RefindDir="$ThisDir/refind"
-ThisScript="$ThisDir/`basename $0`"
-if [[ `whoami` != "root" ]] ; then
+if [[ $UID != 0 ]] ; then
    echo "Not running as root; attempting to elevate privileges via sudo...."
-   sudo "$ThisScript" "$@"
+   sudo "$BASH_SOURCE" "$@"
    if [[ $? != 0 ]] ; then
       echo "This script must be run as root (or using sudo). Exiting!"
       exit 1
@@ -1080,30 +1125,28 @@ if [[ `whoami` != "root" ]] ; then
    fi
 fi
 CheckForFiles
-if [[ $OSName == 'Darwin' ]] ; then
-   if [[ "$ShimSource" != "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
-   if [[ $InstallToEspOnMac == 1 ]] ; then
-      TargetDir=/EFI/BOOT
-      TargetX64="bootx64.efi"
-      TargetIA32="bootia32.efi"
-   fi
-   InstallOnOSX $1
-elif [[ $OSName == 'Linux' ]] ; then
-   InstallOnLinux
-else
-   echo "Running on unknown OS; aborting!"
-   if [[ "$InstallToEspOnMac" == 0 ]] ; then
-      echo "The --notesp option is not supported on Linux! Exiting!"
-      exit 1
-   fi
-fi
+case "$OSTYPE" in
+   darwin*)
+        if [[ "$ShimSource" != "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
+        ;;
+   linux-gnu)
+        InstallOnLinux
+        ;;
+   *)
+        echo "Running on unknown OS; aborting!"
+        if [[ "$InstallToEspOnMac" == 0 ]] ; then
+           echo "The --notesp option is not supported on Linux! Exiting!"
+           exit 1
+        fi
+esac
 
 if [[ $Problems ]] ; then
    echo