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