X-Git-Url: https://code.delx.au/refind/blobdiff_plain/d6bcf1a6b2941929a65134c592ed134a07bc560d..508d89056f8675d0d664493fc82a574119e6f60a:/refind-install diff --git a/refind-install b/refind-install index b399c7f..19da6a0 100755 --- a/refind-install +++ b/refind-install @@ -31,11 +31,21 @@ # installs to the ESP by default. # # 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. # +# This program is licensed under the terms of the GNU GPL, version 3, +# or (at your option) any later version. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + # Revision history: # +# 0.10.4 -- Improved handling of disks (other than /dev/[sh]d? disks). +# 0.10.2 -- Improved Secure Boot detection in Linux, fixed --usedefault in OS X, +# and fixed bug that could cause mountesp to be installed as a FILE +# called /usr/local/bin in OS X. +# 0.10.1 -- Improve extraction of default kernel options from /proc/cmdline. +# Add support for AMD64 (aka AARCH64, aa64) platform. Added +# warning when --alldrivers used without --usedefault. # 0.10.0 -- Enable running under OS X's recovery system & add warning about # SIP & brief instructions on how to deal with it if SIP is # detected to be enabled. Also change way refind_linux.conf default @@ -176,6 +186,17 @@ GetParams() { echo "The --keepname option is incompatible with --usedefault! Aborting!" exit 1 fi + if [[ "$InstallDrivers" == "all" && "$TargetDir" != "/EFI/BOOT" ]] ; then + echo "The --alldrivers option is meant for creating USB flash drives with (near-)" + echo "universal boot support. Using it on a hard disk partition runs the risk of" + echo "creating serious problems, up to and including rendering your computer" + echo -n "unbootable. Are you SURE you want to proceed (Y/N)? " + ReadYesNo + if [[ "$YesNo" != "Y" && "$YesNo" != "y" ]] ; then + echo "Aborting installation!" + exit 0 + fi + fi RLConfFile="$RootDir/boot/refind_linux.conf" EtcKeysDir="$RootDir/etc/refind.d/keys" } # GetParams() @@ -192,6 +213,71 @@ ReadYesNo() { fi } +# Determine what CPU type and EFI bit depth we're using. +# Sets Platform global variable to lowercase EFI platform code (currently +# "x64", "ia32", or "aa64") -- the same code used in filenames. +DeterminePlatform() { + local CpuType + case "$OSTYPE" in + darwin*) + CpuType=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4` + if [[ "$CpuType" == EFI32 ]] ; then + Platform="ia32" + else + Platform="x64" + fi + ;; + linux*) + CpuType=`uname -m` + case "$CpuType" in + aarch64) + Platform="aa64" + ;; + x86_64) + Platform="x64" + ;; + i?86) + Platform="ia32" + # If we're in EFI mode, do some sanity checks, and alert the user or even + # abort. Not in BIOS mode, though, since that could be used on an emergency + # disc to try to recover a troubled Linux installation. + if [[ -d /sys/firmware/efi ]] ; then + if [[ "$ShimSource" != "none" && "$TargetDir" != "/BOOT/EFI" ]] ; then + echo "" + echo "CAUTION: shim does not currently supports 32-bit systems, so you should not" + echo "use the --shim option to install on such systems. Aborting!" + echo "" + exit 1 + fi + echo + echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based" + echo "computers are VERY RARE. If you've installed a 32-bit version of Linux" + echo "on a 64-bit computer, you should manually install the 64-bit version of" + echo "rEFInd. If you're positive you want to continue with this installation," + echo "answer 'Y' to the following question..." + echo + echo -n "Are you sure you want to continue (Y/N)? " + ReadYesNo + if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then + echo "OK; continuing with the installation..." + else + exit 0 + fi + fi # In EFI mode + ;; + *) + echo "Unknown CPU type '$CpuType'; aborting!" + exit 1 + ;; + esac # case "$CpuType".... + ;; + *) + echo "Unknown OS; aborting!" + exit 1 + ;; + esac # case "$OSTYPE".... +} # DeterminePlatform() + # Abort if the rEFInd files can't be found. # Also sets $ConfFile to point to the configuration file, # $IconsDir to point to the icons directory, @@ -201,8 +287,8 @@ ReadYesNo() { CheckForFiles() { # Note: $ThisDir points to real (not symlinked) script home on Linux, # enabling creating a symlink in /usr/sbin (or wherever); but on OS X, - # "readlink" doesn't do the right thing, so the script must not be a - # symlink under OS X. + # "readlink" doesn't do the same thing as under Linux, so the script + # must not be a symlink under OS X. case "$OSTYPE" in darwin*) ThisDir="$( cd -P "${BASH_SOURCE%/*}" && pwd )" @@ -212,11 +298,8 @@ CheckForFiles() { ;; esac RefindDir="$ThisDir/refind" - # 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 - # hasn't yet been determined. This could obviously be improved, but it - # would mean restructuring lots more code.... - if [[ ! -f "$RefindDir/refind_ia32.efi" && ! -f "$RefindDir/refind_x64.efi" ]] ; then + + if [[ ! -f "$RefindDir/refind_$Platform.efi" ]] ; then echo "The rEFInd binary file is missing! Aborting installation!" exit 1 fi @@ -244,6 +327,7 @@ CheckForFiles() { if [[ -f "$ShimSource" ]] ; then if [[ $ShimType == "shimx64.efi" || $ShimType == "shim.efi" ]] ; then TargetX64="grubx64.efi" + TargetAARCH64="grubaa64.efi" MokManagerSource=`dirname "$ShimSource"`/MokManager.efi elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then TargetX64="loader.efi" @@ -300,9 +384,11 @@ SetVarsForBoot() { if [[ $ShimSource == "none" ]] ; then TargetX64="bootx64.efi" TargetIA32="bootia32.efi" + TargetAARCH64="bootaa64.efi" else - if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then + if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" || $ShimType = "shimaa64.efi" ]] ; then TargetX64="grubx64.efi" + TargetAARCH64="grubaa64.efi" elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then TargetX64="loader.efi" else @@ -311,7 +397,7 @@ SetVarsForBoot() { exit 1 fi TargetIA32="bootia32.efi" - TargetShim="bootx64.efi" + TargetShim="boot$Platform.efi" fi if [[ $KeepName == 1 ]] ; then echo "Installation is to /EFI/BOOT, which is incompatible with --keepname! Aborting!" @@ -325,9 +411,11 @@ SetVarsForMsBoot() { if [[ $ShimSource == "none" ]] ; then TargetX64="bootmgfw.efi" TargetIA32="bootmgfw.efi" + TargetAARCH64="bootmgfw.efi" else - if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" ]] ; then + if [[ $ShimType == "shim.efi" || $ShimType == "shimx64.efi" || $ShimType == "shimaa64.efi" ]] ; then TargetX64="grubx64.efi" + TargetAARCH64="grubaa64.efi" elif [[ $ShimType == "preloader.efi" || $ShimType == "PreLoader.efi" ]] ; then TargetX64="loader.efi" else @@ -369,6 +457,7 @@ DetermineTargetDir() { if [[ $ShimSource == "none" || $KeepName == 1 ]] ; then TargetX64="refind_x64.efi" TargetIA32="refind_ia32.efi" + TargetAARCH64="refind_aa64.efi" fi Upgrade=1 fi @@ -503,6 +592,10 @@ CopyRefindFiles() { if [[ $? != 0 ]] ; then Problems=1 fi + cp "$RefindDir/refind_aa64.efi" "$InstallDir/$TargetDir/$TargetAARCH64" 2> /dev/null + if [[ $? != 0 && $Platform == "aa64" ]] ; then + Problems=1 + fi if [[ "$ShimSource" != "none" ]] ; then TargetShim="bootx64.efi" CopyShimFiles @@ -511,22 +604,12 @@ CopyRefindFiles() { cp -r "$RefindDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null cp -r "$ThisDir"/drivers_* "$InstallDir/$TargetDir/" 2> /dev/null elif [[ $Upgrade == 1 || $InstallToEspOnMac == 1 ]] ; then - if [[ $Platform == 'EFI64' ]] ; then - CopyDrivers x64 - CopyTools x64 - else - CopyDrivers ia32 - CopyTools ia32 - fi - fi - Refind="" - if [[ $Platform == 'EFI64' ]] ; then - Refind='bootx64.efi' - elif [[ $Platform == 'EFI32' ]] ; then - Refind='bootia32.efi' + CopyDrivers "$Platform" + CopyTools "$Platform" fi + Refind="boot$Platform.efi" CopyKeys - elif [[ $Platform == 'EFI64' || $TargetDir == "/EFI/Microsoft/Boot" ]] ; then + elif [[ $Platform == 'x64' || $TargetDir == "/EFI/Microsoft/Boot" ]] ; then cp "$RefindDir/refind_x64.efi" "$InstallDir/$TargetDir/$TargetX64" if [[ $? != 0 ]] ; then Problems=1 @@ -551,14 +634,21 @@ CopyRefindFiles() { if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then SetupMacHfs $TargetX64 fi - elif [[ $Platform == 'EFI32' ]] ; then - cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" - if [[ $? != 0 ]] ; then - Problems=1 + elif [[ $Platform == 'ia32' || $Platform == 'aa64' ]] ; then + if [[ $Platform == 'ia32' ]] ; then + cp "$RefindDir/refind_ia32.efi" "$InstallDir/$TargetDir/$TargetIA32" + if [[ $? != 0 ]] ; then + Problems=1 + fi + else + cp "$RefindDir/refind_aa64.efi" "$InstallDir/$TargetDir/$TargetAARCH64" + if [[ $? != 0 ]] ; then + Problems=1 + fi fi - CopyDrivers ia32 - CopyTools ia32 - Refind="refind_ia32.efi" + CopyDrivers $Platform + CopyTools $Platform + Refind="refind_$Platform.efi" if [[ "$TargetDir" == '/System/Library/CoreServices' ]] ; then SetupMacHfs $TargetIA32 fi @@ -705,14 +795,14 @@ SetupMacHfs() { ProductName rEFInd ProductVersion - 0.10.0 + 0.10.3 ENDOFHERE } # SetupMacHfs() CheckForSIP() { - if [[ -x "/usr/bin/csrutil" ]] ; then + if [[ -x "/usr/bin/csrutil" && -z "$TargetPart" ]] ; then local OKToInstall=`/usr/bin/csrutil status | \ grep "Protection status: disabled\|enabled (Apple Internal)\|NVRAM Protections: disabled"` if [[ -z "$OKToInstall" ]] ; then @@ -765,7 +855,7 @@ CheckForSIP() { # Sets Problems=1 if problems found during the installation. InstallOnOSX() { echo "Installing rEFInd on OS X...." - if [[ "$InstallToEspOnMac" == "1" ]] ; then + if [[ "$InstallToEspOnMac" == "1" && -z "$TargetPart" ]] ; then MountOSXESP elif [[ "$TargetDir" == "/EFI/BOOT" || "$OwnHfs" == '1' ]] ; then MountDefaultTarget @@ -775,10 +865,10 @@ InstallOnOSX() { echo "Installing rEFInd to the partition mounted at $InstallDir" DetermineTargetDir CheckForSIP - Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4` CopyRefindFiles - cp "$ThisDir/mountesp" /usr/local/bin &> /dev/null - if [[ $InstallToEspOnMac == "1" ]] ; then + mkdir -p /usr/local/bin &> /dev/null + cp "$ThisDir/mountesp" /usr/local/bin/ &> /dev/null + if [[ $InstallToEspOnMac == "1" && -z "$TargetPart" ]] ; then bless --mount "$InstallDir" --setBoot --file "$InstallDir/$TargetDir/$Refind" --shortform elif [[ "$TargetDir" != "/EFI/BOOT" ]] ; then bless --setBoot --folder "$InstallDir/$TargetDir" --file "$InstallDir/$TargetDir/$Refind" @@ -799,11 +889,6 @@ InstallOnOSX() { echo "Not deleting rEFItBlesser." fi fi - echo - echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the" - echo "bless status with 'bless --info', since this is known to cause disk corruption" - echo "on some systems!!" - echo } # InstallOnOSX() @@ -816,11 +901,11 @@ InstallOnOSX() { # 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() { - local IsSecureBoot - if [[ -f /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data ]] ; then + IsSecureBoot="0" + if [[ -f /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c ]] ; then + IsSecureBoot=`od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c | awk '{print substr($0,length,1)}'` + elif [[ -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 "" @@ -920,12 +1005,12 @@ GenerateKeys() { # 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. +# Also assumes that the SBSign and various key variables are set appropriately. # Aborts script on error SignOneBinary() { - $SBSign --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1" - if [[ $? != 0 ]] ; then + $SBSign --key "$PrivateKey" --cert "$CertKey" --output "$2" "$1" 2>&1 >/dev/null | \ + grep -v "data remaining.*gaps between PE/COFF sections" + if [[ "${PIPESTATUS[0]}" != 0 ]] ; then echo "Problem signing the binary $1! Aborting!" exit 1 fi @@ -944,18 +1029,18 @@ ReSignBinaries() { exit 1 fi GenerateKeys - mkdir -p "$TempDir/drivers_x64" + mkdir -p "$TempDir/drivers_$Platform" cp "$RefindDir/refind.conf-sample $TempDir" 2> /dev/null cp "$ThisDir/refind.conf-sample $TempDir" 2> /dev/null cp "$RefindDir/refind_ia32.efi $TempDir" 2> /dev/null 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" + SignOneBinary "$RefindDir/refind_$Platform.efi" "$TempDir/refind_$Platform.efi" SaveIFS=$IFS IFS=$(echo -en "\n\b") - for Driver in `ls "$RefindDir"/drivers_x64/*.efi "$ThisDir"/drivers_x64/*.efi 2> /dev/null` ; do + for Driver in `ls "$RefindDir"/drivers_$Platform/*.efi "$ThisDir"/drivers_$Platform/*.efi 2> /dev/null` ; do TempName=`basename "$Driver"` - SignOneBinary "$Driver" "$TempDir/drivers_x64/$TempName" + SignOneBinary "$Driver" "$TempDir/drivers_$Platform/$TempName" done IFS=$SaveIFS RefindDir="$TempDir" @@ -968,13 +1053,15 @@ ReSignBinaries() { # and EspFilesystem the filesystem (always "vfat") FindLinuxESP() { echo "The ESP doesn't seem to be mounted! Trying to find it...." + local Name local Drive local PartNum local TableType local DmStatus local SkipIt local Dmraid - for Drive in `ls /dev/[sh]d?` ; do + for Name in `lsblk -r | grep disk | cut -f 1 -d " "` ; do + Drive="/dev/$Name" SkipIt=0 Dmraid=`which dmraid 2> /dev/null` if [ -x "$Dmraid" ] ; then @@ -1025,7 +1112,13 @@ FindMountedESP() { 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 + if [[ -d /sys/firmware/efi ]] ; then + exit 1 + else + echo "The computer appears to be running in BIOS mode and has no ESP. You should" + echo "create an ESP, and ideally boot in EFI mode, before installing rEFInd." + exit 0 + fi fi echo "ESP was found at $InstallDir using $EspFilesystem" } # FindMountedESP @@ -1075,8 +1168,9 @@ AddBootEntry() { if [[ $EfibootmgrProblems ]] ; then echo echo "ALERT: There were problems running the efibootmgr program! You may need to" - 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 "rename the $Refind binary to the default name (EFI/BOOT/bootx64.efi" + echo "on x86-64 systems, EFI/BOOT/bootia32.efi on x86 systems, or" + echo "EFI/BOOT/bootaa64.efi on ARM64 systems) to have it run!" echo else echo "rEFInd has been set as the default boot manager." @@ -1099,7 +1193,12 @@ GenerateRefindLinuxConf() { fi fi if [[ $RootDir == "/" ]] ; then - DefaultOptions=`cat /proc/cmdline | cut -d ' ' -f 2- | sed 's/$/ /' | sed 's/initrd=.* //g' | sed 's/ *$//'` + local FirstCmdlineOption=`cat /proc/cmdline | cut -d ' ' -f 1` + if [[ "$FirstCmdlineOption" =~ (vmlinuz|bzImage|kernel) ]] ; then + DefaultOptions=`cat /proc/cmdline | cut -d ' ' -f 2- | sed 's/\S*initrd=\S*//g' | sed 's/ *$//' | sed 's/^ *//'` + else + DefaultOptions=`cat /proc/cmdline | sed 's/\S*initrd=\S*//g' | sed 's/ *$//' | sed 's/^ *//'` + fi else if [[ -f "$RootDir/etc/default/grub" ]] ; then # We want the default options used by the distribution, stored here.... @@ -1129,41 +1228,6 @@ InstallOnLinux() { FindMountedESP DetermineTargetDir fi - CpuType=`uname -m` - if [[ $CpuType == 'x86_64' ]] ; then - Platform="EFI64" - elif [[ ($CpuType == 'i386' || $CpuType == 'i486' || $CpuType == 'i586' || $CpuType == 'i686') ]] ; then - Platform="EFI32" - # If we're in EFI mode, do some sanity checks, and alert the user or even - # abort. Not in BIOS mode, though, since that could be used on an emergency - # disc to try to recover a troubled Linux installation. - if [[ -d /sys/firmware/efi ]] ; then - if [[ "$ShimSource" != "none" && "$TargetDir" != "/BOOT/EFI" ]] ; then - echo "" - echo "CAUTION: shim does not currently supports 32-bit systems, so you should not" - echo "use the --shim option to install on such systems. Aborting!" - echo "" - exit 1 - fi - echo - echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based" - echo "computers are VERY RARE. If you've installed a 32-bit version of Linux" - echo "on a 64-bit computer, you should manually install the 64-bit version of" - echo "rEFInd. If you're positive you want to continue with this installation," - echo "answer 'Y' to the following question..." - echo - echo -n "Are you sure you want to continue (Y/N)? " - ReadYesNo - if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then - echo "OK; continuing with the installation..." - else - exit 0 - fi - fi # in EFI mode - else - echo "Unknown CPU type '$CpuType'; aborting!" - exit 1 - fi if [[ $LocalKeys == 1 ]] ; then ReSignBinaries @@ -1193,6 +1257,7 @@ if [[ $UID != 0 ]] ; then exit 0 fi fi +DeterminePlatform CheckForFiles case "$OSTYPE" in darwin*)