-0.4.6 (10/??/2012):
--------------------
+0.4.6 (10/6/2012):
+------------------
+
+- Fixed some minor memory management issues.
- Added new "scan_delay" feature to impose a delay before scanning
for disks.
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>\r
\r
<p>Originally written: 3/14/2012; last Web page update:\r
-8/12/2012, referencing rEFInd 0.4.5</p>\r
+10/6/2012, referencing rEFInd 0.4.6</p>\r
\r
\r
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>\r
<hr />
-<p>Many casual users will be able to use rEFInd without making further changes; in its default configuration, the boot manager automatically detects all the EFI boot loader programs you have on your ESP (or your OS X boot partition, in the case of Macs) and displays icons for them. Sometimes, though, you may want to tweak rEFInd's configuration. Sometimes you can obtain your desired results by adjusting the filenames of your boot loaders. Other times, you can edit rEFInd's configuration file, <tt>refind.conf</tt>, which resides in the same directory as its binary file (<tt>refind.efi</tt> or whatever you've renamed it).</p>
+<p>Many casual users will be able to use rEFInd without making changes to its settings; in its default configuration, the boot manager automatically detects all the EFI boot loader programs you have on your ESP (or your OS X boot partition, in the case of Macs) and displays icons for them. On Macs, rEFInd also presents legacy BIOS boot options by default. Sometimes, though, you may want to tweak rEFInd's configuration. Sometimes you can obtain your desired results by adjusting the filenames of your boot loaders. Other times, you can edit rEFInd's configuration file, <tt>refind.conf</tt>, which resides in the same directory as its binary file (<tt>refind.efi</tt> or whatever you've renamed it).</p>
<p>Broadly speaking, rEFInd's configuration file is broken down into two sections: <i>global options</i> and <i>OS stanzas.</i> The global options section sets options that apply globally—to set the timeout period, enable graphics or text mode, and so on. OS stanzas are optional, but if present, they enable you to add new boot options or replace the auto-detected options with customized ones. Both sections include configuration lines and comment lines, the latter being denoted by a leading hash mark (<tt>#</tt>). rEFInd ignores comment lines, so you can add explanatory text. The default configuration file includes numerous comments explaining each of the options.</p>
<p class="sidebar">ESPs use the FAT filesystem, which is case-insensitive. Unfortunately, at least one EFI implementation (Gigabyte's <a href="http://www.rodsbooks.com/gb-hybrid-efi/">Hybrid EFI</a>) contains a bug that causes string comparisons that should be case-insensitive to actually be done in a case-sensitive way. This can cause files that are present to appear to be missing. rEFInd includes code to work around this bug in some situations, but not in all of them. If boot loaders appear to be missing, try changing the case on their filenames or on the <tt>EFI</tt> directory in the ESP. (It's coded as uppercase in rEFInd; but EFI loader filename extensions are coded as lowercase <tt>.efi</tt>. I made these choices because they seem to be the most common uses on real-world installations.)</p>
-<p>Before delving into the configuration file, you should be aware of what you can do by renaming files. By default, rEFInd scans all the filesystems it can read for boot loaders. It scans most of the subdirectories of the <tt>EFI</tt> directory on every filesystem it can access for files with names that end in <tt>.efi</tt>. (rEFIt gives special treatment to the <tt>TOOLS</tt> subdirectory, where it looks for system tools rather than boot loaders.)</p>
+<p>Before delving into the configuration file, you should be aware of what you can do by renaming files. By default, rEFInd scans all the filesystems it can read for boot loaders. It scans most of the subdirectories of the <tt>EFI</tt> directory on every filesystem it can access for files with names that end in <tt>.efi</tt>. (rEFInd gives special treatment to the <tt>tools</tt> subdirectory, where it looks for system tools rather than boot loaders.)</p>
<p>If you're like me, you may sometimes want to hide a boot loader from rEFInd's menu for a brief period—say, because you're testing a variety of configurations but you don't want them all to clutter the menu at once. You might also want to hide a boot loader if you want to override its default settings using a custom entry in <tt>refind.conf</tt> and you don't want an automatic search to duplicate that entry. You can easily hide a boot loader by removing or changing its <tt>.efi</tt> filename extension—for instance, changing <tt>grub.efi</tt> to <tt>grub</tt>.</p>
<tr>
<td><tt>scan_driver_dirs</tt></td>
<td>directory path(s)</td>
- <td>Scans the specified directory or directories for EFI driver files. If rEFInd discovers <tt>.efi</tt> files in those directories, they're loaded and activated as drivers. This option sets directories to scan <i>in addition to</i> the <tt>drivers</tt> subdirectory of the rEFInd installation directory, which is always scanned, if present.</td>
+ <td>Scans the specified directory or directories for EFI driver files. If rEFInd discovers <tt>.efi</tt> files in those directories, they're loaded and activated as drivers. This option sets directories to scan <i>in addition to</i> the <tt>drivers</tt> and <tt>drivers_<i>arch</i></tt> subdirectories of the rEFInd installation directory, which are always scanned, if present.</td>
</tr>
<tr>
<td><tt>scanfor</tt></td>
<td><tt>internal</tt>, <tt>external</tt>, <tt>optical</tt>, <tt>hdbios</tt>, <tt>biosexternal</tt>, <tt>cd</tt>, and <tt>manual</tt></td>
- <td>Tells rEFInd what methods to use to locate boot loaders. The <tt>internal</tt>, <tt>external</tt>, and <tt>optical</tt> parameters tell rEFInd to scan for EFI boot loaders on internal, external, and optical (CD, DVD, and Blu-ray) devices, respectively. The <tt>hdbios</tt>, <tt>biosexternal</tt>, and <tt>cd</tt> parameters are similar, but scan for BIOS boot loaders. (Note that the BIOS options scan more thoroughly and actively on Macs than on UEFI-based PCs; for the latter, only options in the firmware's boot list are scanned.) The <tt>manual</tt> parameter tells rEFInd to scan the configuration file for manual settings. You can specify multiple parameters to have the program scan for multiple boot loader types. When you do so, the order determines the order in which the boot loaders appear in the menu. The default is <tt>internal, external, optical, manual</tt> on most systems, but <tt>internal, hdbios, external, biosexternal, optical, cd, manual</tt> on Macs.</td>
+ <td>Tells rEFInd what methods to use to locate boot loaders. The <tt>internal</tt>, <tt>external</tt>, and <tt>optical</tt> parameters tell rEFInd to scan for EFI boot loaders on internal, external, and optical (CD, DVD, and Blu-ray) devices, respectively. The <tt>hdbios</tt>, <tt>biosexternal</tt>, and <tt>cd</tt> parameters are similar, but scan for BIOS boot loaders. (Note that the BIOS options scan more thoroughly and actively on Macs than on UEFI-based PCs; for the latter, only options in the firmware's boot list are scanned, as described on the <a href="using.html">Using rEFInd</a> page.) The <tt>manual</tt> parameter tells rEFInd to scan the configuration file for manual settings. You can specify multiple parameters to have the program scan for multiple boot loader types. When you do so, the order determines the order in which the boot loaders appear in the menu. The default is <tt>internal, external, optical, manual</tt> on most systems, but <tt>internal, hdbios, external, biosexternal, optical, cd, manual</tt> on Macs.</td>
</tr>
<tr>
<td><tt>scan_delay</tt></td>
<tr>
<td><tt>scan_all_linux_kernels</tt></td>
<td>None</td>
- <td>When set, causes rEFInd to add Linux kernels (files with names that begin with <tt>vmlinuz</tt> or <tt>bzImage</tt>) to the list of EFI boot loaders, even if they lack <tt>.efi</tt> filename extensions. The hope is that this will simplify use of rEFInd on distributions that provide kernels with EFI stub loader support but that don't give those kernels names that end in <tt>.efi</tt>. Of course, the kernels must still be stored on a filesystem that rEFInd can read, and in a directory that it scans. (<a href="drivers.html">Drivers</a> and the <tt>also_scan_dirs</tt> options can help with those issues.) Note that this option can cause unwanted files to be improperly detected and given loader tags, such as older kernels without EFI stub loader support. For this reason, it's disabled by default.</td>
+ <td>When set, causes rEFInd to add Linux kernels (files with names that begin with <tt>vmlinuz</tt> or <tt>bzImage</tt>) to the list of EFI boot loaders, even if they lack <tt>.efi</tt> filename extensions. The hope is that this will simplify use of rEFInd on distributions that provide kernels with EFI stub loader support but that don't give those kernels names that end in <tt>.efi</tt>. Of course, the kernels must still be stored on a filesystem that rEFInd can read, and in a directory that it scans. (<a href="drivers.html">Drivers</a> and the <tt>also_scan_dirs</tt> options can help with those issues.) Note that this option can cause unwanted files to be improperly detected and given loader tags, such as older kernels without EFI stub loader support. For this reason, it's disabled by default, but that may change in the future.</td>
</tr>
<tr>
<td><tt>default_selection</tt></td>
<td>A substring of a boot loader's title; or a numeric position</td>
- <td>Sets the default boot OS based on the loader's title, which appears in the main menu beneath the icons when you select the loader. You can enter any substring of the title as the <tt>default_selection</tt>, so long as it's two or more characters in length. It's best to use a unique substring, since rEFInd stops searching when it finds the first match. Because rEFInd sorts entries within a directory in descending order by file modification time, if you specify a directory (or volume name, for loaders in a partition's root directory) as the <tt>default_selection</tt>, the most recent loader in that directory will be the default. One-character entries are matched against the first character of the title, except for digits, which refer to the numeric order of the boot loader entries. (Note: In version 0.2.0, only the first character of this entry was used, and was matched against the first character of the title.)</td>
+ <td>Sets the default boot OS based on the loader's title, which appears in the main menu beneath the icons when you select the loader. You can enter any substring of the title as the <tt>default_selection</tt>, so long as it's two or more characters in length. It's best to use a unique substring, since rEFInd stops searching when it finds the first match. Because rEFInd sorts entries within a directory in descending order by file modification time, if you specify a directory (or volume name, for loaders in a partition's root directory) as the <tt>default_selection</tt>, the most recent loader in that directory will be the default. One-character entries are matched against the first character of the title, except for digits, which refer to the numeric order of the boot loader entries.</td>
</tr>
</table>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 4/19/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<li>User-configurable graphics and icons—you can set your own background, set new icons, and so on.</li>
-<li>Launch EFI boot loaders</li>
+<li>Launch EFI boot loaders.</li>
-<li>Launch legacy (BIOS) boot loaders on Macs and on some UEFI-based PCs. On the latter, the BIOS boot device must be listed in the firmware's boot options. Often only the hard disk and optical disc are listed by default. Scanning for legacy OSes is more thorough on Macs.</li>
+<li>Launch legacy (BIOS) boot loaders on Macs. (rEFInd also supports legacy boots on some UEFI PCs; see below.)</li>
<li>Launch options for an external EFI shell or disk partitioner. (See the <a href="installing.html">Installing rEFInd</a> section for information on how to obtain and install these components.)</li>
<ul>
<li>Auto-detection of EFI boot loaders, independently on internal hard disks, external hard disks, and optical discs.</li>
- <li>Auto-detection of BIOS boot loaders, independently on internal hard disks, external hard disks, and optical discs.</li>
+ <li>Auto-detection of legacy BIOS boot loaders, independently on internal hard disks, external hard disks, and optical discs.</li>
<li>Manually via the configuration file</li>
</ul>
You can select which of these methods to use to construct the rEFInd main boot menu. Although rEFIt supports auto-detection, it does not support manual configuration; and rEFIt's options to enable, disable, and prioritize individual boot loader detection methods are primitive compared to those in rEFInd.</li>
+<li>Support for launching legacy BIOS boot loaders on UEFI PCs with
+suitable CSM support (as of version 0.4.6). This feature requires building
+rEFInd with the TianoCore EDK2 toolkit, which I do for my main binary
+build. Note that some UEFI PCs, such as those with Gigabyte's Hybrid EFI,
+lack a usable CSM.</li>
+
<li>The ability to fine-tune options passed to EFI boot loaders, via manual configuration.</li>
<li>The ability to specify additional directories to scan for boot loaders and drivers (as of version 0.2.7).</li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
-<li><b><a href="http://sourceforge.net/projects/refind/files/0.4.5/refind-src-0.4.5.zip/download">A
+<li><b><a
+ href="http://sourceforge.net/projects/refind/files/0.4.6/refind-src-0.4.6.zip/download">A
source code zip file</a></b>—This is useful if you want to
compile the software locally. Note that I use Linux with the <a
- href="http://sourceforge.net/projects/gnu-efi">GNU-EFI</a> development
- tools to build the main rEFInd binary, and Linux with the <a
- href="https://sourceforge.net/projects/tianocore/">TianoCore
- development kit</a> for the drivers. rEFIt used an Intel/Microsoft
+ href="https://sourceforge.net/projects/tianocore/">TianoCore EFI
+ Development Kit 2 (EDK2)</a> to build my binaries (below), although the
+ <a href="http://sourceforge.net/projects/gnu-efi">GNU-EFI</a>
+ development tools are also supported. rEFIt used an Intel/Microsoft
toolchain. Backporting rEFInd to that toolchain is theoretically
possible, but I've not attempted it.</li>
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.4.5/refind-bin-0.4.5.zip/download">A
- binary zip file (built with GNU-EFI)</a></b>—Download this if you
- want to install rEFInd and/or its filesystem drivers on an <i>x</i>86
- or <i>x</i>86-64 computer and have no need to test rEFInd first by
- booting it on an optical disc. This zip file package includes both
- <i>x</i>86 (aka IA32) and <i>x</i>86-64 (aka <i>x</i>64, AMD64, or
- EM64T) versions of rEFInd. Which you install depends on your
- architecture, as described on the <a href="installing.html">Installing
- rEFInd</a> page.</li>
-
+ href="http://sourceforge.net/projects/refind/files/0.4.6/refind-bin-0.4.6.zip/download">A
+ binary zip file</a></b>—Download this if you want to install
+ rEFInd and/or its filesystem drivers on an <i>x</i>86 or <i>x</i>86-64
+ computer and have no need to test rEFInd first by booting it on an
+ optical disc. This zip file package includes both <i>x</i>86 (aka IA32)
+ and <i>x</i>86-64 (aka <i>x</i>64, AMD64, or EM64T) versions of rEFInd.
+ Which you install depends on your architecture, as described on the <a
+ href="installing.html">Installing rEFInd</a> page.</li>
+
+<!--
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.4.5/refind-bin-tiano-0.4.5.zip/download">A
- binary zip file (built with TianoCore EDK2)</a></b>—This package
- is just like the preceding one, except that it was built using the
- TianoCore EFI Development Kit 2 (EDK2) rather than the GNU-EFI that was
- used to build the other binary. In theory, the two should work
- identically. In practice, they might not. I originally used GNU-EFI to
- develop rEFInd, so it's the safer version; however, I would appreciate
- feedback about the TianoCore EDK2 build.</li>
+ href="http://sourceforge.net/projects/refind/files/0.4.6/refind-bin-gnuefi-0.4.6.zip/download">A
+ binary zip file (built with GNU-EFI)</a></b>—This package is just
+ like the preceding one, except that it was built using the GNU-EFI
+ development kit rather than the TianoCore EFI Development Kit 2 (EDK2)
+ that was used to build the other binary. I originally used GNU-EFI to
+ develop rEFInd, but the GNU-EFI toolkit doesn't support the legacy
+ (BIOS-mode) boot calls on UEFI-based PCs, so I now consider the
+ TianoCore build to be the primary one. (Macs can boot legacy OSes using
+ either build.)</li>
+-->
<li><b><a
- href="http://sourceforge.net/projects/refind/files/0.4.5/refind-cd-0.4.5.zip/download">A
+ href="http://sourceforge.net/projects/refind/files/0.4.6/refind-cd-0.4.6.zip/download">A
CD-R image file</a></b>—This download contains the same files as
- the GNU-EFI zip file, but you can burn it to a CD-R to test rEFInd (and its
- filesystem drivers) without installing it first. (It boots on UEFI PCs,
- but fails on some older Macs.) If you like it, you can then copy the
- files from the CD-R to your hard disk. The files are named in such a
- way that the disc should boot on either 64-bit (<i>x</i>86-64) or
- 32-bit (<i>x</i>86) EFI computers. I've included an open source EFI
+ the binary zip file, but you can burn it to a CD-R to test rEFInd
+ (and its filesystem drivers) without installing it first. (It boots on
+ UEFI PCs, but fails on some older Macs.) If you like it, you can then
+ copy the files from the CD-R to your hard disk. The files are named in
+ such a way that the disc should boot on either 64-bit (<i>x</i>86-64)
+ or 32-bit (<i>x</i>86) EFI computers. I've included an open source EFI
shell program on this disc that's not included in the binary zip file,
so that you can access an EFI shell from a bootable disc even if you
don't have an EFI shell available from your regular hard disk. This can
</ul>
-<p>If you're using another platform, you can give rEFInd a try; however, you'll need to build it from source code yourself or track down a binary from another source. (Perhaps by the time you read this it will be included in Linux distributions built for unusual CPUs.)</p>
+<p>If you're using a platform other than <i>x</i>86 or <i>x</i>86-64, you can give rEFInd a try; however, you'll need to build it from source code yourself or track down a binary from another source. (Perhaps by the time you read this it will be included in Linux distributions built for unusual CPUs.)</p>
<p>To extract the files from the zip file images I've provided, you'll need a tool such as <tt>unzip</tt>, which is included with Linux and Mac OS X. Numerous Windows utilities also support this format, such as <a href="http://www.pkware.com/software/pkzip/">PKZIP</a> and <a href="http://www.7-zip.org/">7-Zip.</a></p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<li><a href="http://refit.sourceforge.net">The official rEFIt Web page</a></li>
+<li><a href="http://freedesktop.org/wiki/Software/gummiboot">The official gummiboot Web page</a></li>
+
<li><a href="http://elilo.sourceforge.net/">The official ELILO Web page</a></li>
<li><a href="http://www.gnu.org/software/grub/">The official GRUB Web page</a></li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/19/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
initial RAM disk is identified, rEFInd passes a suitable
<tt>initrd=</tt> option to the kernel when it boots.</li>
-<p class="sidebar">rEFInd 0.2.1 and 0.2.2 used a filename of <tt>linux.conf</tt> to hold Linux kernel options; however, the Linux kernel developers plan to use this name themselves, so I've switched to <tt>refind_linux.conf</tt> as of rEFInd 0.2.3. Through version 0.4.2, rEFInd still supported the <tt>linux.conf</tt> filename as a backup to <tt>refind_linux.conf</tt>, but as of version 0.4.3, <tt>linux.conf</tt> no longer works, so you should rename your <tt>linux.conf</tt> file to <tt>refind_linux.conf</tt> if you're upgrading.</p>
+<p class="sidebar">rEFInd 0.2.1 and 0.2.2 used a filename of <tt>linux.conf</tt> to hold Linux kernel options; however, the Linux kernel developers plan to use this name themselves, so I've switched to <tt>refind_linux.conf</tt> as of rEFInd 0.2.3. Through version 0.4.2, rEFInd still supported the <tt>linux.conf</tt> filename as a backup to <tt>refind_linux.conf</tt>, but as of version 0.4.3, <tt>linux.conf</tt> no longer works, so you should rename rEFInd's <tt>linux.conf</tt> file to <tt>refind_linux.conf</tt> if you're upgrading.</p>
<li>rEFInd looks for a file called <tt>refind_linux.conf</tt> in the same
directory as the kernel file. This file is a practical requirement for
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
-<p>Last Web page update: 8/12/2012</p>
+<p>Last Web page update: 10/6/2012</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
+<li><b>0.4.6 (10/6/2012)</b>—Thanks to contributor John Bressler, rEFInd can now boot legacy (BIOS) boot loaders on many UEFI PCs. (Previously, rEFInd could do this only on Macs.) Other changes include a new <tt>scan_delay</tt> option that inserts a delay between rEFInd starting and disk scans (to help detect disks that are slow to appear to the firmware) and a change in the default <tt>scanfor</tt> value so that legacy OSes are detected by default on Macs (but not on PCs). I've also fixed some memory management problems that caused error messages to appear on some systems when rEFInd was compiled with the TianoCore EDK2 toolkit. Finally, I'm now using the TianoCore toolkit to make my primary binary builds, since the new UEFI legacy boot support requires the TianoCore environment. (rEFInd still builds with GNU-EFI, but it doesn't support booting legacy OSes on UEFI systems when built in this way.)</li>
+
<li><b>0.4.5 (8/12/2012)</b>—This version fixes a couple of Mac-related bugs. The most important is that version 0.4.3 and 0.4.4 couldn't boot BIOS-based (aka CSM or Boot Camp) OS installations; 0.4.5 restores this important feature. The second bug is in the <tt>install.sh</tt> script, which would often fail to detect rEFItBlesser, thus leaving it enabled and causing rEFInd to fail to start after the first reboot into OS X.</li>
<li><b>0.4.4 (6/23/2012)</b>—This is a bug-fix release. Most importantly, it fixes a bug in the new <tt>use_graphics_for</tt> feature; in 0.4.3, the options were set incorrectly (they just happened to work as expected on my main test configuration). I've also fixed problems with volume names in the 32-bit versions of both the drivers and the TianoCore EDK2 build of rEFInd itself. Finally, I've tweaked the <tt>install.sh</tt> script to do a better job of identifying the computer's ESP under OS X.</li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 4/19/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
+ <li>The support for booting legacy (BIOS) OSes on UEFI-based PCs
+ currently has a number of limitations. Most importantly, it works
+ off of the list of boot devices stored in the computer's NVRAM. I'd
+ prefer to have it scan disks and partitions, as the Mac's legacy
+ boot support does. Also, the UEFI legacy boot code presents empty
+ optical drives and uses generic icons rather than OS-specific
+ icons.</li>
+
<li>Currently, rEFInd can detect whether it's compiled for <i>x</i>86
or <i>x</i>86-64 systems and displays this information in its
"About" screen (<tt>AboutrEFInd()</tt> in <tt>main.c</tt>). I'd
<ul>
- <li>I'd like to find a way to get rEFInd to launch BIOS boot loaders on
- UEFI-based systems. This option currently works only on
- Macs—or at least, I've not gotten it to work on any of my
- UEFI-based PCs. (I've done some experiments to try to get this to
- work, but so far without success. If you'd like to help on this, <a
- href="mailto:rodsmith@rodsbooks.com">e-mail me</a> for my
- thoughts.)</li>
-
<li>The <a href="http://www.rodsbooks.com/gb-hybrid-efi/">Gigabyte
Hybrid EFI</a> has a bug that causes the allegedly case-insensitive
<tt>StriCmp()</tt> function to perform a case-sensitive comparison.
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-8/12/2012, referencing rEFInd 0.4.5</p>
+10/6/2012, referencing rEFInd 0.4.6</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p class="sidebar"><b>Note:</b> rEFInd defaults to scanning for EFI, but <i>not</i> for BIOS, boot loaders. If you want to launch BIOS-mode OSes from rEFInd, you must edit the <tt>scanfor</tt> line in <tt>refind.conf</tt>, as described on the <a href="configfile.html">Configuring the Boot Manager</a> page. This type of configuration is most likely to be necessary on Macs that dual-boot with Windows.</p>
-<p>Ordinarily, rEFInd displays tags for OSes it finds on internal hard disks, external hard disks (including USB flash drives, CF disks, and so on), and optical discs. Sometimes, though, the firmware hasn't had time to fully examine these devices by the time rEFInd starts; or you might only insert or plug in the media after rEFInd appears. In these cases, you can press the Esc key to have rEFInd re-read its configuration file and re-scan your media for boot loaders. This action can take a few seconds to complete, so be patient. You can also use this feature to detect OSes if you launch a shell and use it to load a driver or edit the <tt>refind.conf</tt> file.</p>
+<p>Ordinarily, rEFInd displays tags for OSes it finds on internal hard disks, external hard disks (including USB flash drives, CF disks, and so on), and optical discs. Sometimes, though, the firmware hasn't had time to fully examine these devices by the time rEFInd starts; or you might only insert or plug in the media after rEFInd appears. In these cases, you can press the Esc key to have rEFInd re-read its configuration file and re-scan your media for boot loaders. This action can take a few seconds to complete, so be patient. You can also use this feature to detect OSes if you launch a shell and use it to load a driver or edit the <tt>refind.conf</tt> file. If you regularly need to press Esc, you might look into the <tt>scan_delay</tt> configuration file option, described on the <a href="configfile.html">Configuring the Boot Manager</a> page.</p>
<h2>Using Keyboard Shortcuts</h2>
<p>rEFInd assigns shortcut letters to most OS entries based on the first letter of the directory in which the OS's boot loader is stored. For instance, if you have a boot loader called <tt>/EFI/debian/elilo.efi</tt>, rEFInd attempts to assign it a shortcut letter of <i>D</i>. rEFInd overrides this default for Mac OS X, Windows, and for Linux's GRUB, ELILO, and EFI stub boot loaders if the distribution can't be more precisely identified, as noted in the preceding table. This method works well for many installations, but it can produce conflicts. For instance, if you have a Macintosh that holds both Mac OS X and Mandriva, both OSes would normally use the <tt>M</tt> shortcut key. In practice, which works depends on the order in which rEFInd detects the OSes.</p>
+<a name="legacy">
+<h2>Booting Legacy OSes</h2>
+</a>
+
+<p>Sometimes it's necessary to boot a legacy (BIOS-based) OS on an EFI computer. This is especially true on Macs, since this is the usual method of dual-booting OS X and Windows. In fact, even most Linux distributions install more easily in BIOS mode on Macs, although running Linux in EFI mode has its advantages. (See my <a href="http://www.rodsbooks.com/ubuntu-efi/">EFI-Booting Ubuntu on a Mac</a> page for an in-depth look at this topic.)</p>
+
+<p>On UEFI-based PCs, booting some OSes in EFI mode and others in BIOS mode is less often necessary, since it's usually easy to install all your OSes in BIOS mode. If you have a working EFI-mode OS installation, though, and if you want to install an OS that lacks EFI-mode boot support, you may need to boot in both modes. This may happen if you want to add one of the BSDs (FreeBSD, OpenBSD, NetBSD, and so on) to a working system, for instance. You might also want to boot a BIOS-mode emergency recovery CD, such as <a href="http://partedmagic.com">Parted Magic</a> or <a href="http://www.sysresccd.org">System Rescue CD.</a></p>
+
+<p>For all such cases, rEFInd supports booting legacy OSes; however, the details vary between Macs and UEFI PCs. Also, be aware that some UEFI PCs lack the Compatibility Support Module (CSM) that's required for this feature to work. This is true even of some computers that can boot BIOS-based OSes natively. This can happen because the firmware is basically a BIOS with a UEFI implementation tacked on top of it; such systems rely on the native BIOS to boot, and may not provide a way for EFI applications to access the BIOS features via CSM mechanisms. If you have such a computer and if you enable a legacy boot option in the configuration file, rEFInd notifies you of its inability to present legacy boot options when it starts up. rEFInd's legacy boot support also depends on features that are not available in the GNU-EFI development package, so you may see a similar notice if you run a version of rEFInd compiled with that package. (The primary build available on the <a href="getting.html">Getting rEFInd</a> page is compiled with the TianoCore EDK2 package, which does support the BIOS boot features.)</p>
+
+<p>The <tt>scanfor</tt> option, described on the <a href="configfile.html">Configuring the Boot Manager</a> page, controls rEFInd's detection of legacy OSes. On Macs, the default is to scan for such OSes, since a common boot scenario on Macs is dual-booting OS X and Windows, and of course BIOS support is required for this. (rEFInd 0.4.5 and earlier did <i>not</i> scan for legacy OSes by default, though, so you may need to change this option if you're upgrading and don't want to scan for legacy OSes.) On UEFI PCs, rEFInd defaults to <i>not</i> scanning for legacy OSes; thus, you must edit the <tt>scanfor</tt> item in the configuration file if you want to boot a legacy OS on a UEFI PC.</p>
+
+ <img src="os_legacy.png" align="right" width="128" height="128"
+ alt="The legacy OS icon is identical for all OSes on UEFI-based PCs."
+ border=2 background="gray"/>
+
+<p>On Macs, rEFInd uses a flexible scanning algorithm inherited from rEFIt. This procedure detects most legacy OSes on most disks, although it can sometimes miss an OS. This scanning algorithm can often identify the legacy OS you've installed and present a suitable icon. On UEFI PCs, rEFInd relies on the computer's NVRAM settings to determine which legacy boot loaders to scan; if an OS isn't listed in the NVRAM settings, rEFInd won't present it as an option. On most UEFI PCs, at least one hard disk and your optical drive appear as options. The two computers I've tested have failed to present USB flash drives as boot options when inserted, though. You may be able to get additional options to appear by editing your boot list in your firmware's setup utility, but I can make no promises about this. The UEFI scanning procedure is also incapable of detecting the OS type, so you'll see a generic legacy OS icon, as shown at the right.</p>
+
<hr />
<p>copyright © 2012 by Roderick W. Smith</p>
/** Helper macro for stringification. */
#define FSW_EFI_STRINGIFY(x) #x
/** Expands to the EFI driver name given the file system type name. */
-#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.4.4 " FSW_EFI_STRINGIFY(t) L" File System Driver"
+#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.4.6 " FSW_EFI_STRINGIFY(t) L" File System Driver"
// function prototypes
# biosexternal - BIOS external boot loaders (USB, eSATA, etc.)
# cd - BIOS optical-disc boot loaders
# manual - use stanzas later in this configuration file
-# Default is internal,external,optical,manual
+# Note that the legacy BIOS options require firmware support, which is
+# not present on all computers.
+# On UEFI PCs, default is internal,external,optical,manual
+# On Macs, default is internal,hdbios,external,biosexternal,optical,cd,manual
#
#scanfor internal,external,optical,manual
File->Buffer = AllocatePool(File->BufferSize);
Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &File->BufferSize, File->Buffer);
if (CheckError(Status, L"while loading the configuration file")) {
- FreePool(File->Buffer);
+ MyFreePool(File->Buffer);
File->Buffer = NULL;
refit_call1_wrapper(FileHandle->Close, FileHandle);
return Status;
// handle a parameter with a single string argument
static VOID HandleString(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Target) {
if (TokenCount == 2) {
- if (*Target != NULL)
- FreePool(*Target);
+ MyFreePool(*Target);
*Target = StrDuplicate(TokenList[1]);
} // if
} // static VOID HandleString()
FreeTokenLine(&TokenList, &TokenCount);
}
- FreePool(File.Buffer);
+ MyFreePool(File.Buffer);
} /* VOID ReadConfig() */
static VOID AddSubmenu(LOADER_ENTRY *Entry, REFIT_FILE *File, REFIT_VOLUME *Volume, CHAR16 *Title) {
while (((TokenCount = ReadTokenLine(File, &TokenList)) > 0) && (StriCmp(TokenList[0], L"}") != 0)) {
if ((StriCmp(TokenList[0], L"loader") == 0) && (TokenCount > 1)) { // set the boot loader filename
- if (SubEntry->LoaderPath != NULL)
- FreePool(SubEntry->LoaderPath);
+ MyFreePool(SubEntry->LoaderPath);
SubEntry->LoaderPath = StrDuplicate(TokenList[1]);
SubEntry->DevicePath = FileDevicePath(Volume->DeviceHandle, SubEntry->LoaderPath);
} else if (StriCmp(TokenList[0], L"initrd") == 0) {
- if (SubEntry->InitrdPath != NULL)
- FreePool(SubEntry->InitrdPath);
+ MyFreePool(SubEntry->InitrdPath);
SubEntry->InitrdPath = NULL;
if (TokenCount > 1) {
SubEntry->InitrdPath = StrDuplicate(TokenList[1]);
}
} else if (StriCmp(TokenList[0], L"options") == 0) {
- if (SubEntry->LoadOptions != NULL)
- FreePool(SubEntry->LoadOptions);
+ MyFreePool(SubEntry->LoadOptions);
SubEntry->LoadOptions = NULL;
if (TokenCount > 1) {
SubEntry->LoadOptions = StrDuplicate(TokenList[1]);
if (SubEntry->InitrdPath != NULL) {
MergeStrings(&SubEntry->LoadOptions, L"initrd=", L' ');
MergeStrings(&SubEntry->LoadOptions, SubEntry->InitrdPath, 0);
- FreePool(SubEntry->InitrdPath);
+ MyFreePool(SubEntry->InitrdPath);
SubEntry->InitrdPath = NULL;
} // if
if (SubEntry->Enabled == TRUE) {
Entry->LoaderPath = StrDuplicate(TokenList[1]);
Entry->DevicePath = FileDevicePath(CurrentVolume->DeviceHandle, Entry->LoaderPath);
SetLoaderDefaults(Entry, TokenList[1], CurrentVolume);
- FreePool(Entry->LoadOptions);
+ MyFreePool(Entry->LoadOptions);
Entry->LoadOptions = NULL; // Discard default options, if any
DefaultsSet = TRUE;
} else if ((StriCmp(TokenList[0], L"volume") == 0) && (TokenCount > 1)) {
if (FindVolume(&CurrentVolume, TokenList[1])) {
- FreePool(Entry->me.Title);
+ MyFreePool(Entry->me.Title);
Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
SPrint(Entry->me.Title, 255, L"Boot %s from %s", (Title != NULL) ? Title : L"Unknown", CurrentVolume->VolName);
Entry->me.BadgeImage = CurrentVolume->VolBadgeImage;
Entry->VolName = CurrentVolume->VolName;
} // if match found
} else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) {
- FreePool(Entry->me.Image);
+ MyFreePool(Entry->me.Image);
Entry->me.Image = LoadIcns(CurrentVolume->RootDir, TokenList[1], 128);
if (Entry->me.Image == NULL) {
Entry->me.Image = DummyImage(128);
}
} else if ((StriCmp(TokenList[0], L"initrd") == 0) && (TokenCount > 1)) {
- if (Entry->InitrdPath)
- FreePool(Entry->InitrdPath);
+ MyFreePool(Entry->InitrdPath);
Entry->InitrdPath = StrDuplicate(TokenList[1]);
} else if ((StriCmp(TokenList[0], L"options") == 0) && (TokenCount > 1)) {
- if (Entry->LoadOptions)
- FreePool(Entry->LoadOptions);
+ MyFreePool(Entry->LoadOptions);
Entry->LoadOptions = StrDuplicate(TokenList[1]);
} else if ((StriCmp(TokenList[0], L"ostype") == 0) && (TokenCount > 1)) {
if (TokenCount > 1) {
if (Entry->InitrdPath) {
MergeStrings(&Entry->LoadOptions, L"initrd=", L' ');
MergeStrings(&Entry->LoadOptions, Entry->InitrdPath, 0);
- FreePool(Entry->InitrdPath);
+ MyFreePool(Entry->InitrdPath);
Entry->InitrdPath = NULL;
} // if
GenerateSubScreen(Entry, Volume);
AddPreparedLoaderEntry(Entry);
} else {
- FreePool(Entry);
+ MyFreePool(Entry);
} // if/else
- FreePool(Title);
+ MyFreePool(Title);
} // if
FreeTokenLine(&TokenList, &TokenCount);
} // while()
} else { // a filename string is NULL
GoOn = FALSE;
} // if/else
- if (OptionsFilename != NULL)
- FreePool(OptionsFilename);
- if (FullFilename != NULL)
- FreePool(FullFilename);
+ MyFreePool(OptionsFilename);
+ MyFreePool(FullFilename);
OptionsFilename = FullFilename = NULL;
} while (GoOn);
return (File);
Options = StrDuplicate(TokenList[1]);
FreeTokenLine(&TokenList, &TokenCount);
FreePool(File);
- }
+ } // if
return Options;
} // static CHAR16 * GetOptionsFile()
}
}
- FreePool (OpenInfo);
+ MyFreePool (OpenInfo);
}
}
- FreePool (ProtocolGuidArray);
+ MyFreePool (ProtocolGuidArray);
}
}
return EFI_SUCCESS;
Error:
- if (*HandleType != NULL) {
- FreePool (*HandleType);
- }
-
- if (*HandleBuffer != NULL) {
- FreePool (*HandleBuffer);
- }
+ MyFreePool (*HandleType);
+ MyFreePool (*HandleBuffer);
*HandleCount = 0;
*HandleBuffer = NULL;
#define TAG_EXIT (7)
#define TAG_SHELL (8)
#define TAG_GPTSYNC (9)
-#define TAG_LEGACY_NON_MAC (10)
+#define TAG_LEGACY_UEFI (10)
#define NUM_TOOLS (9)
#define NUM_SCAN_OPTIONS 10
// try to load it
Image = egLoadIcon(SelfDir, FileName, 128);
if (Image != NULL) {
- FreePool(CutoutName);
+ MyFreePool(CutoutName);
return Image;
}
- FreePool(CutoutName);
+ MyFreePool(CutoutName);
} // while
// try the fallback name
// find the current directory
DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath);
CleanUpPathNameSlashes(DevicePathAsString);
- if (SelfDirPath != NULL)
- FreePool(SelfDirPath);
+ MyFreePool(SelfDirPath);
SelfDirPath = FindPath(DevicePathAsString);
- FreePool(DevicePathAsString);
+ MyFreePool(DevicePathAsString);
return FinishInitRefitLib();
}
{
UINTN i;
- if (*ElementCount > 0) {
+ if ((*ElementCount > 0) && (**ListPtr != NULL)) {
for (i = 0; i < *ElementCount; i++) {
// TODO: call a user-provided routine for each element here
- FreePool((*ListPtr)[i]);
+ MyFreePool((*ListPtr)[i]);
}
- FreePool(*ListPtr);
+ MyFreePool(*ListPtr);
}
-}
+} // VOID FreeList()
//
// firmware device path discovery
PathList[PathCount++] = AppendDevicePath(DevicePath, LegacyLoaderMediaPath);
}
- FreePool(Handles);
+ MyFreePool(Handles);
if (HardcodedPathList) {
for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++)
UINT8 *SectorBuffer1, *SectorBuffer2;
UINTN SectorSum, i;
- FreePool(Volumes);
+ MyFreePool(Volumes);
Volumes = NULL;
VolumesCount = 0;
if (Volume->DeviceHandle == SelfLoadedImage->DeviceHandle)
SelfVolume = Volume;
}
- FreePool(Handles);
+ MyFreePool(Handles);
if (SelfVolume == NULL)
Print(L"WARNING: SelfVolume not found");
break;
}
- FreePool(SectorBuffer1);
- FreePool(SectorBuffer2);
+ MyFreePool(SectorBuffer1);
+ MyFreePool(SectorBuffer2);
}
}
// free pointer from last call
if (*DirEntry != NULL) {
- FreePool(*DirEntry);
- *DirEntry = NULL;
+ FreePool(*DirEntry);
+ *DirEntry = NULL;
}
// read next directory entry
CHAR16 *OnePattern;
if (DirIter->LastFileInfo != NULL) {
- FreePool(DirIter->LastFileInfo);
- DirIter->LastFileInfo = NULL;
+ FreePool(DirIter->LastFileInfo);
+ DirIter->LastFileInfo = NULL;
}
if (EFI_ERROR(DirIter->LastStatus))
EFI_STATUS DirIterClose(IN OUT REFIT_DIR_ITER *DirIter)
{
- if (DirIter->LastFileInfo != NULL) {
- FreePool(DirIter->LastFileInfo);
- DirIter->LastFileInfo = NULL;
- }
- if (DirIter->CloseDirHandle)
- refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle);
+ if (DirIter->LastFileInfo != NULL) {
+ FreePool(DirIter->LastFileInfo);
+ DirIter->LastFileInfo = NULL;
+ }
+ if (DirIter->CloseDirHandle)
+ refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle);
return DirIter->LastStatus;
}
while ((!Found) && (StartPoint < NumCompares)) {
Found = (StrnCmp(SmallCopy, &BigCopy[StartPoint++], SmallLen) == 0);
} // while
- FreePool(SmallCopy);
- FreePool(BigCopy);
+ MyFreePool(SmallCopy);
+ MyFreePool(BigCopy);
} // if
return (Found);
} // if (*First != NULL)
if (Second != NULL)
StrCat(NewString, Second);
- FreePool(*First);
+ MyFreePool(*First);
*First = NewString;
} else {
Print(L"Error! Unable to allocate memory in MergeStrings()!\n");
return Found;
} // BOOLEAN IsIn()
+// Implement FreePool the way it should have been done to begin with, so that
+// it doesn't throw an ASSERT message if fed a NULL pointer....
+VOID MyFreePool(IN OUT VOID *Pointer) {
+ if (Pointer != NULL)
+ FreePool(Pointer);
+}
+
static EFI_GUID AppleRemovableMediaGuid = APPLE_REMOVABLE_MEDIA_PROTOCOL_GUID;
// Eject all removable media.
if (!EFI_ERROR(Status))
Ejected++;
}
- FreePool(Handles);
+ MyFreePool(Handles);
return (Ejected > 0);
} // VOID EjectMedia()
CHAR16 *FindNumbers(IN CHAR16 *InString);
CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index);
BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List);
+VOID MyFreePool(IN OUT VOID *Pointer);
BOOLEAN EjectMedia(VOID);
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.5.6");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.6");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
// unload the image, we don't care if it works or not...
Status = refit_call1_wrapper(BS->UnloadImage, ChildImageHandle);
bailout:
- if (FullLoadOptions != NULL)
- FreePool(FullLoadOptions);
+ MyFreePool(FullLoadOptions);
return ReturnStatus;
} /* static EFI_STATUS StartEFIImageList() */
MergeStrings(&InitrdName, DirEntry->FileName, 0);
} // if
} // if/else
- if (InitrdVersion != NULL)
- FreePool(InitrdVersion);
+ MyFreePool(InitrdVersion);
} // while
DirIterClose(&DirIter);
// Note: Don't FreePool(FileName), since Basename returns a pointer WITHIN the string it's passed.
- FreePool(KernelVersion);
- FreePool(Path);
+ MyFreePool(KernelVersion);
+ MyFreePool(Path);
return (InitrdName);
} // static CHAR16 * FindInitrd()
NewEntry = AllocateZeroPool(sizeof(REFIT_MENU_SCREEN));
if ((Entry != NULL) && (NewEntry != NULL)) {
CopyMem(NewEntry, Entry, sizeof(REFIT_MENU_SCREEN));
- NewEntry->Title = StrDuplicate(Entry->Title);
- NewEntry->TimeoutText = StrDuplicate(Entry->TimeoutText);
+ NewEntry->Title = (Entry->Title) ? StrDuplicate(Entry->Title) : NULL;
+ NewEntry->TimeoutText = (Entry->TimeoutText) ? StrDuplicate(Entry->TimeoutText) : NULL;
if (Entry->TitleImage != NULL) {
NewEntry->TitleImage = AllocatePool(sizeof(EG_IMAGE));
if (NewEntry->TitleImage != NULL)
} // if
NewEntry->InfoLines = (CHAR16**) AllocateZeroPool(Entry->InfoLineCount * (sizeof(CHAR16*)));
for (i = 0; i < Entry->InfoLineCount && NewEntry->InfoLines; i++) {
- NewEntry->InfoLines[i] = StrDuplicate(Entry->InfoLines[i]);
+ NewEntry->InfoLines[i] = (Entry->InfoLines[i]) ? StrDuplicate(Entry->InfoLines[i]) : NULL;
} // for
NewEntry->Entries = (REFIT_MENU_ENTRY**) AllocateZeroPool(Entry->EntryCount * (sizeof (REFIT_MENU_ENTRY*)));
for (i = 0; i < Entry->EntryCount && NewEntry->Entries; i++) {
NewEntry = AllocateZeroPool(sizeof(REFIT_MENU_ENTRY));
if ((Entry != NULL) && (NewEntry != NULL)) {
CopyMem(NewEntry, Entry, sizeof(REFIT_MENU_ENTRY));
- NewEntry->Title = StrDuplicate(Entry->Title);
+ NewEntry->Title = (Entry->Title) ? StrDuplicate(Entry->Title) : NULL;
if (Entry->BadgeImage != NULL) {
NewEntry->BadgeImage = AllocatePool(sizeof(EG_IMAGE));
if (NewEntry->BadgeImage != NULL)
NewEntry->UseGraphicsMode = FALSE;
NewEntry->OSType = 0;
if (Entry != NULL) {
- NewEntry->LoaderPath = StrDuplicate(Entry->LoaderPath);
- NewEntry->VolName = StrDuplicate(Entry->VolName);
+ NewEntry->LoaderPath = (Entry->LoaderPath) ? StrDuplicate(Entry->LoaderPath) : NULL;
+ NewEntry->VolName = (Entry->VolName) ? StrDuplicate(Entry->VolName) : NULL;
NewEntry->DevicePath = Entry->DevicePath;
NewEntry->UseGraphicsMode = Entry->UseGraphicsMode;
- NewEntry->LoadOptions = StrDuplicate(Entry->LoadOptions);
- NewEntry->InitrdPath = StrDuplicate(Entry->InitrdPath);
+ NewEntry->LoadOptions = (Entry->LoadOptions) ? StrDuplicate(Entry->LoadOptions) : NULL;
+ NewEntry->InitrdPath = (Entry->InitrdPath) ? StrDuplicate(Entry->InitrdPath) : NULL;
}
} // if
return (NewEntry);
MergeStrings(&Temp, L"initrd=", 0);
MergeStrings(&Temp, SubEntry->InitrdPath, 0);
MergeStrings(&SubEntry->LoadOptions, Temp, L' ');
- FreePool(Temp);
+ MyFreePool(Temp);
} // if
AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry);
} // if (SubEntry != NULL)
// create the submenu
if (StrLen(Entry->Title) == 0) {
- FreePool(Entry->Title);
+ MyFreePool(Entry->Title);
Entry->Title = NULL;
}
SubScreen = InitializeSubScreen(Entry);
SubEntry = InitializeLoaderEntry(Entry);
if (SubEntry != NULL) {
SubEntry->me.Title = L"Run Apple Hardware Test";
- FreePool(SubEntry->LoaderPath);
+ MyFreePool(SubEntry->LoaderPath);
SubEntry->LoaderPath = StrDuplicate(DiagsFileName);
SubEntry->DevicePath = FileDevicePath(Volume->DeviceHandle, SubEntry->LoaderPath);
SubEntry->UseGraphicsMode = GlobalConfig.GraphicsFor & GRAPHICS_FOR_OSX;
while ((TokenCount = ReadTokenLine(File, &TokenList)) > 1) {
SubEntry = InitializeLoaderEntry(Entry);
SubEntry->me.Title = StrDuplicate(TokenList[0]);
- if (SubEntry->LoadOptions != NULL)
- FreePool(SubEntry->LoadOptions);
+ MyFreePool(SubEntry->LoadOptions);
SubEntry->LoadOptions = StrDuplicate(TokenList[1]);
MergeStrings(&SubEntry->LoadOptions, InitrdOption, L' ');
FreeTokenLine(&TokenList, &TokenCount);
SubEntry->UseGraphicsMode = GlobalConfig.GraphicsFor & GRAPHICS_FOR_LINUX;
AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry);
} // while
- if (InitrdOption)
- FreePool(InitrdOption);
- if (Temp)
- FreePool(Temp);
- FreePool(File);
+ MyFreePool(InitrdOption);
+ MyFreePool(Temp);
+ MyFreePool(File);
} // if Linux options file exists
} else if (Entry->OSType == 'E') { // entries for ELILO
MergeStrings(&InitrdOption, InitrdName, 0);
} // if
MergeStrings(&Options, InitrdOption, ' ');
- if (InitrdOption != NULL)
- FreePool(InitrdOption);
- if (InitrdName != NULL)
- FreePool(InitrdName);
+ MyFreePool(InitrdOption);
+ MyFreePool(InitrdName);
return (Options);
} // static CHAR16 * GetMainLinuxOptions()
Temp = FindLastDirName(LoaderPath);
MergeStrings(&OSIconName, Temp, L',');
- FreePool(Temp);
+ MyFreePool(Temp);
if (OSIconName != NULL) {
ShortcutLetter = OSIconName[0];
}
Entry->me.ShortcutLetter = ShortcutLetter;
if (Entry->me.Image == NULL)
Entry->me.Image = LoadOSIcon(OSIconName, L"unknown", FALSE);
- if (PathOnly != NULL)
- FreePool(PathOnly);
+ MyFreePool(PathOnly);
} // VOID SetLoaderDefaults()
// Add a specified EFI boot loader to the list, using automatic settings
while (LoaderList != NULL) {
Temp = LoaderList;
LoaderList = LoaderList->NextEntry;
- FreePool(Temp->FileName);
- FreePool(Temp);
+ MyFreePool(Temp->FileName);
+ MyFreePool(Temp);
} // while
} // static VOID CleanUpLoaderList()
NewLoader->TimeStamp = DirEntry->ModificationTime;
LoaderList = AddLoaderListEntry(LoaderList, NewLoader);
} // if
- FreePool(Extension);
+ MyFreePool(Extension);
} // while
NewLoader = LoaderList;
while (NewLoader != NULL) {
Status = DirIterClose(&DirIter);
if (Status != EFI_NOT_FOUND) {
if (Path)
- SPrint(FileName, 255, L"while scanning the %s directory", Path);
+ SPrint(FileName, 255, L"while scanning the %s directory", Path);
else
- StrCpy(FileName, L"while scanning the root directory");
+ StrCpy(FileName, L"while scanning the root directory");
CheckError(Status, FileName);
} // if (Status != EFI_NOT_FOUND)
} // if not scanning our own directory
CHAR16 FileName[256], *Directory, *MatchPatterns;
UINTN i, Length;
- MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
- if (GlobalConfig.ScanAllLinux)
- MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
+ MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
+ if (GlobalConfig.ScanAllLinux)
+ MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) {
// check for Mac OS X boot loader
Length = StrLen(Directory);
if (Length > 0)
ScanLoaderDir(Volume, Directory, MatchPatterns);
- FreePool(Directory);
+ MyFreePool(Directory);
} // while
} // if
} // static VOID ScanEfiFiles()
Entry = AllocateZeroPool(sizeof(LEGACY_ENTRY));
Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
SPrint(Entry->me.Title, 255, L"Boot legacy target %s", LegacyDescription);
- Entry->me.Tag = TAG_LEGACY_NON_MAC;
+ Entry->me.Tag = TAG_LEGACY_UEFI;
Entry->me.Row = 0;
Entry->me.ShortcutLetter = ShortcutLetter;
Entry->me.Image = LoadOSIcon(L"legacy", L"legacy", TRUE);
SubEntry = AllocateZeroPool(sizeof(LEGACY_ENTRY));
SubEntry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
SPrint(SubEntry->me.Title, 255, L"Boot %s", LegacyDescription);
- SubEntry->me.Tag = TAG_LEGACY_NON_MAC;
+ SubEntry->me.Tag = TAG_LEGACY_UEFI;
Entry->BdsOption = BdsOption;
AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry);
// Grab each boot option variable from the boot order, and convert
// the variable into a BDS boot option
UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
- Print(L"Scanning '%s'\n", BootOption);
BdsOption = BdsLibVariableToOption (&TempList, BootOption);
if (BdsOption != NULL) {
Entry->me.Row = 1;
Entry->me.ShortcutLetter = ShortcutLetter;
Entry->me.Image = Image;
- Entry->LoaderPath = StrDuplicate(LoaderPath);
+ Entry->LoaderPath = (LoaderPath) ? StrDuplicate(LoaderPath) : NULL;
Entry->DevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, Entry->LoaderPath);
Entry->UseGraphicsMode = UseGraphicsMode;
}
}
- FreePool (HandleBuffer);
- FreePool (HandleType);
+ MyFreePool (HandleBuffer);
+ MyFreePool (HandleType);
}
Done:
- FreePool (AllHandleBuffer);
+ MyFreePool (AllHandleBuffer);
return Status;
} /* EFI_STATUS ConnectAllDriversToAllControllers() */
#else
// load drivers from the subdirectories of rEFInd's home directory specified
// in the DRIVER_DIRS constant.
while ((Directory = FindCommaDelimited(DRIVER_DIRS, i++)) != NULL) {
- SelfDirectory = StrDuplicate(SelfDirPath);
+ SelfDirectory = SelfDirPath ? StrDuplicate(SelfDirPath) : NULL;
CleanUpPathNameSlashes(SelfDirectory);
MergeStrings(&SelfDirectory, Directory, L'\\');
NumFound += ScanDriverDir(SelfDirectory);
- FreePool(Directory);
- FreePool(SelfDirectory);
+ MyFreePool(Directory);
+ MyFreePool(SelfDirectory);
}
// Scan additional user-specified driver directories....
Length = StrLen(Directory);
if (Length > 0)
NumFound += ScanDriverDir(Directory);
- FreePool(Directory);
+ MyFreePool(Directory);
} // while
// connect all devices
GlobalConfig.LegacyType = LEGACY_TYPE_MAC;
} // static VOID FindLegacyBootType
+// Warn the user if legacy OS scans are enabled but the firmware or this
+// application can't support them....
+static VOID WarnIfLegacyProblems() {
+ BOOLEAN found = FALSE;
+ UINTN i = 0;
+
+ if (GlobalConfig.LegacyType == LEGACY_TYPE_NONE) {
+ do {
+ if (GlobalConfig.ScanFor[i] == 'h' || GlobalConfig.ScanFor[i] == 'b' || GlobalConfig.ScanFor[i] == 'c')
+ found = TRUE;
+ i++;
+ } while ((i < NUM_SCAN_OPTIONS) && (!found));
+ if (found) {
+ Print(L"NOTE: refind.conf's 'scanfor' line specifies scanning for one or more legacy\n");
+ Print(L"(BIOS) boot options; however, this is not possible because ");
+#ifdef __MAKEWITH_TIANO
+ Print(L"your computer lacks\n");
+ Print(L"the necessary Compatibility Support Module (CSM) support.\n");
+#else
+ Print(L"this program was\n");
+ Print(L"compiled without the necessary support. Please visit\n");
+ Print(L"http://www.rodsbooks.com/refind/getting.html and download and install a rEFInd\n");
+ Print(L"binary built with the TianoCore EDK2 to enable legacy boot support.\n");
+#endif
+ PauseForKey();
+ } // if (found)
+ } // if no legacy support
+} // static VOID WarnIfLegacyProblems()
+
// Locates boot loaders. NOTE: This assumes that GlobalConfig.LegacyType is set correctly.
static VOID ScanForBootloaders(VOID) {
UINTN i;
}
break;
} // switch()
- if (FileName != NULL) {
- FreePool(FileName);
- FileName = NULL;
- }
+ MyFreePool(FileName);
+ FileName = NULL;
} // for
} // static VOID ScanForTools
return Status;
// read configuration
+ CopyMem(GlobalConfig.ScanFor, "ieom ", NUM_SCAN_OPTIONS);
FindLegacyBootType();
if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC)
CopyMem(GlobalConfig.ScanFor, "ihebocm ", NUM_SCAN_OPTIONS);
- else
- CopyMem(GlobalConfig.ScanFor, "ieom ", NUM_SCAN_OPTIONS);
ReadConfig();
+ WarnIfLegacyProblems();
MainMenu.TimeoutSeconds = GlobalConfig.Timeout;
// disable EFI watchdog timer
break;
#ifdef __MAKEWITH_TIANO
- case TAG_LEGACY_NON_MAC: // Boot a legacy OS on a non-Mac
+ case TAG_LEGACY_UEFI: // Boot a legacy OS on a non-Mac
StartLegacyUEFI((LEGACY_ENTRY *)ChosenEntry);
break;
#endif // __MAKEWITH_TIANO
break;
} // switch()
- FreePool(Selection);
- Selection = StrDuplicate(ChosenEntry->Title);
+ MyFreePool(Selection);
+ Selection = (ChosenEntry->Title) ? StrDuplicate(ChosenEntry->Title) : NULL;
} // while()
// If we end up here, things have gone wrong. Try to reboot, and if that
AddListElement((VOID ***) &(Screen->Entries), &(Screen->EntryCount), Entry);
}
-VOID FreeMenu(IN REFIT_MENU_SCREEN *Screen)
-{
- if (Screen->Entries)
- FreePool(Screen->Entries);
-}
static INTN FindMenuShortcutEntry(IN REFIT_MENU_SCREEN *Screen, IN CHAR16 *Shortcut)
{
case MENU_FUNCTION_CLEANUP:
// release temporary memory
for (i = 0; i <= State->MaxIndex; i++)
- FreePool(DisplayStrings[i]);
- FreePool(DisplayStrings);
+ MyFreePool(DisplayStrings[i]);
+ MyFreePool(DisplayStrings);
break;
case MENU_FUNCTION_PAINT_ALL:
break;
case MENU_FUNCTION_CLEANUP:
- FreePool(itemPosX);
+ MyFreePool(itemPosX);
break;
case MENU_FUNCTION_PAINT_ALL:
VOID AddMenuInfoLine(IN REFIT_MENU_SCREEN *Screen, IN CHAR16 *InfoLine);
VOID AddMenuEntry(IN REFIT_MENU_SCREEN *Screen, IN REFIT_MENU_ENTRY *Entry);
-VOID FreeMenu(IN REFIT_MENU_SCREEN *Screen);
VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINTN Function, IN CHAR16 *ParamText);
UINTN RunMenu(IN REFIT_MENU_SCREEN *Screen, OUT REFIT_MENU_ENTRY **ChosenEntry);
UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT REFIT_MENU_ENTRY **ChosenEntry);