]> code.delx.au - refind/blob - install.sh
Modified install.sh script to include "--usedefault" and "--drivers"
[refind] / install.sh
1 #!/bin/bash
2 #
3 # Linux/MacOS X script to install rEFInd
4 #
5 # Usage:
6 #
7 # ./install.sh [esp]
8 #
9 # The "esp" option is valid only on Mac OS X; it causes
10 # installation to the EFI System Partition (ESP) rather than
11 # to the current OS X boot partition. Under Linux, this script
12 # installs to the ESP by default.
13 #
14 # This program is copyright (c) 2012 by Roderick W. Smith
15 # It is released under the terms of the GNU GPL, version 3,
16 # a copy of which should be included in the file COPYING.txt.
17 #
18 # Revision history:
19 #
20 # 0.4.8 -- Added --usedefault & --drivers options & changed "esp" option to "--esp"
21 # 0.4.5 -- Fixed check for rEFItBlesser in OS X
22 # 0.4.2 -- Added notice about BIOS-based OSes & made NVRAM changes in Linux smarter
23 # 0.4.1 -- Added check for rEFItBlesser in OS X
24 # 0.3.3.1 -- Fixed OS X 10.7 bug; also works as make target
25 # 0.3.2.1 -- Check for presence of source files; aborts if not present
26 # 0.3.2 -- Initial version
27 #
28 # Note: install.sh version numbers match those of the rEFInd package
29 # with which they first appeared.
30
31 TargetDir=/EFI/refind
32
33 #
34 # Functions used by both OS X and Linux....
35 #
36
37 GetParams() {
38 InstallToEspOnMac=0
39 InstallDrivers=0
40 while [[ $# -gt 0 ]]; do
41 case $1 in
42 --esp | --ESP) InstallToEspOnMac=1
43 ;;
44 --usedefault) TargetDir=/EFI/BOOT
45 TargetPart=$2
46 shift
47 ;;
48 --drivers) InstallDrivers=1
49 ;;
50 * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--drivers]"
51 echo "Aborting!"
52 exit 1
53 esac
54 shift
55 done
56 if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then
57 echo "You may use --esp OR --usedefault, but not both! Aborting!"
58 exit 1
59 fi
60 # exit 1
61 } # GetParams()
62
63 # Abort if the rEFInd files can't be found.
64 # Also sets $ConfFile to point to the configuration file, and
65 # $IconsDir to point to the icons directory
66 CheckForFiles() {
67 # Note: This check is satisfied if EITHER the 32- or the 64-bit version
68 # is found, even on the wrong platform. This is because the platform
69 # hasn't yet been determined. This could obviously be improved, but it
70 # would mean restructuring lots more code....
71 if [[ ! -f $RefindDir/refind_ia32.efi && ! -f $RefindDir/refind_x64.efi ]] ; then
72 echo "The rEFInd binary file is missing! Aborting installation!"
73 exit 1
74 fi
75
76 if [[ -f $RefindDir/refind.conf-sample ]] ; then
77 ConfFile=$RefindDir/refind.conf-sample
78 elif [[ -f $ThisDir/refind.conf-sample ]] ; then
79 ConfFile=$ThisDir/refind.conf-sample
80 else
81 echo "The sample configuration file is missing! Aborting installation!"
82 exit 1
83 fi
84
85 if [[ -d $RefindDir/icons ]] ; then
86 IconsDir=$RefindDir/icons
87 elif [[ -d $ThisDir/icons ]] ; then
88 IconsDir=$ThisDir/icons
89 else
90 echo "The icons directory is missing! Aborting installation!"
91 fi
92 } # CheckForFiles()
93
94 # Copy the rEFInd files to the ESP or OS X root partition.
95 # Sets Problems=1 if any critical commands fail.
96 CopyRefindFiles() {
97 mkdir -p $InstallDir/$TargetDir &> /dev/null
98 if [[ $TargetDir == '/EFI/BOOT' ]] ; then
99 cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir/bootia32.efi 2> /dev/null
100 if [[ $? != 0 ]] ; then
101 echo "Note: IA32 (x86) binary not installed!"
102 fi
103 cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir/bootx64.efi 2> /dev/null
104 if [[ $? != 0 ]] ; then
105 Problems=1
106 fi
107 if [[ $InstallDrivers == 1 ]] ; then
108 cp -r $RefindDir/drivers_* $InstallDir/$TargetDir/
109 fi
110 Refind=""
111 elif [[ $Platform == 'EFI32' ]] ; then
112 cp $RefindDir/refind_ia32.efi $InstallDir/$TargetDir
113 if [[ $? != 0 ]] ; then
114 Problems=1
115 fi
116 if [[ $InstallDrivers == 1 ]] ; then
117 mkdir -p $InstallDir/$TargetDir/drivers_ia32
118 cp -r $RefindDir/drivers_ia32/*_ia32.efi $InstallDir/$TargetDir/drivers_ia32/
119 fi
120 Refind="refind_ia32.efi"
121 elif [[ $Platform == 'EFI64' ]] ; then
122 cp $RefindDir/refind_x64.efi $InstallDir/$TargetDir
123 if [[ $? != 0 ]] ; then
124 Problems=1
125 fi
126 if [[ $InstallDrivers == 1 ]] ; then
127 mkdir -p $InstallDir/$TargetDir/drivers_x64
128 cp -r $RefindDir/drivers_x64/*_x64.efi $InstallDir/$TargetDir/drivers_x64/
129 fi
130 Refind="refind_x64.efi"
131 else
132 echo "Unknown platform! Aborting!"
133 exit 1
134 fi
135 echo "Copied rEFInd binary file $Refind"
136 echo ""
137 if [[ -d $InstallDir/$TargetDir/icons ]] ; then
138 rm -rf $InstallDir/$TargetDir/icons-backup &> /dev/null
139 mv -f $InstallDir/$TargetDir/icons $InstallDir/$TargetDir/icons-backup
140 echo "Notice: Backed up existing icons directory as icons-backup."
141 fi
142 cp -r $IconsDir $InstallDir/$TargetDir
143 if [[ $? != 0 ]] ; then
144 Problems=1
145 fi
146 if [[ -f $InstallDir/$TargetDir/refind.conf ]] ; then
147 echo "Existing refind.conf file found; copying sample file as refind.conf-sample"
148 echo "to avoid collision."
149 echo ""
150 cp -f $ConfFile $InstallDir/$TargetDir
151 if [[ $? != 0 ]] ; then
152 Problems=1
153 fi
154 else
155 echo "Copying sample configuration file as refind.conf; edit this file to configure"
156 echo "rEFInd."
157 echo ""
158 cp -f $ConfFile $InstallDir/$TargetDir/refind.conf
159 if [[ $? != 0 ]] ; then
160 Problems=1
161 fi
162 fi
163 } # CopyRefindFiles()
164
165 # Mount the partition the user specified with the --usedefault option
166 MountDefaultTarget() {
167 InstallDir=/tmp/refind_install
168 mkdir -p $InstallDir
169 if [[ $OSName == 'Darwin' ]] ; then
170 mount -t msdos $TargetPart $InstallDir
171 elif [[ $OSName == 'Linux' ]] ; then
172 mount -t vfat $TargetPart $InstallDir
173 fi
174 if [[ $? != 0 ]] ; then
175 echo "Couldn't mount $TargetPart ! Aborting!"
176 rmdir $InstallDir
177 exit 1
178 fi
179 UnmountEsp=1
180 } # MountDefaultTarget()
181
182 #
183 # A series of OS X support functions....
184 #
185
186 # Mount the ESP at /Volumes/ESP or determine its current mount
187 # point.
188 # Sets InstallDir to the ESP mount point
189 # Sets UnmountEsp if we mounted it
190 MountOSXESP() {
191 # Identify the ESP. Note: This returns the FIRST ESP found;
192 # if the system has multiple disks, this could be wrong!
193 Temp=`diskutil list | grep " EFI "`
194 Esp=/dev/`echo $Temp | cut -f 5 -d ' '`
195 # If the ESP is mounted, use its current mount point....
196 Temp=`df | grep $Esp`
197 InstallDir=`echo $Temp | cut -f 6 -d ' '`
198 if [[ $InstallDir == '' ]] ; then
199 mkdir /Volumes/ESP &> /dev/null
200 mount -t msdos $Esp /Volumes/ESP
201 if [[ $? != 0 ]] ; then
202 echo "Unable to mount ESP! Aborting!\n"
203 exit 1
204 fi
205 UnmountEsp=1
206 InstallDir="/Volumes/ESP"
207 fi
208 } # MountOSXESP()
209
210 # Control the OS X installation.
211 # Sets Problems=1 if problems found during the installation.
212 InstallOnOSX() {
213 echo "Installing rEFInd on OS X...."
214 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
215 MountDefaultTarget
216 elif [[ $InstallToEspOnMac == "1" ]] ; then
217 MountOSXESP
218 else
219 InstallDir="/"
220 fi
221 echo "Installing rEFInd to the partition mounted at '$InstallDir'"
222 Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4`
223 CopyRefindFiles
224 if [[ $InstallToEspOnMac == "1" ]] ; then
225 bless --mount $InstallDir --setBoot --file $InstallDir/$TargetDir/$Refind
226 elif [[ $TargetDir != "/EFI/BOOT" ]] ; then
227 bless --setBoot --folder $InstallDir/$TargetDir --file $InstallDir/$TargetDir/$Refind
228 fi
229 if [[ $? != 0 ]] ; then
230 Problems=1
231 fi
232 if [[ -f /Library/StartupItems/rEFItBlesser || -d /Library/StartupItems/rEFItBlesser ]] ; then
233 echo
234 echo "/Library/StartupItems/rEFItBlesser found!"
235 echo "This program is part of rEFIt, and will cause rEFInd to fail to work after"
236 echo -n "its first boot. Do you want to remove rEFItBlesser (Y/N)? "
237 read YesNo
238 if [[ $YesNo == "Y" || $YesNo == "y" ]] ; then
239 echo "Deleting /Library/StartupItems/rEFItBlesser..."
240 rm -r /Library/StartupItems/rEFItBlesser
241 else
242 echo "Not deleting rEFItBlesser."
243 fi
244 fi
245 echo
246 echo "WARNING: If you have an Advanced Format disk, *DO NOT* attempt to check the"
247 echo "bless status with 'bless --info', since this is known to cause disk corruption"
248 echo "on some systems!!"
249 echo
250 } # InstallOnOSX()
251
252
253 #
254 # Now a series of Linux support functions....
255 #
256
257 # Identifies the ESP's location (/boot or /boot/efi); aborts if
258 # the ESP isn't mounted at either location.
259 # Sets InstallDir to the ESP mount point.
260 FindLinuxESP() {
261 EspLine=`df /boot/efi | grep boot`
262 InstallDir=`echo $EspLine | cut -d " " -f 6`
263 EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3`
264 if [[ $EspFilesystem != 'vfat' ]] ; then
265 echo "/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be mounted at"
266 echo "/boot or /boot/efi and it must be VFAT! Aborting!"
267 exit 1
268 fi
269 echo "ESP was found at $InstallDir using $EspFilesystem"
270 } # MountLinuxESP
271
272 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
273 # If this fails, sets Problems=1
274 AddBootEntry() {
275 InstallIt="0"
276 Efibootmgr=`which efibootmgr 2> /dev/null`
277 if [[ $Efibootmgr ]] ; then
278 modprobe efivars &> /dev/null
279 InstallDisk=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 1-8`
280 PartNum=`grep $InstallDir /etc/mtab | cut -d " " -f 1 | cut -c 9-10`
281 EntryFilename=$TargetDir/$Refind
282 EfiEntryFilename=`echo ${EntryFilename//\//\\\}`
283 EfiEntryFilename2=`echo ${EfiEntryFilename} | sed s/\\\\\\\\/\\\\\\\\\\\\\\\\/g`
284 ExistingEntry=`$Efibootmgr -v | grep $EfiEntryFilename2`
285 if [[ $ExistingEntry ]] ; then
286 ExistingEntryBootNum=`echo $ExistingEntry | cut -c 5-8`
287 FirstBoot=`$Efibootmgr | grep BootOrder | cut -c 12-15`
288 if [[ $ExistingEntryBootNum != $FirstBoot ]] ; then
289 echo "An existing rEFInd boot entry exists, but isn't set as the default boot"
290 echo "manager. The boot order is being adjusted to make rEFInd the default boot"
291 echo "manager. If this is NOT what you want, you should use efibootmgr to"
292 echo "manually adjust your EFI's boot order."
293 $Efibootmgr -b $ExistingEntryBootNum -B &> /dev/null
294 InstallIt="1"
295 fi
296 else
297 InstallIt="1"
298 fi
299 if [[ $InstallIt == "1" ]] ; then
300 echo "Installing it!"
301 $Efibootmgr -c -l $EfiEntryFilename -L rEFInd -d $InstallDisk -p $PartNum &> /dev/null
302 if [[ $? != 0 ]] ; then
303 EfibootmgrProblems=1
304 Problems=1
305 fi
306 fi
307 else
308 EfibootmgrProblems=1
309 Problems=1
310 fi
311 if [[ $EfibootmgrProblems ]] ; then
312 echo
313 echo "ALERT: There were problems running the efibootmgr program! You may need to"
314 echo "rename the $Refind binary to the default name (EFI/boot/bootx64.efi"
315 echo "on x86-64 systems or EFI/boot/bootia32.efi on x86 systems) to have it run!"
316 echo
317 fi
318 } # AddBootEntry()
319
320 # Controls rEFInd installation under Linux.
321 # Sets Problems=1 if something goes wrong.
322 InstallOnLinux() {
323 echo "Installing rEFInd on Linux...."
324 if [[ $TargetDir == "/EFI/BOOT" ]] ; then
325 MountDefaultTarget
326 else
327 FindLinuxESP
328 fi
329 CpuType=`uname -m`
330 if [[ $CpuType == 'x86_64' ]] ; then
331 Platform="EFI64"
332 elif [[ $CpuType == 'i386' || $CpuType == 'i486' || $CpuType == 'i586' || $CpuType == 'i686' ]] ; then
333 Platform="EFI32"
334 echo
335 echo "CAUTION: This Linux installation uses a 32-bit kernel. 32-bit EFI-based"
336 echo "computers are VERY RARE. If you've installed a 32-bit version of Linux"
337 echo "on a 64-bit computer, you should manually install the 64-bit version of"
338 echo "rEFInd. If you're installing on a Mac, you should do so from OS X. If"
339 echo "you're positive you want to continue with this installation, answer 'Y'"
340 echo "to the following question..."
341 echo
342 echo -n "Are you sure you want to continue (Y/N)? "
343 read ContYN
344 if [[ $ContYN == "Y" || $ContYN == "y" ]] ; then
345 echo "OK; continuing with the installation..."
346 else
347 exit 0
348 fi
349 else
350 echo "Unknown CPU type '$CpuType'; aborting!"
351 exit 1
352 fi
353 CopyRefindFiles
354 if [[ $TargetDir != "/EFI/BOOT" ]] ; then
355 AddBootEntry
356 fi
357 } # InstallOnLinux()
358
359 #
360 # The main part of the script. Sets a few environment variables,
361 # performs a few startup checks, and then calls functions to
362 # install under OS X or Linux, depending on the detected platform.
363 #
364
365 GetParams $@
366 OSName=`uname -s`
367 ThisDir="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
368 RefindDir="$ThisDir/refind"
369 ThisScript="$ThisDir/`basename $0`"
370 CheckForFiles
371 if [[ `whoami` != "root" ]] ; then
372 echo "Not running as root; attempting to elevate privileges via sudo...."
373 sudo $ThisScript $1 $2 $3
374 if [[ $? != 0 ]] ; then
375 echo "This script must be run as root (or using sudo). Exiting!"
376 exit 1
377 else
378 exit 0
379 fi
380 fi
381 if [[ $OSName == 'Darwin' ]] ; then
382 InstallOnOSX $1
383 elif [[ $OSName == 'Linux' ]] ; then
384 InstallOnLinux
385 else
386 echo "Running on unknown OS; aborting!"
387 fi
388
389 if [[ $Problems ]] ; then
390 echo
391 echo "ALERT:"
392 echo "Installation has completed, but problems were detected. Review the output for"
393 echo "error messages and take corrective measures as necessary. You may need to"
394 echo "re-run this script or install manually before rEFInd will work."
395 echo
396 else
397 echo
398 echo "Installation has completed successfully."
399 echo
400 fi
401
402 if [[ $UnmountEsp ]] ; then
403 echo "Unmounting install dir"
404 umount $InstallDir
405 fi
406
407 if [[ $InstallDir == /tmp/refind_install ]] ; then
408 # sleep 5
409 rmdir $InstallDir
410 fi