]> code.delx.au - refind/commitdiff
New script to help with juggling installation locations.
authorsrs5694 <srs5694@users.sourceforge.net>
Thu, 3 Jan 2013 03:08:01 +0000 (22:08 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Thu, 3 Jan 2013 03:08:01 +0000 (22:08 -0500)
mvrefind.sh [new file with mode: 0755]

diff --git a/mvrefind.sh b/mvrefind.sh
new file mode 100755 (executable)
index 0000000..bdab41a
--- /dev/null
@@ -0,0 +1,275 @@
+#!/bin/bash
+#
+# Linux script to move an existing rEFInd installation from one directory to another
+#
+# Usage:
+#
+# ./mvrefind.sh /path/to/source /path/to/destination
+#
+# Typically used to "hijack" or "unhijack" a Windows boot loader location or
+# to help convert a rEFInd installation made in BIOS mode to one that works
+# in EFI mode.
+#
+# Revision history:
+#
+# 0.6.3   -- Initial release
+#
+# Note: mvrefind.sh version numbers match those of the rEFInd package
+# with which they first appeared.
+
+RootDir="/"
+SourceX64="refind_x64.efi"
+TargetX64=$SourceX64
+SourceIA32="refind_ia32.efi"
+TargetIA32=$SourceIA32
+SourceShim="shim.efi"
+TargetShim=$SourceShim
+SourceDir=${1}
+TargetDir=${2}
+
+# Identifies the ESP's location (/boot or /boot/efi); aborts if the ESP isn't
+# mounted at either location. Also splits the ESP location from SourceDir and
+# TargetDir, leaving them intact but creating new EspSourceDir and EspTargetDir
+# variables containing only the ESP components thereof. These new variables
+# are also converted to all-lowercase and any trailing slash is stripped, to
+# assist in comparisons. (This is reasonable because FAT is case-insensitive.)
+# Sets InstallDir to the ESP mount point.
+FindLinuxESP() {
+   EspLine=`df $RootDir/boot/efi 2> /dev/null | grep boot/efi`
+   if [[ ! -n $EspLine ]] ; then
+      EspLine=`df $RootDir/boot | grep boot`
+   fi
+   InstallDir=`echo $EspLine | cut -d " " -f 6`
+   if [[ -n $InstallDir ]] ; then
+      EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
+   fi
+   if [[ $EspFilesystem != 'vfat' ]] ; then
+      echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be"
+      echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
+      exit 1
+   fi
+
+   # Sanity check on source & target....
+   EspPathLength=`expr length $InstallDir`
+   Temp=`echo $SourceDir | cut -c 1-$EspPathLength`
+   if [[ $Temp != $InstallDir ]] ; then
+      echo "$SourceDir isn't on the ESP ($InstallDir)! Aborting!"
+      exit 1
+   fi
+   Temp=`echo $TargetDir | cut -c 1-$EspPathLength`
+   if [[ $Temp != $InstallDir ]] ; then
+      echo "$TargetDir isn't on the ESP ($InstallDir)! Aborting!"
+      exit 1
+   fi
+
+   # Temporarily replace "/" in pathnames with ",", so as to enable sed to
+   # work on them
+   TempInstallDir=`echo $InstallDir | tr '/' ','`
+   Temp=`echo $SourceDir | tr '/' ',' | sed s/${TempInstallDir}//g | tr ',' '/' | tr '[A-Z]' '[a-z]'`
+   EspSourceDir=`dirname $Temp`/`basename $Temp`
+   Temp=`echo $TargetDir | tr '/' ',' | sed s/${TempInstallDir}//g | tr ',' '/' | tr '[A-Z]' '[a-z]'`
+   EspTargetDir=`dirname $Temp`/`basename $Temp`
+   if [[ $EspSourceDir == $EspTargetDir ]] ; then
+      echo "$SourceDir is the same as $TargetDir! Aborting!"
+      exit 1
+   fi
+} # FindLinuxESP
+
+# Adjust filename variables appropriately for their locations and detected
+# presence (or lack thereof) of shim installation
+AdjustFilenames() {
+   echo "Entering AdjustFilenames()"
+   if [[ -f $SourceDir/grubx64.efi ]] ; then
+      SourceX64="grubx64.efi"
+      TargetX64=$SourceX64
+      if [[ $EspSourceDir == "/efi/boot" ]] ; then
+         SourceShim="bootx64.efi"
+      elif [[ $EspSourceDir == "/efi/microsoft/boot" ]] ; then
+         SourceShim="bootmgfw.efi"
+      fi
+   else
+      SourceShim="none"
+      TargetShim="none"
+      if [[ $EspSourceDir == "/efi/boot" ]] ; then
+         SourceX64="bootx64.efi"
+         SourceIA32="bootia32.efi"
+      elif [[ $EspSourceDir == "/efi/microsoft/boot" ]] ; then
+         SourceX64="bootmgfw.efi"
+      fi
+   fi
+
+   if [[ $EspTargetDir == "/efi/boot" ]] ; then
+      if [[ $TargetShim == "none" ]] ; then
+         TargetX64="bootx64.efi"
+         TargetIA32="bootia32.efi"
+      else
+         TargetShim="bootx64.efi"
+      fi
+   elif [[ $EspTargetDir == "/efi/microsoft/boot" ]] ; then
+      if [[ $TargetShim == "none" ]] ; then
+         TargetX64="bootmgfw.efi"
+      else
+         TargetShim="bootmgfw.efi"
+      fi
+   fi
+
+   echo "Leaving AdjustFilenames():"
+   echo "  SourceX64 = $SourceX64, TargetX64 = $TargetX64"
+   echo "  SourceIA32 = $SourceIA32, TargetIA32 = $TargetIA32"
+   echo "  SourceShim = $SourceShim, TargetShim = $TargetShim"
+} # AdjustFilenames()
+
+# Checks for the presence of necessary files, including both boot loaders
+# and support utilities (efibootmgr, etc.)
+CheckForFiles() {
+   echo "Entering CheckForFiles()"
+   if [[ (! -f $SourceDir/$SourceX64 && ! -f $SourceDir/$SourceIA32) ||
+         ($SourceShim != "none" && ! -f $SourceDir/SourceShim) ||
+         ! -f $SourceDir/refind.conf ]] ; then
+      echo "There doesn't seem to be a rEFInd installation at $SourceDir!"
+      echo "Aborting!"
+      exit 1
+   fi
+   if [[ $EspTargetDir != "/efi/boot" && $EspTargetDir != "/efi/microsoft/boot" ]] ; then
+      Efibootmgr=`which efibootmgr 2> /dev/null`
+      if [[ ! -f $Efibootmgr ]] ; then
+         echo "Moving to a non-default directory requires a working efibootmgr utility, but"
+         echo "one can't be found! Aborting!"
+         exit 1
+      elif [[ ! -d "/sys/firmware/efi" ]] ; then
+         echo "Moving to a non-default directory requires a boot into EFI mode, but we seem"
+         echo "to be running in BIOS mode. (Perhaps typing 'modprobe efivars' will fix this."
+         echo "Aborting!"
+      fi
+   fi
+} # CheckForFiles()
+
+# Do final checks & then move the files!
+MoveFiles() {
+   echo "Entering MoveFiles()"
+   ExistingFiles=`find $TargetDir -name "*.efi" 2> /dev/null`
+   if [[ -n $ExistingFiles && $EspTargetDir != "/efi/boot" && $EspTargetDir != "/efi/microsoft/boot" ]] ; then
+      echo "$TargetDir isn't empty! Aborting!"
+      exit 1
+   fi
+
+   if [[ $EspTargetDir == "/efi/boot" && -d $TargetDir ]] ; then
+      if [[ -d $InstallDir/EFI/BOOT-rEFIndBackup ]] ; then
+         echo ""
+         echo "Caution: An existing backup of a default boot loader exists! If the current"
+         echo "default boot loader and the backup are different boot loaders, the current"
+         echo "one will become inaccessible."
+         echo ""
+         echo -n "Do you want to proceed with moving (Y/N)? "
+         read YesNo
+         if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
+            echo "OK; continuing with the move..."
+         else
+            exit 0
+         fi
+      else
+         mv $TargetDir $InstallDir/EFI/BOOT-refindBackup &> /dev/null
+      fi
+   fi
+
+   if [[ $EspTargetDir == "/efi/microsoft/boot" && -d $TargetDir ]] ; then
+      mv -n $EspTargetDir/bootmgfw.efi $InstallDir/EFI/Microsoft/
+   fi
+
+   mkdir -p $TargetDir
+   mv $SourceDir/icons $TargetDir/ 2> /dev/null
+   mv $SourceDir/icons-backup $TargetDir/ 2> /dev/null
+   mv $SourceDir/drivers_* $TargetDir/ 2> /dev/null
+   mv $SourceDir/keys $TargetDir 2> /dev/null
+   mv $SourceDir/$SourceX64 $TargetDir/$TargetX64 2> /dev/null
+   mv $SourceDir/$SourceIA32 $TargetDir/$TargetIA32 2> /dev/null
+   mv $SourceDir/$SourceShim $TargetDir/$TargetShim 2> /dev/null
+   mv $SourceDir/refind.conf* $TargetDir/ 2> /dev/null
+   rmdir $SourceDir 2> /dev/null
+} # MoveFiles()
+
+# Clean up after moving files -- mainly restoring old backed-up files, if present
+PostMoveCleanup() {
+   if [[ $EfiSourceDir == "/efi/boot" && -d $InstallDir/EFI/BOOT-rEFIndBackup && ! -d $SourceDir ]] ; then
+      mv $InstallDir/EFI/BOOT-rEFIndBackup $SourceDir 2> /dev/null
+   fi
+   if [[ $EfiSourceDir == "/efi/microsoft/boot" && -f $InstallDir/EFI/Microsoft/bootmgfw.efi ]] ; then
+      mv -n $InstallDir/EFI/Microsoft/bootmgfw.efi $SourceDir/bootmgfw.efi
+   fi
+} # PostMoveCleanup()
+
+# If necessary, create a new NVRAM entry for the new location
+AddNvramEntry() {
+   echo "Entering AddNvramEntry()"
+   InstallIt="0"
+   Efibootmgr=`which efibootmgr 2> /dev/null`
+   InstallDisk=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
+   PartNum=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
+
+   if [[ $TargetShim != "none" ]] ; then
+      EntryFilename=$TargetDir/$TargetShim
+   else
+      CpuType=`uname -m`
+      if [[ $CpuType == 'x86_64' ]] ; then
+         EntryFilename=$TargetDir/$TargetX64
+      else
+         EntryFilename=$TargetDir/$TargetIA32
+      fi
+   fi # if/else
+
+   EfiEntryFilename=`echo ${EntryFilename//\//\\\}`
+   EfiEntryFilename2=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
+   ExistingEntry=`$Efibootmgr -v | grep $EfiEntryFilename2`
+
+   if [[ $ExistingEntry ]] ; then
+      ExistingEntryBootNum=`echo $ExistingEntry | cut -c 5-8`
+      FirstBoot=`$Efibootmgr | grep BootOrder | cut -c 12-15`
+      if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
+         echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
+         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"
+   fi
+
+   if [[ $InstallIt == "1" ]] ; then
+      $Efibootmgr -c -l $EfiEntryFilename -L "rEFInd Boot Manager" -d $InstallDisk -p $PartNum &> /dev/null
+      if [[ $? != 0 ]] ; then
+         EfibootmgrProblems=1
+      fi
+   fi
+
+   if [[ $EfibootmgrProblems ]] ; then
+      echo
+      echo "ALERT: There were problems running the efibootmgr program! Your moved rEFInd"
+      echo "might not run!"
+      echo
+   fi
+} # AddNvramEntry
+
+#
+# Main body of script
+#
+
+if [[ $# != 2 ]] ; then
+   echo "Usage: $0 {source-directory} {target-directory}"
+   exit 1
+fi
+if [[ `whoami` != "root" ]] ; then
+   echo "Not running as root! Aborting!"
+   exit 1
+fi
+
+FindLinuxESP
+AdjustFilenames
+CheckForFiles
+MoveFiles
+PostMoveCleanup
+echo "EspTargetDir == \"$EspTargetDir\""
+if [[ $EspTargetDir != "/efi/boot" && $EspTargetDir != "/efi/microsoft/boot" ]] ; then
+   AddNvramEntry
+fi