X-Git-Url: https://code.delx.au/refind/blobdiff_plain/7f1e7b5f752e324db88ab658e2b7d1bbb5b62922..b8bf5591559b45540015db6e08040ba4540140c5:/install.sh diff --git a/install.sh b/install.sh index dc6d898..a95d30e 100755 --- a/install.sh +++ b/install.sh @@ -7,11 +7,13 @@ # ./install.sh [options] # # options include: -# "--esp" to install to the ESP rather than to the system's root -# filesystem. This is the default on Linux +# "--notesp" to install to the OS X root filesystem rather than to the ESP. +# This option may not be used under 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. +# "--ownhfs {devicefile}" to install to an HFS+ volume that's NOT currently +# an OS X boot volume. # "--root {dir}" to specify installation using the specified directory # as the system's root # "--alldrivers" to install all drivers along with regular files @@ -27,12 +29,22 @@ # to the current OS X boot partition. Under Linux, this script # installs to the ESP by default. # -# This program is copyright (c) 2012 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.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 +# 0.7.7 -- Fixed bug that created mangled refind_linux.conf file; added ability +# to locate and mount ESP on Linux, if it's not mounted +# 0.7.6 -- Added --ownhfs {device-filename} option +# 0.7.5 -- Fixed bug when installing to ESP on recent versions of OS X # 0.7.2 -- Fixed code that could be confused by use of autofs to mount the ESP # 0.7.0 -- Added support for the new Btrfs driver # 0.6.12 -- Added support for PreLoader as well as for shim @@ -82,16 +94,20 @@ AlwaysYes=0 # GetParams() { - InstallToEspOnMac=0 - if [[ $OSName == "Linux" ]] ; then - # Install the driver required to read /boot, if it's available - InstallDrivers="boot" - else - InstallDrivers="none" - fi + InstallToEspOnMac=1 + # Install the driver required to read Linux /boot, if it's available + # Note: Under OS X, this will be installed only if a Linux partition + # is detected, in which case the ext4fs driver will be installed. + InstallDrivers="boot" while [[ $# -gt 0 ]]; do case $1 in - --esp | --ESP) InstallToEspOnMac=1 + --notesp) InstallToEspOnMac=0 + ;; + --ownhfs) OwnHfs=1 + InstallToEspOnMac=0 + TargetPart="$2" + TargetDir=/System/Library/CoreServices + shift ;; --usedefault) TargetDir=/EFI/BOOT TargetPart="$2" @@ -100,6 +116,7 @@ GetParams() { shift ;; --root) RootDir="$2" + InstallToEspOnMac=0 shift ;; --localkeys) LocalKeys=1 @@ -114,27 +131,26 @@ GetParams() { ;; --yes) AlwaysYes=1 ;; - * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} ]" + * ) echo "Usage: $0 [--notesp | --usedefault {device-file} | --root {dir} |" + echo " --ownhfs {device-file} ]" echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]" echo " [--localkeys] [--yes]" exit 1 esac shift done - - if [[ $InstallToEspOnMac == 1 && "$TargetDir" == '/EFI/BOOT' ]] ; then - echo "You may use --esp OR --usedefault, but not both! Aborting!" + if [[ "$InstallToEspOnMac" == 0 && "$RootDir" == '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then + echo "You may use --notesp OR --usedefault, but not both! Aborting!" exit 1 fi if [[ "$RootDir" != '/' && "$TargetDir" == '/EFI/BOOT' ]] ; then - echo "You may use --usedefault OR --root, but not both! Aborting!" + echo "You may use --root OR --usedefault, but not both! Aborting!" exit 1 fi - if [[ "$RootDir" != '/' && $InstallToEspOnMac == 1 ]] ; then - echo "You may use --root OR --esp, but not both! Aborting!" + if [[ "$TargetDir" != '/System/Library/CoreServices' && "$OwnHfs" == '1' ]] ; then + echo "If you use --ownhfs, you may NOT use --usedefault! Aborting!" exit 1 fi - RLConfFile="$RootDir/boot/refind_linux.conf" EtcKeysDir="$RootDir/etc/refind.d/keys" } # GetParams() @@ -228,6 +244,140 @@ CopyKeys() { fi } # CopyKeys() +# Set varaibles for installation in EFI/BOOT directory +SetVarsForBoot() { + TargetDir="/EFI/BOOT" + if [[ $ShimSource == "none" ]] ; then + TargetX64="bootx64.efi" + TargetIA32="bootia32.efi" + else + if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then + TargetX64="grubx64.efi" + elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then + TargetX64="loader.efi" + else + echo "Unknown shim/PreBootloader type: $ShimType" + echo "Aborting!" + exit 1 + fi + TargetIA32="bootia32.efi" + TargetShim="bootx64.efi" + fi +} # SetVarsForBoot() + +# Set variables for installation in EFI/Microsoft/Boot directory +SetVarsForMsBoot() { + TargetDir="/EFI/Microsoft/Boot" + if [[ $ShimSource == "none" ]] ; then + TargetX64="bootmgfw.efi" + else + if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then + TargetX64="grubx64.efi" + elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then + TargetX64="loader.efi" + else + echo "Unknown shim/PreBootloader type: $ShimType" + echo "Aborting!" + exit 1 + fi + TargetShim="bootmgfw.efi" + fi +} # SetVarsForMsBoot() + +# TargetDir defaults to /EFI/refind; however, this function adjusts it as follows: +# - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot, +# install to that directory under the suitable name; but DO NOT do this if +# refind.conf is also in /EFI/refind. +# - If booted in BIOS mode and the ESP lacks any other EFI files, install to +# /EFI/BOOT +# - If booted in BIOS mode and there's no refind.conf file and there is a +# /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and +# install under that name, "hijacking" the Windows boot loader filename +DetermineTargetDir() { + Upgrade=0 + + if [[ -f $InstallDir/EFI/BOOT/refind.conf ]] ; then + SetVarsForBoot + Upgrade=1 + fi + if [[ -f $InstallDir/EFI/Microsoft/Boot/refind.conf ]] ; then + SetVarsForMsBoot + Upgrade=1 + fi + if [[ -f $InstallDir/EFI/refind/refind.conf ]] ; then + TargetDir="/EFI/refind" + if [[ "$OSName" == 'Darwin' ]] ; then + TargetX64="refind_x64.efi" + TargetIA32="refind_ia32.efi" + fi + Upgrade=1 + fi + if [[ $Upgrade == 1 ]] ; then + echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it." + fi + + if [[ ! -d /sys/firmware/efi && ! $OSName == '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 + mv -n "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" "$InstallDir/EFI/Microsoft" &> /dev/null + SetVarsForMsBoot + echo "Running in BIOS mode with a suspected Windows installation; moving boot loader" + echo "files so as to install to $InstallDir$TargetDir." + elif [[ ! -n "$FoundEfiFiles" ]] ; then # In BIOS mode and no default loader; install as default loader + SetVarsForBoot + echo "Running in BIOS mode with no existing default boot loader; installing to" + echo $InstallDir$TargetDir + else + echo "Running in BIOS mode with an existing default boot loader; backing it up and" + echo "installing rEFInd in its place." + 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 installation (Y/N)? " + ReadYesNo + if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then + echo "OK; continuing with the installation..." + else + exit 0 + fi + fi + mv -n "$InstallDir/EFI/BOOT" "$InstallDir/EFI/BOOT-rEFIndBackup" + SetVarsForBoot + fi + fi # BIOS-mode +} # DetermineTargetDir() + +# Determine (or guess) the filesystem used on the Linux /boot filesystem. +# Store the result in the BootFS global variable. +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 +} # SetBootFS() + # 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). @@ -236,9 +386,8 @@ CopyDrivers() { mkdir -p "$InstallDir/$TargetDir/drivers_$1" cp "$ThisDir"/drivers_$1/*_$1.efi "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null cp "$RefindDir"/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 =` + elif [[ "$InstallDrivers" == "boot" ]] ; then + SetBootFS DriverType="" case $BootFS in ext2 | ext3) DriverType="ext2" @@ -253,6 +402,8 @@ CopyDrivers() { ;; hfsplus) DriverType="hfs" ;; + ntfs) DriverType="ntfs" + ;; *) BootFS="" esac if [[ -n $BootFS ]] ; then @@ -262,13 +413,13 @@ CopyDrivers() { cp "$RefindDir/drivers_$1/${DriverType}_$1.efi" "$InstallDir/$TargetDir/drivers_$1"/ 2> /dev/null fi fi -} +} # CopyDrivers() # Copy tools (currently only gptsync, and that only on Macs) to the EFI/tools # directory on the ESP. Must be passed a suitable architecture code (ia32 # or x64). CopyTools() { - mkdir -p $InstallDir/EFI/tools + mkdir -p "$InstallDir/EFI/tools" if [[ $OSName == 'Darwin' ]] ; then cp -f "$RefindDir/tools_$1/gptsync_$1.efi" "$InstallDir/EFI/tools/" if [[ -f "$InstallDir/EFI/tools/gptsync.efi" ]] ; then @@ -298,7 +449,7 @@ CopyRefindFiles() { if [[ $InstallDrivers == "all" ]] ; then cp -r "$RefindDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null cp -r "$ThisDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null - elif [[ $Upgrade == 1 ]] ; then + elif [[ $Upgrade == 1 || $InstallToEspOnMac == 1 ]] ; then if [[ $Platform == 'EFI64' ]] ; then CopyDrivers x64 CopyTools x64 @@ -308,6 +459,11 @@ CopyRefindFiles() { fi fi Refind="" + if [[ $Platform == 'EFI64' ]] ; then + Refind='bootx64.efi' + elif [[ $Platform == 'EFI32' ]] ; then + Refind='bootia32.efi' + fi CopyKeys elif [[ $Platform == 'EFI64' || $TargetDir == "/EFI/Microsoft/Boot" ]] ; then cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64" @@ -331,6 +487,9 @@ CopyRefindFiles() { cp "$ThisDir/keys/refind.crt" "$EtcKeysDir" 2> /dev/null fi fi + if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then + SetupMacHfs $TargetX64 + fi elif [[ $Platform == 'EFI32' ]] ; then cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" if [[ $? != 0 ]] ; then @@ -339,6 +498,9 @@ CopyRefindFiles() { CopyDrivers ia32 CopyTools ia32 Refind="refind_ia32.efi" + if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then + SetupMacHfs $TargetIA32 + fi else echo "Unknown platform! Aborting!" exit 1 @@ -380,12 +542,24 @@ CopyRefindFiles() { fi } # CopyRefindFiles() -# Mount the partition the user specified with the --usedefault option +# Mount the partition the user specified with the --usedefault or --ownhfs option MountDefaultTarget() { InstallDir=/tmp/refind_install mkdir -p "$InstallDir" + UnmountEsp=1 if [[ $OSName == 'Darwin' ]] ; then - mount -t msdos "$TargetPart" "$InstallDir" + if [[ $OwnHfs == '1' ]] ; then + Temp=`diskutil info "$TargetPart" | grep "Mount Point"` + InstallDir=`echo $Temp | cut -f 3-30 -d ' '` + if [[ $InstallDir == '' ]] ; then + InstallDir=/tmp/refind_install + mount -t hfs "$TargetPart" "$InstallDir" + else + UnmountEsp=0 + fi + else + mount -t msdos "$TargetPart" "$InstallDir" + fi elif [[ $OSName == 'Linux' ]] ; then mount -t vfat "$TargetPart" "$InstallDir" fi @@ -394,7 +568,6 @@ MountDefaultTarget() { rmdir "$InstallDir" exit 1 fi - UnmountEsp=1 } # MountDefaultTarget() # @@ -408,39 +581,92 @@ MountDefaultTarget() { MountOSXESP() { # Identify the ESP. Note: This returns the FIRST ESP found; # if the system has multiple disks, this could be wrong! - Temp=`diskutil list | grep " EFI "` - Esp=/dev/`echo $Temp | cut -f 5 -d ' '` + Temp=$(mount | sed -n -E "/^(\/dev\/disk[0-9]+s[0-9]+) on \/ \(.*$/s//\1/p") + if [ $Temp ]; then + Temp=$(diskutil list | grep " EFI " | grep -o 'disk.*' | head -n 1) + if [ -z $Temp ]; then + echo "Warning: root device doesn't have an EFI partition" + fi + else + echo "Warning: root device could not be found" + fi + if [ -z $Temp ]; then + Temp=$(diskutil list | sed -n -E '/^ *[0-9]+:[ ]+EFI EFI[ ]+[0-9.]+ [A-Z]+[ ]+(disk[0-9]+s[0-9]+)$/ { s//\1/p + q + }' ) + + if [ -z $Temp ]; then + echo "Could not find an EFI partition. Aborting!" + exit 1 + fi + fi + Esp=/dev/`echo $Temp` # If the ESP is mounted, use its current mount point.... - Temp=`df | 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 + # Some systems have HFS+ "ESPs." They shouldn't, but they do. If this is + # detected, mount it as such and set appropriate options. if [[ $? != 0 ]] ; then - echo "Unable to mount ESP! Aborting!\n" - exit 1 + mount -t hfs "$Esp" /Volumes/Esp + OwnHfs=1 + InstallToEspOnMac=0 + if [[ $? != 0 ]] ; then + echo "Unable to mount ESP! Aborting!\n" + exit 1 + fi fi UnmountEsp=1 InstallDir="/Volumes/ESP" fi } # MountOSXESP() +# Set up for booting from Mac HFS+ volume that boots rEFInd in MJG's way +# (http://mjg59.dreamwidth.org/7468.html) +# Must be passed the original rEFInd binary filename (without a path). +SetupMacHfs() { + if [[ -s "$InstallDir/mach_kernel" ]] ; then + echo "Attempt to install rEFInd to a partition with a /mach_kernel file! Aborting!" + exit 1 + fi + cp -n "$InstallDir/$TargetDir/boot.efi" "$InstallDir/$TargetDir/boot.efi-backup" &> /dev/null + ln -f "$InstallDir/$TargetDir/$1" "$InstallDir/$TargetDir/boot.efi" + touch "$InstallDir/mach_kernel" + rm "$InstallDir/$TargetDir/SystemVersion.plist" &> /dev/null + cat - << ENDOFHERE >> "$InstallDir/$TargetDir/SystemVersion.plist" + + + + ProductBuildVersion + + ProductName + rEFInd + ProductVersion + 0.8.5 + + +ENDOFHERE +} # SetupMacHfs() + # Control the OS X installation. # Sets Problems=1 if problems found during the installation. InstallOnOSX() { echo "Installing rEFInd on OS X...." - if [[ "$TargetDir" == "/EFI/BOOT" ]] ; then - MountDefaultTarget - elif [[ "$InstallToEspOnMac" == "1" ]] ; then + if [[ "$InstallToEspOnMac" == "1" ]] ; then MountOSXESP + elif [[ "$TargetDir" == "/EFI/BOOT" || "$OwnHfs" == '1' ]] ; then + MountDefaultTarget else InstallDir="$RootDir/" fi echo "Installing rEFInd to the partition mounted at $InstallDir" + DetermineTargetDir 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 @@ -623,33 +849,80 @@ ReSignBinaries() { IFS=$SaveIFS RefindDir="$TempDir" DeleteRefindDir=1 -} +} # ReSignBinaries() + +# Locate and mount an ESP, if possible, based on parted output. +# Should be called only if /boot/efi is NOT an acceptable ESP. +# Sets InstallDir to the mounted ESP's path ($RootDir/boot/efi) +# and EspFilesystem the filesystem (always "vfat") +FindLinuxESP() { + echo "The ESP doesn't seem to be mounted! Trying to find it...." + local Drive + local PartNum + local TableType + local DmStatus + local SkipIt + local Dmraid + for Drive in `ls /dev/[sh]d?` ; do + SkipIt=0 + Dmraid=`which dmraid 2> /dev/null` + if [ -x "$Dmraid" ] ; then + DmStatus=`dmraid -r | grep $Drive` + if [ -n "$DmStatus" ] ; then + echo "$Drive seems to be part of a RAID array; skipping!" + SkipIt=1 + fi + fi + TableType=`parted $Drive print -m -s 2>/dev/null | awk -F: '$1 == "'$Drive'" { print $6 }'` + if [[ $TableType == 'gpt' && $SkipIt == 0 ]] ; then # read only GPT disks that aren't part of dmraid array + PartNum=`LANG=C parted $Drive print -m -s 2>/dev/null | awk -F: '$7 ~ "(^boot| boot)" { print $1 }' | head -n 1` + if [ "$PartNum" -eq "$PartNum" ] 2> /dev/null ; then + InstallDir="$RootDir/boot/efi" + mkdir -p $InstallDir + mount $Drive$PartNum $InstallDir + EspFilesystem=`grep "$Drive$PartNum.*/boot/efi" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3` + if [[ $EspFilesystem != 'vfat' ]] ; then + umount $InstallDir + else + echo "Mounting ESP at $InstallDir" + break; + fi + fi # $PartNum -eq $PartNum + fi # TableType + done +} # FindLinuxESP() # 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() { +FindMountedESP() { + mount /boot &> /dev/null + mount /boot/efi &> /dev/null 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 | uniq | grep -v autofs | cut -d " " -f 3` + EspFilesystem=`grep -w "$InstallDir" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3` fi - echo "EspFilesystem is '$EspFilesystem'" if [[ $EspFilesystem != 'vfat' ]] ; then - echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be" + FindLinuxESP + fi + if [[ $EspFilesystem != 'vfat' ]] ; then + echo "$RootDir/$InstallDir 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" -} # FindLinuxESP +} # FindMountedESP # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM. # If this fails, sets Problems=1 AddBootEntry() { + local PartNum InstallIt="0" Efibootmgr=`which efibootmgr 2> /dev/null` if [[ "$Efibootmgr" ]] ; then @@ -695,6 +968,8 @@ AddBootEntry() { echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi" echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!" echo + else + echo "rEFInd has been set as the default boot manager." fi } # AddBootEntry() @@ -703,138 +978,41 @@ GenerateRefindLinuxConf() { if [[ -f "$RLConfFile" ]] ; then echo "Existing $RLConfFile found; not overwriting." else + echo "Creating $RLConfFile; edit it to adjust kernel options." if [[ -f "$RootDir/etc/default/grub" ]] ; then # We want the default options used by the distribution, stored here.... source "$RootDir/etc/default/grub" + echo "Setting default boot options based on $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=` + Uuid=`blkid -o export -s UUID "$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 -} - -# Set varaibles for installation in EFI/BOOT directory -SetVarsForBoot() { - TargetDir="/EFI/BOOT" - if [[ $ShimSource == "none" ]] ; then - TargetX64="bootx64.efi" - TargetIA32="bootia32.efi" - else - if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then - TargetX64="grubx64.efi" - elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then - TargetX64="loader.efi" - else - echo "Unknown shim/PreBootloader type: $ShimType" - echo "Aborting!" - exit 1 - fi - TargetIA32="bootia32.efi" - TargetShim="bootx64.efi" - fi -} # SetFilenamesForBoot() - -# Set variables for installation in EFI/Microsoft/Boot directory -SetVarsForMsBoot() { - TargetDir="/EFI/Microsoft/Boot" - if [[ $ShimSource == "none" ]] ; then - TargetX64="bootmgfw.efi" - else - if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then - TargetX64="grubx64.efi" - elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then - TargetX64="loader.efi" - else - echo "Unknown shim/PreBootloader type: $ShimType" - echo "Aborting!" - exit 1 - fi - TargetShim="bootmgfw.efi" + 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 } -# TargetDir defaults to /EFI/refind; however, this function adjusts it as follows: -# - If an existing refind.conf is available in /EFI/BOOT or /EFI/Microsoft/Boot, -# install to that directory under the suitable name; but DO NOT do this if -# refind.conf is also in /EFI/refind. -# - If booted in BIOS mode and the ESP lacks any other EFI files, install to -# /EFI/BOOT -# - If booted in BIOS mode and there's no refind.conf file and there is a -# /EFI/Microsoft/Boot/bootmgfw.efi file, move it down one level and -# install under that name, "hijacking" the Windows boot loader filename -DetermineTargetDir() { - Upgrade=0 - - if [[ -f $InstallDir/EFI/BOOT/refind.conf ]] ; then - SetVarsForBoot - Upgrade=1 - fi - if [[ -f $InstallDir/EFI/Microsoft/Boot/refind.conf ]] ; then - SetVarsForMsBoot - Upgrade=1 - fi - if [[ -f $InstallDir/EFI/refind/refind.conf ]] ; then - TargetDir="/EFI/refind" - Upgrade=1 - fi - if [[ $Upgrade == 1 ]] ; then - echo "Found rEFInd installation in $InstallDir$TargetDir; upgrading it." - fi - - if [[ ! -d /sys/firmware/efi && $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 - mv -n "$InstallDir/EFI/Microsoft/Boot/bootmgfw.efi" "$InstallDir/EFI/Microsoft" &> /dev/null - SetVarsForMsBoot - echo "Running in BIOS mode with a suspected Windows installation; moving boot loader" - echo "files so as to install to $InstallDir$TargetDir." - elif [[ ! -n "$FoundEfiFiles" ]] ; then # In BIOS mode and no default loader; install as default loader - SetVarsForBoot - echo "Running in BIOS mode with no existing default boot loader; installing to" - echo $InstallDir$TargetDir - else - echo "Running in BIOS mode with an existing default boot loader; backing it up and" - echo "installing rEFInd in its place." - 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 installation (Y/N)? " - ReadYesNo - if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then - echo "OK; continuing with the installation..." - else - exit 0 - fi - fi - mv -n "$InstallDir/EFI/BOOT" "$InstallDir/EFI/BOOT-rEFIndBackup" - SetVarsForBoot - fi - fi # BIOS-mode -} # DetermineTargetDir() - # Controls rEFInd installation under Linux. # Sets Problems=1 if something goes wrong. InstallOnLinux() { + if [[ "$TargetDir" == "/System/Library/CoreServices" ]] ; then + echo "You may not use the --ownhfs option under Linux! Aborting!" + exit 1 + fi echo "Installing rEFInd on Linux...." modprobe efivars &> /dev/null if [[ $TargetDir == "/EFI/BOOT" ]] ; then MountDefaultTarget else - FindLinuxESP + FindMountedESP DetermineTargetDir fi CpuType=`uname -m` @@ -891,7 +1069,6 @@ 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 )" @@ -922,6 +1099,10 @@ 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 if [[ $Problems ]] ; then @@ -937,7 +1118,7 @@ else echo fi -if [[ $UnmountEsp ]] ; then +if [[ $UnmountEsp == '1' ]] ; then echo "Unmounting install dir" umount $InstallDir fi