# "--esp" to install to the ESP rather than to the system's root
# filesystem. This is the default on Linux
# "--usedefault {devicefile}" to install as default
-# (/EFI/BOOT/BOOTX64.EFI and similar) to the specified
-# device (/dev/sdd1 or whatever) without registering with
-# the NVRAM
-# "--drivers" to install drivers along with regular files
+# (/EFI/BOOT/BOOTX64.EFI and similar) to the specified device
+# (/dev/sdd1 or whatever) without registering with the NVRAM.
+# "--alldrivers" to install all drivers along with regular files
+# "--nodrivers" to suppress driver installation (default in Linux is
+# driver used on /boot; --nodrivers is OS X default)
+# "--shim {shimfile}" to install a shim.efi file for Secure Boot
+# "--localkeys" to re-sign x86-64 binaries with a locally-generated key
#
# The "esp" option is valid only on Mac OS X; it causes
# installation to the EFI System Partition (ESP) rather than
#
# Revision history:
#
-# 0.5.1 -- Added --shim option
+# 0.6.1 -- Added --root option; minor bug fixes
+# 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option;
+# changed default driver installation behavior in Linux to install
+# the driver needed to read /boot (if available)
+# 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
+# 0.5.1.1 -- Fixed bug that caused script failure under OS X
+# 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
+# in /boot
# 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
# Note: install.sh version numbers match those of the rEFInd package
# with which they first appeared.
+RootDir="/"
TargetDir=/EFI/refind
-EtcKeysDir=/etc/refind.d/keys
LocalKeysBase="refind_local"
ShimSource="none"
TargetX64="refind_x64.efi"
GetParams() {
InstallToEspOnMac=0
- InstallDrivers=0
+ if [[ $OSName == "Linux" ]] ; then
+ # Install the driver required to read /boot, if it's available
+ InstallDrivers="boot"
+ else
+ InstallDrivers="none"
+ fi
while [[ $# -gt 0 ]]; do
case $1 in
--esp | --ESP) InstallToEspOnMac=1
TargetIA32="bootia32.efi"
shift
;;
+ --root) RootDir=$2
+ shift
+ ;;
+ --localkeys) LocalKeys=1
+ ;;
--shim) ShimSource=$2
shift
;;
- --drivers) InstallDrivers=1
+ --drivers | --alldrivers) InstallDrivers="all"
;;
- --localkeys) LocalKeys=1
+ --nodrivers) InstallDrivers="none"
;;
- * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--drivers] "
- echo " [--localkeys] [--shim {shim-filename}]"
- echo "Aborting!"
+ * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} ]"
+ echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]"
+ echo " [--localkeys]"
exit 1
esac
shift
done
+
if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then
echo "You may use --esp OR --usedefault, but not both! Aborting!"
exit 1
fi
-# exit 1
+ if [[ $RootDir != '/' && $TargetDir == '/EFI/BOOT' ]] ; then
+ echo "You may use --usedefault OR --root, but not both! Aborting!"
+ exit 1
+ fi
+ if [[ $RootDir != '/' && $InstallToEspOnMac == 1 ]] ; then
+ echo "You may use --root OR --esp, but not both! Aborting!"
+ exit 1
+ fi
+
+ RLConfFile="$RootDir/boot/refind_linux.conf"
+ EtcKeysDir="$RootDir/etc/refind.d/keys"
} # GetParams()
# Abort if the rEFInd files can't be found.
# 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
+ mkdir -p $InstallDir/$TargetDir/keys/
+ cp $EtcKeysDir/$LocalKeysBase.cer $InstallDir/$TargetDir/keys/
+ cp $EtcKeysDir/$LocalKeysBase.crt $InstallDir/$TargetDir/keys/
+# else
+# cp $ThisDir/refind.cer $InstallDir/$TargetDir/keys/
+# cp $ThisDir/refind.crt $InstallDir/$TargetDir/keys/
fi
} # CopyKeys()
+# Copy drivers from $RefindDir/drivers_$1 to $InstallDir/$TargetDir/drivers_$1,
+# honoring the $InstallDrivers condition. Must be passed a suitable
+# architecture code (ia32 or x64).
+CopyDrivers() {
+ if [[ $InstallDrivers == "all" ]] ; then
+ mkdir -p $InstallDir/$TargetDir/drivers_$1
+ cp $RefindDir/drivers_$1/*_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
+ cp $ThisDir/drivers_$1/*_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
+ elif [[ $InstallDrivers == "boot" && -x `which 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 =`
+ DriverType=""
+ case $BootFS in
+ ext2 | ext3 | ext4) DriverType="ext4"
+ ;;
+ reiserfs) DriverType="reiserfs"
+ ;;
+ hfsplus) DriverType="hfs"
+ ;;
+ *) BootFS=""
+ esac
+ if [[ -n $BootFS ]] ; then
+ echo "Installing driver for $BootFS (${DriverType}_$1.efi)"
+ mkdir -p $InstallDir/$TargetDir/drivers_$1
+ cp $RefindDir/drivers_$1/${DriverType}_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
+ cp $ThisDir/drivers_$1/${DriverType}_$1.efi $InstallDir/$TargetDir/drivers_$1/ 2> /dev/null
+ fi
+ fi
+}
+
# Copy the rEFInd files to the ESP or OS X root partition.
# Sets Problems=1 if any critical commands fail.
CopyRefindFiles() {
TargetShim="bootx64.efi"
CopyShimFiles
fi
- if [[ $InstallDrivers == 1 ]] ; then
- cp -r $RefindDir/drivers_* $InstallDir/$TargetDir/
+ if [[ $InstallDrivers == "all" ]] ; then
+ cp -r $RefindDir/drivers_* $InstallDir/$TargetDir/ 2> /dev/null
+ cp -r $ThisDir/drivers_* $InstallDir/$TargetDir/ 2> /dev/null
fi
Refind=""
CopyKeys
if [[ $? != 0 ]] ; then
Problems=1
fi
- if [[ $InstallDrivers == 1 ]] ; then
- mkdir -p $InstallDir/$TargetDir/drivers_ia32
- cp -r $RefindDir/drivers_ia32/*_ia32.efi $InstallDir/$TargetDir/drivers_ia32/
- fi
+ CopyDrivers ia32
Refind="refind_ia32.efi"
elif [[ $Platform == 'EFI64' ]] ; then
cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/$TargetX64
if [[ $? != 0 ]] ; then
Problems=1
fi
- if [[ $InstallDrivers == 1 ]] ; then
- mkdir -p $InstallDir/$TargetDir/drivers_x64
- cp -r $RefindDir/drivers_x64/*_x64.efi $InstallDir/$TargetDir/drivers_x64/
- fi
+ CopyDrivers x64
Refind="refind_x64.efi"
CopyKeys
if [[ $ShimSource != "none" ]] ; then
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
+ cp $ThisDir/keys/refind.cer $EtcKeysDir
+ cp $ThisDir/keys/refind.crt $EtcKeysDir
fi
fi
else
if [[ $? != 0 ]] ; then
Problems=1
fi
+ cp -rf $ThisDir/keys $InstallDir/$TargetDir/
if [[ -f $InstallDir/$TargetDir/refind.conf ]] ; then
echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
echo "to avoid overwriting your customizations."
elif [[ $InstallToEspOnMac == "1" ]] ; then
MountOSXESP
else
- InstallDir="/"
+ InstallDir="$RootDir/"
fi
echo "Installing rEFInd to the partition mounted at '$InstallDir'"
Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
# 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
echo ""
- 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 "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 "http://www.rodsbooks.com/refind/secureboot.html."
echo ""
echo -n "Do you want to proceed with installation (Y/N)? "
read ContYN
# 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!"
+ $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
+ if [[ $? != 0 ]] ; then
+ echo "Problem signing the binary $1! Aborting!"
exit 1
fi
}
# not, try to generate new keys and store them in $EtcKeysDir.
ReSignBinaries() {
SBSign=`which sbsign 2> /dev/null`
+ echo "Found sbsign at $SBSign"
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!"
+ echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
+ echo "Aborting!"
exit 1
fi
GenerateKeys
mkdir -p $TempDir/drivers_x64
- cp $RefindDir/refind.conf-sample $TempDir
+ cp $RefindDir/refind.conf-sample $TempDir 2> /dev/null
+ cp $ThisDir/refind.conf-sample $TempDir 2> /dev/null
cp $RefindDir/refind_ia32.efi $TempDir
- cp -a $RefindDir/drivers_ia32 $TempDir
+ cp -a $RefindDir/drivers_ia32 $TempDir 2> /dev/null
+ cp -a $ThisDir/drivers_ia32 $TempDir 2> /dev/null
SignOneBinary $RefindDir/refind_x64.efi $TempDir/refind_x64.efi
- for Driver in `ls $RefindDir/drivers_x64/*.efi` ; do
+ for Driver in `ls $RefindDir/drivers_x64/*.efi $ThisDir/drivers_x64/*.efi 2> /dev/null` ; do
TempName=`basename $Driver`
SignOneBinary $Driver $TempDir/drivers_x64/$TempName
done
DeleteRefindDir=1
}
-# Identifies the ESP's location (/boot or /boot/efi); aborts if
-# the ESP isn't mounted at either location.
+# Identifies the ESP's location (/boot or /boot/efi, or these locations under
+# the directory specified by --root); aborts if the ESP isn't mounted at
+# either location.
# Sets InstallDir to the ESP mount point.
FindLinuxESP() {
- EspLine=`df /boot/efi | grep boot`
+ 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`
- EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
+ if [[ -n $InstallDir ]] ; then
+ EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
+ fi
if [[ $EspFilesystem != 'vfat' ]] ; then
- echo "/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be mounted at"
- echo "/boot or /boot/efi and it must be VFAT! Aborting!"
+ 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
echo "ESP was found at $InstallDir using $EspFilesystem"
fi
} # AddBootEntry()
+# Create a minimal/sample refind_linux.conf file in /boot.
+GenerateRefindLinuxConf() {
+ if [[ ! -f $RLConfFile ]] ; then
+ if [[ -f "$RootDir/etc/default/grub" ]] ; then
+ # We want the default options used by the distribution, stored here....
+ source "$RootDir/etc/default/grub"
+ fi
+ RootFS=`df $RootDir | grep dev | cut -f 1 -d " "`
+ StartOfDevname=`echo $RootFS | cut -b 1-7`
+ if [[ $StartOfDevname == "/dev/sd" || $StartOfDevName == "/dev/hd" ]] ; then
+ # Identify root filesystem by UUID rather than by device node, if possible
+ Uuid=`blkid -o export $RootFS 2> /dev/null | grep UUID=`
+ if [[ -n $Uuid ]] ; then
+ RootFS=$Uuid
+ fi
+ fi
+ DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
+ echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
+ echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
+ echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
+ fi
+}
+
# Controls rEFInd installation under Linux.
# Sets Problems=1 if something goes wrong.
InstallOnLinux() {
CopyRefindFiles
if [[ $TargetDir != "/EFI/BOOT" ]] ; then
AddBootEntry
+ GenerateRefindLinuxConf
fi
} # InstallOnLinux()
# install under OS X or Linux, depending on the detected platform.
#
-GetParams $@
OSName=`uname -s`
+GetParams $@
ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
RefindDir="$ThisDir/refind"
ThisScript="$ThisDir/`basename $0`"
if [[ `whoami` != "root" ]] ; then
echo "Not running as root; attempting to elevate privileges via sudo...."
- sudo $ThisScript $1 $2 $3 $4 $5 $6
+ sudo $ThisScript "$@"
if [[ $? != 0 ]] ; then
echo "This script must be run as root (or using sudo). Exiting!"
exit 1
fi
CheckForFiles
if [[ $OSName == 'Darwin' ]] ; then
- if [[ $ShimDir != "none" ]] ; then
+ if [[ $ShimSource != "none" ]] ; then
echo "The --shim option is not supported on OS X! Exiting!"
exit 1
fi