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