pages correctly, the original creator was David Vignoni (aka
"deviantdark" on the deviantart site).
+* The keys icon for MOK keys management comes from the
+ kdeartwork-iconthemes-4.8.5 package on Gentoo.
+
* The Linux Mint icon comes from the Linux Mint 11.1 user guide
(http://ftp.heanet.ie/pub/linuxmint.com/docs/user-guide/)
IN OUT LIST_ENTRY *BdsBootOptionList\r
);\r
\r
-//\r
-// Bds misc lib functions\r
-//\r
-/**\r
- Get boot mode by looking up the configuration table and parsing the HOB list.\r
-\r
- @param BootMode The boot mode from PEI handoff HOB.\r
-\r
- @retval EFI_SUCCESS Successfully got boot mode.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibGetBootMode (\r
- OUT EFI_BOOT_MODE *BootMode\r
- );\r
+// //\r
+// // Bds misc lib functions\r
+// //\r
+// /**\r
+// Get boot mode by looking up the configuration table and parsing the HOB list.\r
+// \r
+// @param BootMode The boot mode from PEI handoff HOB.\r
+// \r
+// @retval EFI_SUCCESS Successfully got boot mode.\r
+// \r
+// **/\r
+// EFI_STATUS\r
+// EFIAPI\r
+// BdsLibGetBootMode (\r
+// OUT EFI_BOOT_MODE *BootMode\r
+// );\r
\r
\r
/**\r
//#include <Protocol/FSInjectProtocol.h>
//#include <Protocol/MsgLog.h>
-#include "lib.h"
+//#include "lib.h"
//#include "boot.h"
//#include "BiosVideo.h"
#include "../include/Bmp.h"
INCLUDE_DIRS = -I $(EDK2BASE)/MdePkg \
-I $(EDK2BASE)/MdePkg/Include \
+ -I $(EDK2BASE)/MdeModulePkg/ \
-I $(EDK2BASE)/MdeModulePkg/Include \
-I $(EDK2BASE)/IntelFrameworkPkg/Include \
-I $(EDK2BASE)/MdePkg/Include/$(ARCHDIR) \
CC=gcc
CXX=g++
CXXFLAGS=-O2 -fpic -D_REENTRANT -D_GNU_SOURCE -Wall -g
-NAMES=prefit
+NAMES=refind
SRCS=$(NAMES:=.c)
OBJS=$(NAMES:=.o)
HEADERS=$(NAMES:=.h)
0.4.8 (??/??/2012):
-------------------
+- Added the directory from which rEFInd launched to dont_scan_dirs. This
+ works around a bug in which rEFInd would show itself as a bogus Windows
+ entry if it's installed as EFI/Microsoft/boot/bootmgfw.efi.
+
+- Added support for launching MokManager.efi for managing the Machine Owner
+ Keys (MOKs) maintained by the Shim boot loader developed by Fedora and
+ SUSE.
+
+- Added support for Apple's Recovery HD partition: If it's detected, a new
+ icon appears on the second row. This icon can be removed by explicitly
+ setting the "showtools" option in refind.conf and excluding the
+ "apple_recovery" option from that line.
+
- Fixed bug that caused text-mode ("textonly" refind.conf option enabled)
menu entries to be right-aligned rather than left-aligned when rEFInd was
compiled with the TianoCore EDK2.
</tr>
<tr>
<td><tt>showtools</tt></td>
- <td><tt>shell</tt>, <tt>gptsync</tt>, <tt>about</tt>, <tt>apple_recovery</tt>, <tt>exit</tt>, <tt>shutdown</tt>, and <tt>reboot</tt></td>
- <td>Specifies which tool tags to display on the second row. <tt>shell</tt> launches an EFI shell, <tt>gptsync</tt> launches a tool that creates a hybrid MBR, <tt>about</tt> displays information about the program, <tt>apple_recovery</tt> boots the OS X Recovery HD, <tt>exit</tt> terminates rEFInd, <tt>shutdown</tt> shuts down the computer (or reboots it, on UEFI PCs), and <tt>reboot</tt> reboots the computer. The tags appear in the order in which you specify them. The default is <tt>shell, about, apple_recovery, shutdown, reboot</tt>. Note that the <tt>shell</tt>, <tt>apple_recovery</tt>, and <tt>gptsync</tt> options all require the presence of programs not included with rEFInd. See the <a href="installing.html#addons">"Installing Additional Components"</a> section of the <a href="installing.html">Installing rEFInd</a> page for pointers to the shell and <tt>gptsync</tt> programs. The <tt>apple_recovery</tt> option will appear only if you've got an Apple Recovery HD partition (which has a boot loader called <tt>com.apple.recovery.boot/boot.efi</tt>).</td>
+ <td><tt>shell</tt>, <tt>gptsync</tt>, <tt>apple_recovery</tt>, <tt>mok_tool</tt>, <tt>about</tt>, <tt>exit</tt>, <tt>shutdown</tt>, and <tt>reboot</tt></td>
+ <td>Specifies which tool tags to display on the second row. <tt>shell</tt> launches an EFI shell, <tt>gptsync</tt> launches a tool that creates a hybrid MBR, <tt>apple_recovery</tt> boots the OS X Recovery HD, <tt>mok_tool</tt> launches a tool to manage Machine Owner Keys (MOKs) on systems with Secure Boot active, <tt>about</tt> displays information about the program, <tt>exit</tt> terminates rEFInd, <tt>shutdown</tt> shuts down the computer (or reboots it, on UEFI PCs), and <tt>reboot</tt> reboots the computer. The tags appear in the order in which you specify them. The default is <tt>shell, apple_recovery, mok_tool, about, shutdown, reboot</tt>. Note that the <tt>shell</tt>, <tt>apple_recovery</tt>, <tt>mok_tool</tt>, and <tt>gptsync</tt> options all require the presence of programs not included with rEFInd. See the <a href="installing.html#addons">"Installing Additional Components"</a> section of the <a href="installing.html">Installing rEFInd</a> page for pointers to the shell and <tt>gptsync</tt> programs. The <tt>apple_recovery</tt> option will appear only if you've got an Apple Recovery HD partition (which has a boot loader called <tt>com.apple.recovery.boot/boot.efi</tt>). See the <a href="secureboot.html">Secure Boot</a> page for information on Secure Boot and MOK management.</td>
</tr>
<tr>
<td><tt>textonly</tt></td>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 4/19/2012; last Web page update:
-11/6/2012, referencing rEFInd 0.4.7</p>
+11/15/2012, referencing rEFInd 0.4.7</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>All of these drivers rely on filesystem wrapper code written by rEFIt's author, Christoph Phisterer. They all suffer from speed problems on some systems, as described later in <a href="#notes">"Notes on Specific Drivers;"</a> however, these problems are very minor on most systems.</p>
-<p class="sidebar"><b>Note:</b> rEFInd's <tt>install.sh</tt> script does not currently install drivers; however, if you installed manually, you may have already installed rEFInd's drivers. See the <a href="installing.html">Installing rEFInd</a> page for details.</p>
+<p class="sidebar"><b>Note:</b> rEFInd's <tt>install.sh</tt> script does not install drivers by default. It does if you pass it the <tt>--drivers</tt> option, though. If you installed manually, you may also have installed rEFInd's drivers. See the <a href="installing.html">Installing rEFInd</a> page for details.</p>
<p>If you want to use one or more of these drivers, you can install them from the rEFInd binary package from the <tt>refind/drivers_<tt class="variable">arch</tt></tt> directory, where <tt class="variable">arch</tt> is a CPU architecture code—<tt>x64</tt> or <tt>ia32</tt>. The files are named after the filesystems they handle, such as <tt>ext2_x64.efi</tt> for the 64-bit ext2fs driver. You should copy the files for the filesystems you want to use to the <tt>drivers</tt> or <tt>drivers_<tt class="variable">arch</tt></tt> subdirectory of the main rEFInd installation directory. (You may need to create this subdirectory.) Be careful to install drivers only for your own architecture. Attempting to load drivers for the wrong CPU type will cause a small delay at best, or may cause the computer to crash at worst. I've placed rEFInd's drivers in directories that are named to minimize this risk, but you should exercise care when copying driver files.</p>
fs0: <tt class="userinput">map -r</tt>
</pre>
-<p>If you build rEFInd from source, you should be aware that the drivers rely on <a href="https://sourceforge.net/projects/tianocore/">TianoCore's development kit,</a> whereas rEFInd itself uses <a href="http://sourceforge.net/projects/gnu-efi/">GNU-EFI.</a> Thus, to compile both, you'll need to install both development kits. Unfortunately, the TianoCore kit is a bit unusual from a Linux developer's perspective, and you'll probably have to build it from source code. Consult the <tt>BUILDING.txt</tt> file in the source package for more information. None of this is important if you use a binary build of rEFInd, unless you've obtained it from a third party who hasn't built the drivers. If that's the case, you'll have to download rEFInd from Sourceforge (see the <a href="http://www.rodsbooks.com/refind/getting.html">Getting rEFInd page</a> for details) or use drivers from another source.</p>
+<p>If you build rEFInd from source, you should be aware that the drivers rely on <a href="https://sourceforge.net/projects/tianocore/">TianoCore's development kit,</a> whereas rEFInd itself can use either TianoCore's kit or <a href="http://sourceforge.net/projects/gnu-efi/">GNU-EFI.</a> Thus, to compile both, you'll need to install TianoCore, with GNU-EFI being optional but providing no additional benefits. Unfortunately, the TianoCore kit is a bit unusual from a Linux developer's perspective, and you'll probably have to build it from source code. Consult the <tt>BUILDING.txt</tt> file in the source package for more information. None of this is important if you use a binary build of rEFInd, unless you've obtained it from a third party who hasn't built the drivers. If that's the case, you'll have to download rEFInd from Sourceforge (see the <a href="http://www.rodsbooks.com/refind/getting.html">Getting rEFInd page</a> for details) or use drivers from another source.</p>
<h2>Finding Additional EFI Drivers</h2>
<ul>
-<li><b><a href="http://refit.sourceforge.net">rEFIt's ext2fs and ReiserFS drivers</a></b>—You can gain read-only access to ext2fs, ext3fs, and ReiserFS volumes with these drivers. You can use the binaries in the <tt>refit-bin-0.14/efi/tools/drivers</tt> directory of the binary package directly on a Mac. On a UEFI-based PC, though, you'll need to break the Mac-style "fat" binary into its 32- and 64-bit components. You can use my <a href="http://www.rodsbooks.com/thin/index.html"><tt>thin</tt></a> program for this job.</li>
+<li><b><a href="http://refit.sourceforge.net">rEFIt's ext2fs and ReiserFS drivers</a></b>—You can gain read-only access to ext2fs, ext3fs, and ReiserFS volumes with these drivers, originally written by Christoph Pfisterer. You can use the binaries in the <tt>refit-bin-0.14/efi/tools/drivers</tt> directory of the binary package directly on a Mac. On a UEFI-based PC, though, you'll need to break the Mac-style "fat" binary into its 32- and 64-bit components. You can use my <a href="http://www.rodsbooks.com/thin/index.html"><tt>thin</tt></a> program for this job.</li>
<li><b><a href="https://sourceforge.net/projects/cloverefiboot/">Clover EFI's ISO-9660, ext2fs, and HFS+ drivers</a></b>—This project is an offshoot of TianoCore, the main UEFI project. It's primarily a Hackintosh boot loader, but it includes drivers for <a href="http://cloverefiboot.svn.sourceforge.net/viewvc/cloverefiboot/VBoxFsDxe/">ISO-9660, ext2fs, and HFS+;</a> however, building them requires a fair amount of expertise. These drivers served as a starting point for rEFInd's drivers.</li>
<li><b><a href="https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxFsDxe">VirtualBox's HFS+ and ISO-9660 drivers</a></b>—These drivers are available in source code form, and come with VirtualBox binaries. I've not attempted to compile them myself, but I've seen a report that suggests they may include assumptions that require use of <a href="http://www.mingw.org/">MinGW,</a> a GCC-based compiler for Windows (and cross-compiler to build Windows executables under Linux). I don't know of a source for binaries suitable for use on EFI-based computers; if you want to use them, you'll need to figure out how to compile them yourself.</li>
+<li><b>Ext2Pkg</b>—This driver, based on <a href="https://bitbucket.org/alinrus/ext2pkg">bitbucket</a> and with a backup on <a href="https://github.com/the-ridikulus-rat/Tianocore_Ext2Pkg">github,</a> appears to be an ext2fs/ext3fs driver built independently of the driver written by Christoph Pfisterer. The linked-to sites provide access to source code via <tt>git</tt> but do not provide binaries. When I built binaries, they failed to work. Under VirtualBox, the driver loaded but then hung when I tried to access an ext2 filesystem. On a 32-bit Mac Mini, I got error messages when I tried to access an ext2 filesystem. As I write, the code was last updated in March of 2012. If you check the project and it's been updated more recently, it might be worth trying. Otherwise, I can't recommend this driver. I mention it here only in case it improves in the future.</li>
+
</ul>
<p>Most of these cross-project drivers appear to be related, and most of them have fed into rEFInd's drivers. I used the Clover package, which in turn was based on the VirtualBox drivers, as a starting point. Everybody else has dropped rEFIt's original ReiserFS driver, but I added that back. Of these drivers, only the Clover EFI Tools NTFS driver is missing from rEFInd. Specific versions can have their own quirks, though. For instance, the Clover (and I suspect VirtualBox) drivers don't return volume labels, which causes rEFInd to display loaders on those volumes as being on a disk called <tt>Unknown</tt>. (I fixed that bug for rEFInd's version, and it wasn't present in the original rEFIt drivers.)</p>
<h2>Notes on Specific Drivers</h2>
</a>
-<p>I've tested several of the drivers described on this page on a handful of systems. The ext2fs driver (from any source) works on both ext2fs and ext3fs, but not on ext4fs—at least, not in my one test. (There may be options you can use when creating an ext4 filesystem that would enable the ext2fs driver to handle it, but if so I don't know what they are.) The ReiserFS driver is obviously useful only on ReiserFS partitions. (Reiser4 is not supported, as far as I know.) Given that these filesystems are getting a bit on in age by Linux standards, you might do well to use them on a separate Linux <tt>/boot</tt> partition; however, if you're willing to use ext3fs or ReiserFS on your root (<tt>/</tt>) filesystem, you can use the EFI drivers to read your kernel from it. Note that this assumes you use conventional partitions; to the best of my knowledge, there's no EFI driver for Linux's Logical Volume Manager (LVM) or Redundant Array of Independent Disks (RAID) configurations, so the EFI can't access filesystems stored in these ways.</p>
+<p>I've tested several of the drivers described on this page on a handful of systems. The Pfisterer ext2fs driver (from any source) works on both ext2fs and ext3fs, but not on ext4fs—at least, not in my one test. (There may be options you can use when creating an ext4 filesystem that would enable the ext2fs driver to handle it, but if so I don't know what they are.) The ReiserFS driver is obviously useful only on ReiserFS partitions. (Reiser4 is not supported, as far as I know.) Given that these filesystems are getting a bit on in age by Linux standards, you might do well to use them on a separate Linux <tt>/boot</tt> partition; however, if you're willing to use ext3fs or ReiserFS on your root (<tt>/</tt>) filesystem, you can use the EFI drivers to read your kernel from it. Note that this assumes you use conventional partitions; to the best of my knowledge, there's no EFI driver for Linux's Logical Volume Manager (LVM) or Redundant Array of Independent Disks (RAID) configurations, so the EFI can't access filesystems stored in these ways.</p>
-<p>The ext2fs and ReiserFS drivers work, but they are a bit sluggish—particularly the ext2fs driver. The extent of the problem depends on the computer. In my tests so far, VirtualBox has fared the worst. On it, loading a Linux kernel with EFI stub loader from a FAT partition takes 2 seconds, from the moment of selecting the OS in rEFInd to the moment the kernel messages begin to appear. The equivalent time using ReiserFS or HFS+ is 20 seconds, and with ext2fs it's 200 seconds (that is, 3 minutes and 20 seconds). On a 32-bit Mac Mini, though, the speed problem is much less pronounced—my kernel loads in just 3 seconds from a ReiserFS partition and in 13 seconds from an ext2 filesystem. Speeds were similar with my newest computer, an ASUS P8H77-I board. Times with ext2fs on a UEFI PC with an Intel motherboard are in the 2–4 second range. If you try the ext2fs driver and it seems to hang, be patient; it may finally boot up. If so, and if the delay is too great for you to accept, you might consider using ReiserFS instead of ext2fs or ext3fs, at least if a change is practical. (For a <tt>/boot</tt> partition, it almost certainly is practical; you can back it up quite easily, create a fresh filesystem on it, and restore it. You may need to adjust your <tt>/etc/fstab</tt> entry for a new UUID value, though. As noted earlier, be sure to use <tt>notail</tt> as an option in <tt>/etc/fstab</tt> for ReiserFS if you want to read it from EFI.) You can even use HFS+ on a Linux <tt>/boot</tt> partition, although this makes the most sense on a Mac, which has its own EFI HFS+ driver.</p>
+<p>The Pfisterer ext2fs and ReiserFS drivers work, but they are a bit sluggish—particularly the ext2fs driver. The extent of the problem depends on the computer. In my tests so far, VirtualBox has fared the worst. On it, loading a Linux kernel with EFI stub loader from a FAT partition takes 2 seconds, from the moment of selecting the OS in rEFInd to the moment the kernel messages begin to appear. The equivalent time using ReiserFS or HFS+ is 20 seconds, and with ext2fs it's 200 seconds (that is, 3 minutes and 20 seconds). On a 32-bit Mac Mini, though, the speed problem is much less pronounced—my kernel loads in just 3 seconds from a ReiserFS partition and in 13 seconds from an ext2 filesystem. Speeds were similar with my newest computer, an ASUS P8H77-I board. Times with ext2fs on a UEFI PC with an Intel motherboard are in the 2–4 second range. If you try the ext2fs driver and it seems to hang, be patient; it may finally boot up. If so, and if the delay is too great for you to accept, you might consider using ReiserFS instead of ext2fs or ext3fs, at least if a change is practical. (For a <tt>/boot</tt> partition, it almost certainly is practical; you can back it up quite easily, create a fresh filesystem on it, and restore it. You may need to adjust your <tt>/etc/fstab</tt> entry for a new UUID value, though. As noted earlier, be sure to use <tt>notail</tt> as an option in <tt>/etc/fstab</tt> for ReiserFS if you want to read it from EFI.) You can even use HFS+ on a Linux <tt>/boot</tt> partition, although this makes the most sense on a Mac, which has its own EFI HFS+ driver. Of course, you can also create a FAT <tt>/boot</tt> partition and not deal with drivers at all. Mounting your ESP at <tt>/boot</tt> is a practical solution for many users.</p>
<p>Since the ext2fs and ReiserFS drivers share a common origin, it should come as no surprise that they perform in much the same way no matter which version (rEFIt, Clover, or rEFInd) you use. The NTFS driver from the Clover Tools package is nice and speedy, so if for some reason you need to place a boot loader on an NTFS volume, this driver might be worth tracking down.</p>
<h2>Getting rEFInd from Your OS's Repositories</h2>
-<p>If you use Arch Linux, you can obtain rEFInd from its repositories, in both <a href="https://www.archlinux.org/packages/extra/any/refind-efi/">stable</a> and <a href="https://aur.archlinux.org/packages/refind-efi-tianocore-git/">git (experimental)</a> releases. The git release is likely to include pre-release bug fixes and new features, but those features may be poorly tested or undocumented.</p>
+<p>I know of a small number of pre-packaged versions of rEFInd, either in official OS repositories or in ancillary repositories:</p>
-<p>You can also obtain rEFInd from the <a href="http://nixos.org/nixpkgs/">Nix Packages collection,</a> which creates packages for a number of OSes using its own packaging system.</p>
+<ul>
+
+<li><b>Arch Linux</b>—You can obtain rEFInd from the Arch
+ repositories, in both <a
+ href="https://www.archlinux.org/packages/extra/any/refind-efi/">stable</a>
+ and <a
+ href="https://aur.archlinux.org/packages/refind-efi-tianocore-git/">git
+ (experimental)</a> releases. The git release is likely to include
+ pre-release bug fixes and new features, but those features may be
+ poorly tested or undocumented. The last I checked, both builds used the
+ Tianocore toolkit, and so support booting BIOS/legacy boot loaders on
+ UEFI-based PCs.</li>
+
+<li><b>The <a href="http://nixos.org/nixpkgs/">Nix Packages
+ collection</a></b>—This site creates packages for a number of
+ OSes using its own packaging system.</li>
+
+<li><b><a
+ href="https://build.opensuse.org/package/show?package=refind&project=home%3Amichael-chang%3AUEFI">OpenSUSE
+ Build Service (OBS)</a></b>—This site holds a binary x86-64 build
+ of rEFInd that should install on any RPM-based distribution. It doesn't
+ completely set up rEFInd, though; it just places the rEFInd files in
+ the <tt>/usr/share/refind</tt> directory, and a copy of
+ <tt>install.sh</tt> as <tt>/usr/sbin/refind_install</tt>.
+ Unfortunately, the script makes assumptions about the locations of
+ files and so is useless when files are moved around in this way. Thus,
+ you'll need to install manually after installing this RPM, so you might
+ as well download the rEFInd binary <tt>.zip</tt> file from Sourceforge
+ instead.</li>
+
+</ul>
<p>To the best of my knowledge, no other Linux distribution yet includes rEFInd in its repositories. That's likely to change in time. If you hear of rEFInd being included in an OS's official package set, feel free to <a href="mailto:rodsmith@rodsbooks.com">drop me a line.</a></p>
<li><a href="linux.html">Options for Booting Linux</a>—Methods of booting Linux, particularly with the EFI stub loader (distribution maintainers should read this!)</li>
+<li><a href="secureboot.html">Managing Secure Boot</a>—Some pointers on using rEFInd on a computer with Secure Boot active</li>
+
<li><a href="revisions.html">Revisions</a>—Information on the history of rEFInd releases</li>
<li><a href="todo.html">The Future of rEFInd</a>—Current bugs that need squashing and features that I hope to one day add</a></li>
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
<p>Originally written: 3/14/2012; last Web page update:
-11/7/2012, referencing rEFInd 0.4.7</p>
+11/15/2012, referencing rEFInd 0.4.7</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>Rename the configuration file by typing <tt><b>mv refind.conf-sample refind.conf</b></tt>. Consult the <a href="configfile.html">Editing the rEFInd Configuration File</a> page for information on how to adjust your options.</li>
-<p class="sidebar"><b>Weird:</b> I've received one report about a Lenovo computer that works only if rEFInd is installed using the name (<tt>-L</tt> parameter) <tt>Windows Boot Manager</tt> and the existing Windows boot loader, if present, is renamed.</p>
+<p class="sidebar"><b>Weird:</b> A <a href="http://mjg59.dreamwidth.org/20187.html">bug exists</a> in some Lenovo computers (and perhaps in some others, too) that causes the firmware's boot manager to refuse to boot any boot loader that doesn't have the name <tt>Windows Boot Manager</tt> or <tt>Red Hat Enterprise Linux</tt>. If you have such a system, you must pass one of those names (in quotes) rather than <tt>rEFInd</tt> to <tt>efibootmgr</tt> via its <tt>-L</tt> option. This bug was reported to Lenovo in mid-November 2012, so with any luck updated firmware without this bug will be available later this year or early in 2013. I can make no promises about this, though.</p>
<a name="efibootmgr">
-<li>On a UEFI-based system, type <tt><b>efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd</b></tt> to add rEFInd to your EFI's list of available boot loaders, which it stores in NVRAM. (Adjust the path to the binary as required if you install somewhere else.) You may need to install this program on some systems; it's a standard part of most distributions' repositories.</li>
+<li>On a UEFI-based system, type <tt><b>efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd</b></tt> to add rEFInd to your EFI's list of available boot loaders, which it stores in NVRAM. Adjust the path to the binary as required if you install somewhere else. You may also need to include additional options if your ESP isn't on <tt>/dev/sda1</tt> or if your configuration is otherwise unusual; consult the <tt>efibootmgr</tt> man page for details. You may need to install this program on some systems; it's a standard part of most distributions' repositories.</li>
</a>
<li>If other boot loaders are already installed, you can use <tt>efibootmgr</tt> to adjust their boot order. For instance, <b><tt>efibootmgr -o 3,7,2</tt></b> sets the firmware to try boot loader #3 first, followed by #7, followed by #2. (The program should have displayed a list of boot loaders when you added yours in the preceding step.) Place rEFInd's number first to set it as the default boot program.</li>
<h2>Installing rEFInd Manually Using Windows</h2>
</a>
+<p class="sidebar"><b>Warning:</b> Windows 8 implements a fast shutdown feature that helps speed up shutdown and startup operations on a single-boot computer. Unfortunately, this feature can cause filesystem corruption if it's used on a multi-boot computer. You can disable the feature by launching an Administrator Command Prompt window and typing <tt class="userinput">powercfg /h off</tt> in it.</p>
+
<p>To install rEFInd under Windows, you must first find a way to access the ESP, which Windows normally hides from view. One way to accomplish this goal, and to proceed forward once the ESP is accessible, is as follows:</p>
<ol>
<p>When you reboot, rEFInd should come up. With any luck, it will detect your old boot loader as an option, if one was installed before.</p>
-<p>If your computer seems to insist on booting an EFI boot loader called <tt>EFI/Microsoft/BOOT/bootmgfw.efi</tt>, be aware that it might not actually be looking for that filename, but for a boot manager with the EFI description <tt>Microsoft Boot Manager</tt>. Changing the description of the "real" <tt>EFI/Microsoft/BOOT/bootmgfw.efi</tt> using <tt>efibootmgr</tt> and then giving rEFInd that description, even when rEFInd is installed in a more conventional location, may work. I've received a report that at least one Lenovo model has this peculiar affliction.</p>
-
<a name="upgrading">
<h2>Upgrading rEFInd</h2>
</a>
</ol>
+<a name="uninstalling">
+<h2>Uninstalling rEFInd</h2>
+</a>
+
+<p>If you decide you don't want to keep rEFInd, you can uninstall it. Doing so is a matter of removing the rEFInd files from your ESP (or from your OS X boot partition, if you installed the program there). In Linux, a command like the following, typed as <tt>root</tt>, should do the trick:</p>
+
+<pre class="listing">
+# <tt class="userinput">rm -r /boot/efi/EFI/refind</tt>
+</pre>
+
+<p>This example assumes that your ESP is mounted at <tt>/boot/efi</tt> and that rEFInd is installed in <tt>EFI/refind</tt> on that partition. If you've mounted your ESP elsewhere, or installed rEFInd elsewhere, you should adjust the command appropriately.</p>
+
+<p>The same procedure works in OS X, with the caveat that the ESP isn't normally mounted in OS X and rEFInd is installed to the OS X boot partition by default. You'll also need to use <tt>sudo</tt> to acquire <tt>root</tt> privileges. Thus, you'd probably use a command like the following in OS X:</p>
+
+<pre class="listing">
+$ <tt class="userinput">sudo rm -r /EFI/refind</tt>
+</pre>
+
+<p>Many variants of both of these commands are possible on both OS X and Linux. For instance, you'd probably use <tt>sudo</tt> on Ubuntu; and if you installed rEFInd to your ESP on a Mac, you'd need to first mount the ESP and include its path in the <tt>rm</tt> command.</p>
+
+<p>From Windows, you must reverse the directions for <a href="#windows">installing in Windows</a>—type <tt class="userinput">mountvol S: /S</tt> to mount your ESP as <tt>S:</tt>, then navigate to the <tt>S:\EFI</tt> directory and delete the <tt>refind</tt> subdirectory.</p>
+
+<p>In any of these cases, when the computer boots and cannot find the rEFInd files, it should move on to the next boot loader in its list. In my experience, some EFI firmware implementations remove boot loaders they can't find from their NVRAM lists, so nothing else will be required, provided you have another working boot loader in your firmware's list. If your firmware doesn't automatically clean up its NVRAM entries, rEFInd's entry will do little harm; however, you can delete it with the <tt>efibootmgr</tt> utility in Linux:</p>
+
+<pre class="listing">
+# <tt class="userinput">efibootmgr --verbose</tt>
+Timeout: 10 seconds
+BootOrder: 0000,0007
+Boot0000* rEFInd HD(2,1b8,64000,f1b7598e-baa8-16ea-4ef6-3ff3b606ac1e)File(\EFI\refind\refind.efi)
+Boot0007* CD/DVD Drive BIOS(3,0,00)PATA: HP DVD Writer 1040r .
+# <tt class="userinput">efibootmgr --delete-bootnum --bootnum 0000</tt>
+Timeout: 10 seconds
+BootOrder: 0007
+Boot0007* CD/DVD Drive</pre>
+
+<p class="sidebar"><b>Warning:</b> As noted earlier, <tt>efibootmgr</tt> has been linked to firmware corruption on some Macs, at least with pre-3.0 Linux kernels. Therefore, I don't recommend using <tt>efibootmgr</tt> on Macs.</p>
+
+<p>This example shows use of <tt>efibootmgr</tt>'s <tt>--verbose</tt> (<tt>-v</tt>) option to display boot loaders so as to identify which one is rEFInd, followed by <tt>--delete-bootnum</tt> (<tt>-B</tt>) to delete a boot program and <tt>--bootnum</tt> (<tt>-b</tt>) to identify which one to delete. Of course, in this example there's not much else left, so you'd presumably want to install another boot loader at this point! If you already have another one installed, you may want to check the <tt>BootOrder</tt> line to determine which one will take precedence when you reboot. If you don't like what it shows, you can adjust it with the <tt>--bootorder</tt> (<tt>-o</tt>) option; consult <tt>efibootmgr</tt>'s <tt>man</tt> page for details.</p>
+
+<p>If you're not using Linux, you may be able to find a utility that serves a similar function. The OS X <tt>bless</tt> utility (or its GUI equivalent, the Startup Disk item in System Preferences) should do the trick; but Macs pick up standard OS X boot loaders when they boot and find that a configured non-standard boot loader is missing, so this shouldn't be necessary on Macs. Under Windows, the <tt>bcdedit</tt> command, described in the <a href="#windows">section on installing rEFInd under Windows,</a> may work, although I've not attempted this.</p>
+
<hr />
<p>copyright © 2012 by Roderick W. Smith</p>
<p><a href="index.html">Go to the main rEFInd page</a></p>
-<p><a href="revisions.html">Learn about rEFInd's history</a></p>
+<p><a href="secureboot.html">Learn how to manage Secure Boot</a></p>
<p><a href="http://www.rodsbooks.com/">Return</a> to my main Web page.</p>
</body>
#define refit_call10_wrapper(f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+#define uefi_call_wrapper(f, n, ...) \
+ f(__VA_ARGS__)
+
#endif /* not GNU EFI -- TianoCore EDK2 */
#endif /* !__REFIT_CALL_WRAPPER_H__ */
# documentation for details)
# gptsync - the (dangerous) gptsync.efi utility (requires external
# program; see rEFInd documentation for details)
-# about - an "about this program" option
# apple_recovery - boots the Apple Recovery HD partition, if present
+# mok_tool - makes available the Machine Owner Key (MOK) maintenance
+# tool, MokManager.efi, used on Secure Boot systems
+# about - an "about this program" option
# exit - a tag to exit from rEFInd
# shutdown - shuts down the computer (a bug causes this to reboot
# EFI systems)
# reboot - a tag to reboot the computer
-# Default is shell,about,apple_recovery,shutdown,reboot
+# Default is shell,apple_recovery,mok_tool,about,shutdown,reboot
#
#showtools shell, about, reboot
options "fs0:\EFI\tools\launch_windows.nsh"
disabled
}
+
+# Mac OS is normally detected and run automatically; however,
+# if you want to do something unusual, a manual boot stanza may
+# be the way to do it. This one does nothing very unusual, but
+# it may serve as a starting point. Note that you'll almost
+# certainly need to change the "volume" line for this example
+# to work.
+menuentry "My Mac OS X" {
+ icon \EFI\refind\icons\os_mac.icns
+ volume "OS X boot"
+ loader \System\Library\CoreServices\boot.efi
+ disabled
+}
refind/menu.c\r
refind/screen.c\r
refind/driver_support.c\r
+ refind/mok.c\r
libeg/image.c\r
libeg/load_bmp.c\r
libeg/load_icns.c\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
-# MdeModulePkg/MdeModulePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
IntelFrameworkPkg/IntelFrameworkPkg.dec\r
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
\r
HobLib\r
MemoryAllocationLib\r
IoLib\r
+ PerformanceLib\r
\r
[Guids]\r
gEfiAcpiTableGuid\r
\r
gEfiLegacyBiosProtocolGuid # PROTOCOL TO_START\r
\r
+ gEfiLoadFile2ProtocolGuid\r
+ gEfiLoadFileProtocolGuid\r
+ gEfiHiiPackageListProtocolGuid\r
+\r
[FeaturePcd]\r
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport\r
\r
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiScsiIoProtocolGuid = { 0x932F47e6, 0x2362, 0x4002, { 0x80, 0x3E, 0x3C, 0xD5, 0x4B, 0x13, 0x8F, 0x85 }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiScsiPassThruProtocolGuid = { 0xA59E8FCF, 0xBDA0, 0x43BB, { 0x90, 0xB1, 0xD3, 0x73, 0x2E, 0xCA, 0xA8, 0x77 }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiSimpleNetworkProtocolGuid = { 0xA19832B9, 0xAC25, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiUgaDrawProtocolGuid = { 0x982C298B, 0xF4FA, 0x41CB, { 0xB8, 0x38, 0x77, 0xAA, 0x68, 0x8F, 0xB8, 0x39 }};
+//GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiUgaDrawProtocolGuid = { 0x982C298B, 0xF4FA, 0x41CB, { 0xB8, 0x38, 0x77, 0xAA, 0x68, 0x8F, 0xB8, 0x39 }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiAbsolutePointerProtocolGuid = { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } };
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiAcpiTableProtocolGuid = { 0xFFE06BDD, 0x6107, 0x46A6, { 0x7B, 0xB2, 0x5A, 0x9C, 0x7E, 0xC5, 0x27, 0x5C }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiEdidActiveProtocolGuid = { 0xBD8C1056, 0x9F36, 0x44EC, { 0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86 }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiSimplePointerProtocolGuid = { 0x31878C87, 0x0B75, 0x11D5, { 0x9A, 0x4F, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiSmbiosProtocolGuid = {0x3583ff6, 0xcb36, 0x4940, { 0x94, 0x7e, 0xb9, 0xb3, 0x9f, 0x4a, 0xfa, 0xf7}};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiSecurityArchProtocolGuid = { 0xA46423E3, 0x4617, 0x49F1, { 0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 }};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiLegacyBiosProtocolGuid = { 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d }};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiLoadFile2ProtocolGuid = { 0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d }};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiLoadFileProtocolGuid = { 0x56EC3091, 0x954C, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiHiiPackageListProtocolGuid = { 0x6a1ee763, 0xd47a, 0x43b4, {0xaa, 0xbe, 0xef, 0x1d, 0xe2, 0xab, 0x56, 0xfc}};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiDriverBindingProtocolGuid = { 0x18A031AB, 0xB443, 0x4D1A, { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiComponentNameProtocolGuid = { 0x107A772C, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiDriverConfigurationProtocolGuid = { 0x107A772B, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiDriverConfiguration2ProtocolGuid = { 0xBFD7DC1D, 0x24F1, 0x40D9, { 0x82, 0xE7, 0x2E, 0x09, 0xBB, 0x6B, 0x4E, 0xBE }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiDriverDiagnosticsProtocolGuid = { 0x0784924F, 0xE296, 0x11D4, { 0x9A, 0x49, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = { 0x4D330321, 0x025F, 0x4AAC, { 0x90, 0xD8, 0x5E, 0xD9, 0x00, 0x17, 0x3B, 0x63 }};
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiLoadFileProtocolGuid = { 0x56EC3091, 0x954C, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiLoadFile2ProtocolGuid = { 0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d }};
// Definition of PCDs used in this module
-GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdUgaConsumeSupport = _PCD_VALUE_PcdUgaConsumeSupport;
+//GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdUgaConsumeSupport = _PCD_VALUE_PcdUgaConsumeSupport;
// Definition of PCDs used in libraries
-#define _PCD_TOKEN_PcdDebugPrintErrorLevel 5U
-#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x80000000U
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel = _PCD_VALUE_PcdDebugPrintErrorLevel;
-extern const UINT32 _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel;
-#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel
-//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdDebugClearMemoryValue 10U
-#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gPcd_FixedAtBuild_PcdDebugClearMemoryValue = _PCD_VALUE_PcdDebugClearMemoryValue;
-extern const UINT8 _gPcd_FixedAtBuild_PcdDebugClearMemoryValue;
-#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _gPcd_FixedAtBuild_PcdDebugClearMemoryValue
-//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdDebugPropertyMask 11U
-#define _PCD_VALUE_PcdDebugPropertyMask 0x0fU
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gPcd_FixedAtBuild_PcdDebugPropertyMask = _PCD_VALUE_PcdDebugPropertyMask;
-extern const UINT8 _gPcd_FixedAtBuild_PcdDebugPropertyMask;
-#define _PCD_GET_MODE_8_PcdDebugPropertyMask _gPcd_FixedAtBuild_PcdDebugPropertyMask
-//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdMaximumLinkedListLength 6U
+#define _PCD_TOKEN_PcdMaximumLinkedListLength 2U
#define _PCD_VALUE_PcdMaximumLinkedListLength 1000000U
GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdMaximumLinkedListLength = _PCD_VALUE_PcdMaximumLinkedListLength;
extern const UINT32 _gPcd_FixedAtBuild_PcdMaximumLinkedListLength;
#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _gPcd_FixedAtBuild_PcdMaximumLinkedListLength
-//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdMaximumAsciiStringLength 7U
+#define _PCD_TOKEN_PcdMaximumAsciiStringLength 3U
#define _PCD_VALUE_PcdMaximumAsciiStringLength 1000000U
GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength = _PCD_VALUE_PcdMaximumAsciiStringLength;
extern const UINT32 _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength;
#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength
-//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 8U
+#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 4U
#define _PCD_VALUE_PcdMaximumUnicodeStringLength 1000000U
GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength = _PCD_VALUE_PcdMaximumUnicodeStringLength;
extern const UINT32 _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength;
#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength
-//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdVerifyNodeInList 9U
+#define _PCD_TOKEN_PcdVerifyNodeInList 5U
#define _PCD_VALUE_PcdVerifyNodeInList ((BOOLEAN)0U)
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdVerifyNodeInList = _PCD_VALUE_PcdVerifyNodeInList;
extern const BOOLEAN _gPcd_FixedAtBuild_PcdVerifyNodeInList;
#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _gPcd_FixedAtBuild_PcdVerifyNodeInList
-//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdDriverDiagnosticsDisable 12U
+#define _PCD_TOKEN_PcdDriverDiagnosticsDisable 6U
#define _PCD_VALUE_PcdDriverDiagnosticsDisable ((BOOLEAN)0U)
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdDriverDiagnosticsDisable = _PCD_VALUE_PcdDriverDiagnosticsDisable;
extern const BOOLEAN _gPcd_FixedAtBuild_PcdDriverDiagnosticsDisable;
#define _PCD_GET_MODE_BOOL_PcdDriverDiagnosticsDisable _gPcd_FixedAtBuild_PcdDriverDiagnosticsDisable
-//#define _PCD_SET_MODE_BOOL_PcdDriverDiagnosticsDisable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_BOOL_PcdDriverDiagnosticsDisable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdComponentNameDisable 13U
+#define _PCD_TOKEN_PcdComponentNameDisable 7U
#define _PCD_VALUE_PcdComponentNameDisable ((BOOLEAN)0U)
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdComponentNameDisable = _PCD_VALUE_PcdComponentNameDisable;
extern const BOOLEAN _gPcd_FixedAtBuild_PcdComponentNameDisable;
#define _PCD_GET_MODE_BOOL_PcdComponentNameDisable _gPcd_FixedAtBuild_PcdComponentNameDisable
-//#define _PCD_SET_MODE_BOOL_PcdComponentNameDisable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_BOOL_PcdComponentNameDisable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdDriverDiagnostics2Disable 14U
-#define _PCD_VALUE_PcdDriverDiagnostics2Disable ((BOOLEAN)1U)
+#define _PCD_TOKEN_PcdDriverDiagnostics2Disable 8U
+#define _PCD_VALUE_PcdDriverDiagnostics2Disable ((BOOLEAN)0U)
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdDriverDiagnostics2Disable = _PCD_VALUE_PcdDriverDiagnostics2Disable;
extern const BOOLEAN _gPcd_FixedAtBuild_PcdDriverDiagnostics2Disable;
#define _PCD_GET_MODE_BOOL_PcdDriverDiagnostics2Disable _gPcd_FixedAtBuild_PcdDriverDiagnostics2Disable
-//#define _PCD_SET_MODE_BOOL_PcdDriverDiagnostics2Disable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_BOOL_PcdDriverDiagnostics2Disable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdComponentName2Disable 15U
-#define _PCD_VALUE_PcdComponentName2Disable ((BOOLEAN)1U)
+#define _PCD_TOKEN_PcdComponentName2Disable 9U
+#define _PCD_VALUE_PcdComponentName2Disable ((BOOLEAN)0U)
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdComponentName2Disable = _PCD_VALUE_PcdComponentName2Disable;
extern const BOOLEAN _gPcd_FixedAtBuild_PcdComponentName2Disable;
#define _PCD_GET_MODE_BOOL_PcdComponentName2Disable _gPcd_FixedAtBuild_PcdComponentName2Disable
-//#define _PCD_SET_MODE_BOOL_PcdComponentName2Disable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_BOOL_PcdComponentName2Disable ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-#define _PCD_TOKEN_PcdUefiLibMaxPrintBufferSize 17U
+#define _PCD_TOKEN_PcdUefiLibMaxPrintBufferSize 10U
#define _PCD_VALUE_PcdUefiLibMaxPrintBufferSize 320U
GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdUefiLibMaxPrintBufferSize = _PCD_VALUE_PcdUefiLibMaxPrintBufferSize;
extern const UINT32 _gPcd_FixedAtBuild_PcdUefiLibMaxPrintBufferSize;
#define _PCD_GET_MODE_32_PcdUefiLibMaxPrintBufferSize _gPcd_FixedAtBuild_PcdUefiLibMaxPrintBufferSize
-//#define _PCD_SET_MODE_32_PcdUefiLibMaxPrintBufferSize ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+#define _PCD_SET_MODE_32_PcdUefiLibMaxPrintBufferSize ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
EFI_STATUS
);
-VOID
-EFIAPI
-ProcessLibraryConstructorList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- Status = UefiBootServicesTableLibConstructor (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
- Status = UefiRuntimeServicesTableLibConstructor (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
- Status = UefiLibConstructor (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
- Status = DxeServicesTableLibConstructor (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
- Status = HobLibConstructor (ImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
-}
-
-
-
-VOID
-EFIAPI
-ProcessLibraryDestructorList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
-
-}
+// VOID
+// EFIAPI
+// ProcessLibraryConstructorList (
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+// )
+// {
+// EFI_STATUS Status;
+//
+// Status = UefiBootServicesTableLibConstructor (ImageHandle, SystemTable);
+// ASSERT_EFI_ERROR (Status);
+//
+// Status = UefiRuntimeServicesTableLibConstructor (ImageHandle, SystemTable);
+// ASSERT_EFI_ERROR (Status);
+//
+// Status = UefiLibConstructor (ImageHandle, SystemTable);
+// ASSERT_EFI_ERROR (Status);
+//
+// Status = DxeServicesTableLibConstructor (ImageHandle, SystemTable);
+// ASSERT_EFI_ERROR (Status);
+//
+// Status = HobLibConstructor (ImageHandle, SystemTable);
+// ASSERT_EFI_ERROR (Status);
+//
+// }
+
+
+
+// VOID
+// EFIAPI
+// ProcessLibraryDestructorList (
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+// )
+// {
+//
+// }
const UINT32 _gUefiDriverRevision = 0x00010000U;
-EFI_STATUS
-EFIAPI
-ProcessModuleEntryPointList (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- return efi_main (ImageHandle, SystemTable);
-}
+// EFI_STATUS
+// EFIAPI
+// ProcessModuleEntryPointList (
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+// )
+//
+// {
+// return efi_main (ImageHandle, SystemTable);
+// }
VOID
EFIAPI
gBS->Exit (gImageHandle, Status, 0, NULL);
}
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = 0U;
+//GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = 0U;
+
+// EFI_STATUS
+// EFIAPI
+// ProcessModuleUnloadList (
+// IN EFI_HANDLE ImageHandle
+// )
+// {
+// return EFI_SUCCESS;
+// }
+
+// Stuff added in effort to get Secure Boot working....
+
+#define _PCD_TOKEN_PcdDebugPropertyMask 11U
+#define _PCD_VALUE_PcdDebugPropertyMask 0x0fU
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gPcd_FixedAtBuild_PcdDebugPropertyMask = _PCD_VALUE_PcdDebugPropertyMask;
+extern const UINT8 _gPcd_FixedAtBuild_PcdDebugPropertyMask;
+#define _PCD_GET_MODE_8_PcdDebugPropertyMask _gPcd_FixedAtBuild_PcdDebugPropertyMask
+//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugClearMemoryValue 10U
+#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gPcd_FixedAtBuild_PcdDebugClearMemoryValue = _PCD_VALUE_PcdDebugClearMemoryValue;
+extern const UINT8 _gPcd_FixedAtBuild_PcdDebugClearMemoryValue;
+#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _gPcd_FixedAtBuild_PcdDebugClearMemoryValue
+//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugPrintErrorLevel 5U
+#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x80000000U
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel = _PCD_VALUE_PcdDebugPrintErrorLevel;
+extern const UINT32 _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel;
+#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _gPcd_FixedAtBuild_PcdDebugPrintErrorLevel
+//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
-EFI_STATUS
-EFIAPI
-ProcessModuleUnloadList (
- IN EFI_HANDLE ImageHandle
- )
-{
- return EFI_SUCCESS;
-}
$(EFILIB)/DxeHobLib/DxeHobLib/OUTPUT/DxeHobLib.lib \
$(EFILIB)/BaseIoLibIntrinsic/BaseIoLibIntrinsic/OUTPUT/BaseIoLibIntrinsic.lib \
$(EFILIB)/BasePeCoffLib/BasePeCoffLib/OUTPUT/BasePeCoffLib.lib
+# /usr/local/UDK2010/MyWorkSpace/Build/Mde/RELEASE_GCC46/X64/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu/OUTPUT/SecPeiDxeTimerLibCpu.lib \
+# /usr/local/UDK2010/MyWorkSpace/Build/MdeModule/RELEASE_GCC46/X64/MdeModulePkg/Core/Dxe/DxeMain/OUTPUT/DxeCore.lib \
+# /usr/local/UDK2010/MyWorkSpace/Build/Mde/RELEASE_GCC46/X64/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib/OUTPUT/BaseCacheMaintenanceLib.lib \
+# /usr/local/UDK2010/MyWorkSpace/Build/Mde/RELEASE_GCC46/X64/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull/OUTPUT/BasePerformanceLibNull.lib
+# $(EFILIB)/../../MdeModulePkg/Core/Dxe/DxeMain/OUTPUT/DxeCore.lib
+# /usr/local/UDK2010/MyWorkSpace/Build/MdeModule/RELEASE_GCC46/X64/MdeModulePkg/Core/Dxe/DxeMain/OUTPUT/DxeMain/DxeMain.obj
-SOURCE_NAMES = config driver_support icns lib main menu screen AutoGen
+SOURCE_NAMES = config driver_support icns lib main menu screen mok AutoGen
OBJS = $(SOURCE_NAMES:=.obj)
all: $(BUILDME)
LOCAL_LDFLAGS = -L$(SRCDIR)/../libeg/
LOCAL_LIBS = -leg
-OBJS = main.o config.o menu.o screen.o icns.o lib.o driver_support.o
+OBJS = main.o config.o menu.o screen.o icns.o lib.o mok.o driver_support.o
all: $(TARGET)
// read a file into a buffer
//
-static EFI_STATUS ReadFile(IN EFI_FILE_HANDLE BaseDir, CHAR16 *FileName, REFIT_FILE *File)
+EFI_STATUS ReadFile(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileName, IN OUT REFIT_FILE *File, OUT UINTN *size)
{
EFI_STATUS Status;
EFI_FILE_HANDLE FileHandle;
EFI_FILE_INFO *FileInfo;
UINT64 ReadSize;
+ CHAR16 Message[256];
File->Buffer = NULL;
File->BufferSize = 0;
// read the file, allocating a buffer on the way
Status = refit_call5_wrapper(BaseDir->Open, BaseDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
- if (CheckError(Status, L"while loading the configuration file"))
+ SPrint(Message, 255, L"while loading the file '%s'", FileName);
+ if (CheckError(Status, Message))
return Status;
FileInfo = LibFileInfo(FileHandle);
return EFI_LOAD_ERROR;
}
ReadSize = FileInfo->FileSize;
- if (ReadSize > MAXCONFIGFILESIZE)
- ReadSize = MAXCONFIGFILESIZE;
FreePool(FileInfo);
- File->BufferSize = (UINTN)ReadSize; // was limited to a few K before, so this is safe
+ File->BufferSize = (UINTN)ReadSize;
File->Buffer = AllocatePool(File->BufferSize);
+ if (File->Buffer == NULL) {
+ size = 0;
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ *size = File->BufferSize;
+ } // if/else
Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &File->BufferSize, File->Buffer);
- if (CheckError(Status, L"while loading the configuration file")) {
+ if (CheckError(Status, Message)) {
MyFreePool(File->Buffer);
File->Buffer = NULL;
refit_call1_wrapper(FileHandle->Close, FileHandle);
}
// TODO: detect other encodings as they are implemented
}
-
+
return EFI_SUCCESS;
}
return;
}
- Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File);
+ Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File, &i);
if (EFI_ERROR(Status))
return;
+ GlobalConfig.DontScan = StrDuplicate(SelfDirPath);
+
for (;;) {
TokenCount = ReadTokenLine(&File, &TokenList);
if (TokenCount == 0)
GlobalConfig.ShowTools[i - 1] = TAG_SHUTDOWN;
} else if (StriCmp(FlagName, L"apple_recovery") == 0) {
GlobalConfig.ShowTools[i - 1] = TAG_APPLE_RECOVERY;
+ } else if (StriCmp(FlagName, L"mok_tool") == 0) {
+ GlobalConfig.ShowTools[i - 1] = TAG_MOK_TOOL;
} else {
Print(L" unknown showtools flag: '%s'\n", FlagName);
}
REFIT_VOLUME *Volume;
CHAR16 **TokenList;
CHAR16 *Title = NULL;
- UINTN TokenCount;
+ UINTN TokenCount, size;
LOADER_ENTRY *Entry;
if (FileExists(SelfDir, CONFIG_FILE_NAME)) {
- Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File);
+ Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File, &size);
if (EFI_ERROR(Status))
return;
REFIT_FILE * ReadLinuxOptionsFile(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume) {
CHAR16 *OptionsFilename, *FullFilename;
BOOLEAN GoOn = TRUE;
- UINTN i = 0;
+ UINTN i = 0, size;
REFIT_FILE *File = NULL;
EFI_STATUS Status;
MergeStrings(&FullFilename, OptionsFilename, '\\');
if (FileExists(Volume->RootDir, FullFilename)) {
File = AllocateZeroPool(sizeof(REFIT_FILE));
- Status = ReadFile(Volume->RootDir, FullFilename, File);
+ Status = ReadFile(Volume->RootDir, FullFilename, File, &size);
GoOn = FALSE;
if (CheckError(Status, L"while loading the Linux options file")) {
if (File != NULL)
#define HIDEUI_FLAG_ARROWS (0x0010)
#define HIDEUI_ALL ((0xffff))
+EFI_STATUS ReadFile(IN EFI_FILE_HANDLE BaseDir, CHAR16 *FileName, REFIT_FILE *File, UINTN *size);
VOID ReadConfig(VOID);
VOID ScanUserConfigured(VOID);
UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList);
#define REFIT_DEBUG (0)
// Tag classifications; used in various ways.
-#define TAG_ABOUT (1)
-#define TAG_REBOOT (2)
-#define TAG_SHUTDOWN (3)
-#define TAG_TOOL (4)
-#define TAG_LOADER (5)
-#define TAG_LEGACY (6)
-#define TAG_EXIT (7)
-#define TAG_SHELL (8)
-#define TAG_GPTSYNC (9)
-#define TAG_LEGACY_UEFI (10)
+#define TAG_ABOUT (1)
+#define TAG_REBOOT (2)
+#define TAG_SHUTDOWN (3)
+#define TAG_TOOL (4)
+#define TAG_LOADER (5)
+#define TAG_LEGACY (6)
+#define TAG_EXIT (7)
+#define TAG_SHELL (8)
+#define TAG_GPTSYNC (9)
+#define TAG_LEGACY_UEFI (10)
#define TAG_APPLE_RECOVERY (11)
-#define NUM_TOOLS (10)
+#define TAG_MOK_TOOL (12)
+#define NUM_TOOLS (11)
#define NUM_SCAN_OPTIONS 10
{ NULL, L"tool_part.icns", 48 },
{ NULL, L"tool_rescue.icns", 48 },
{ NULL, L"tool_apple_rescue.icns", 48 },
+ { NULL, L"tool_mok_tool.icns", 48 },
{ NULL, L"vol_internal.icns", 32 },
{ NULL, L"vol_external.icns", 32 },
{ NULL, L"vol_optical.icns", 32 },
#define BUILTIN_ICON_TOOL_PART (5)
#define BUILTIN_ICON_TOOL_RESCUE (6)
#define BUILTIN_ICON_TOOL_APPLE_RESCUE (7)
-#define BUILTIN_ICON_VOL_INTERNAL (8)
-#define BUILTIN_ICON_VOL_EXTERNAL (9)
-#define BUILTIN_ICON_VOL_OPTICAL (10)
-#define BUILTIN_ICON_COUNT (11)
+#define BUILTIN_ICON_TOOL_MOK_TOOL (8)
+#define BUILTIN_ICON_VOL_INTERNAL (9)
+#define BUILTIN_ICON_VOL_EXTERNAL (10)
+#define BUILTIN_ICON_VOL_OPTICAL (11)
+#define BUILTIN_ICON_COUNT (12)
#endif
//
// Converts forward slashes to backslashes, removes duplicate slashes, and
-// removes slashes from both the start and end of the pathname.
+// removes slashes from the end of the pathname.
// Necessary because some (buggy?) EFI implementations produce "\/" strings
// in pathnames, because some user inputs can produce duplicate directory
// separators, and because we want consistent start and end slashes for
UINTN i, FinalChar = 0;
BOOLEAN LastWasSlash = FALSE;
- NewName = AllocateZeroPool(sizeof(CHAR16) * (StrLen(PathName) + 2));
+ NewName = AllocateZeroPool(sizeof(CHAR16) * (StrLen(PathName) + 4));
if (NewName != NULL) {
for (i = 0; i < StrLen(PathName); i++) {
if ((PathName[i] == L'/') || (PathName[i] == L'\\')) {
- if ((!LastWasSlash) && (FinalChar != 0))
+ if ((!LastWasSlash) /* && (FinalChar != 0) */)
NewName[FinalChar++] = L'\\';
LastWasSlash = TRUE;
} else {
+ if (FinalChar == 0) {
+ NewName[FinalChar++] = L'\\';
+ }
NewName[FinalChar++] = PathName[i];
LastWasSlash = FALSE;
} // if/else
} // for
NewName[FinalChar] = 0;
- if ((FinalChar > 0) && (NewName[FinalChar - 1] == L'\\'))
+ if ((FinalChar > 1) && (NewName[FinalChar - 1] == L'\\'))
NewName[--FinalChar] = 0;
if (FinalChar == 0) {
NewName[0] = L'\\';
}
if (DirIter->CloseDirHandle)
refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle);
- return DirIter->LastStatus;
+ return DirIter->LastStatus;
}
//
return (PathOnly);
}
+// Splits an EFI device path into device and filename components. For instance, if InString is
+// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)/\bzImage-3.5.1.efi,
+// this function will truncate that input to
+// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)
+// and return bzImage-3.5.1.efi as its return value.
+// It does this by searching for the last ")" character in InString, copying everything
+// after that string (after some cleanup) as the return value, and truncating the original
+// input value.
+// If InString contains no ")" character, this function leaves the original input string
+// unmodified and returns a NULL value.
+static CHAR16* SplitDeviceString(IN OUT CHAR16 *InString) {
+ INTN i;
+ CHAR16 *FileName = NULL;
+ BOOLEAN Found = FALSE;
+
+ i = StrLen(InString) - 1;
+ while ((i >= 0) && (!Found)) {
+ if (InString[i] == L')') {
+ Found = TRUE;
+ FileName = StrDuplicate(&InString[i + 1]);
+ CleanUpPathNameSlashes(FileName);
+ InString[i + 1] = '\0';
+ } // if
+ i--;
+ } // while
+ return FileName;
+} // static CHAR16* SplitDeviceString()
+
+// Takes an input loadpath, splits it into disk and filename components, finds a matching
+// DeviceVolume, and returns that and the filename (*loader).
+VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **DeviceVolume, OUT CHAR16 **loader) {
+ CHAR16 *DeviceString, *VolumeDeviceString, *Temp;
+ UINTN i = 0;
+ BOOLEAN Found = FALSE;
+
+ MyFreePool(*loader);
+ MyFreePool(*DeviceVolume);
+ *DeviceVolume = NULL;
+ DeviceString = DevicePathToStr(loadpath);
+ *loader = SplitDeviceString(DeviceString);
+
+ while ((i < VolumesCount) && (!Found)) {
+ VolumeDeviceString = DevicePathToStr(Volumes[i]->DevicePath);
+ Temp = SplitDeviceString(VolumeDeviceString);
+ if (StriCmp(DeviceString, VolumeDeviceString) == 0) {
+ Found = TRUE;
+ *DeviceVolume = Volumes[i];
+ }
+ MyFreePool(Temp);
+ MyFreePool(VolumeDeviceString);
+ i++;
+ } // while
+
+ MyFreePool(DeviceString);
+} // VOID FindVolumeAndFilename()
+
// Returns all the digits in the input string, including intervening
// non-digit characters. For instance, if InString is "foo-3.3.4-7.img",
// this function returns "3.3.4-7". If InString contains no digits,
MyFreePool(Handles);
return (Ejected > 0);
} // VOID EjectMedia()
+
+
+// Return the GUID as a string, suitable for display to the user. Note that the calling
+// function is responsible for freeing the allocated memory.
+CHAR16 * GuidAsString(EFI_GUID *GuidData) {
+ CHAR16 *TheString;
+
+ TheString = AllocateZeroPool(42 * sizeof(CHAR16));
+ if (TheString != 0) {
+ SPrint (TheString, 82, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (UINTN)GuidData->Data1, (UINTN)GuidData->Data2, (UINTN)GuidData->Data3,
+ (UINTN)GuidData->Data4[0], (UINTN)GuidData->Data4[1], (UINTN)GuidData->Data4[2],
+ (UINTN)GuidData->Data4[3], (UINTN)GuidData->Data4[4], (UINTN)GuidData->Data4[5],
+ (UINTN)GuidData->Data4[6], (UINTN)GuidData->Data4[7]);
+ }
+ return TheString;
+} // GuidAsString(EFI_GUID *GuidData)
CHAR16 *FindExtension(IN CHAR16 *Path);
CHAR16 *FindLastDirName(IN CHAR16 *Path);
CHAR16 *FindPath(IN CHAR16* FullPath);
+VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **DeviceVolume, OUT CHAR16 **loader);
CHAR16 *FindNumbers(IN CHAR16 *InString);
CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index);
BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List);
BOOLEAN EjectMedia(VOID);
+CHAR16 * GuidAsString(EFI_GUID *GuidData);
+
#endif
\ No newline at end of file
*/
/*
* Modifications copyright (c) 2012 Roderick W. Smith
- *
+ *
* Modifications distributed under the terms of the GNU General Public
* License (GPL) version 3 (GPLv3), a copy of which must be distributed
* with this source code or binaries made from it.
- *
+ *
*/
#include "global.h"
#include "lib.h"
#include "icns.h"
#include "menu.h"
+#include "mok2.h"
#include "../include/Handle.h"
#include "../include/refit_call_wrapper.h"
#include "driver_support.h"
//
// variables
-#define MACOSX_LOADER_PATH L"System\\Library\\CoreServices\\boot.efi"
+#define MACOSX_LOADER_PATH L"\\System\\Library\\CoreServices\\boot.efi"
#if defined (EFIX64)
#define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\shellx64.efi"
#define DRIVER_DIRS L"drivers,drivers_x64"
#define DRIVER_DIRS L"drivers"
#endif
+#define MOK_NAMES L"\\EFI\\tools\\MokManager.efi,\\EFI\\redhat\\MokManager.efi"
+
// Filename patterns that identify EFI boot loaders. Note that a single case (either L"*.efi" or
// L"*.EFI") is fine for most systems; but Gigabyte's buggy Hybrid EFI does a case-sensitive
// comparison when it should do a case-insensitive comparison, so I'm doubling this up. It does
REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- {TAG_SHELL, TAG_ABOUT, TAG_APPLE_RECOVERY, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
+ {TAG_SHELL, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
// Structure used to hold boot loader filenames and time stamps in
// a linked list; used to sort entries within a directory.
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.3");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.7");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
{
EFI_STATUS Status, ReturnStatus;
EFI_HANDLE ChildImageHandle;
- EFI_LOADED_IMAGE *ChildLoadedImage;
+ EFI_LOADED_IMAGE *ChildLoadedImage = NULL;
+ REFIT_FILE File;
+ VOID *ImageData = NULL;
+ UINTN ImageSize;
+ REFIT_VOLUME *DeviceVolume = NULL;
UINTN DevicePathIndex;
CHAR16 ErrorInfo[256];
CHAR16 *FullLoadOptions = NULL;
+ CHAR16 *loader = NULL;
+ BOOLEAN UseMok = FALSE;
- if (Verbose)
- Print(L"Starting %s\n", ImageTitle);
if (ErrorInStep != NULL)
*ErrorInStep = 0;
- // load the image into memory
- ReturnStatus = Status = EFI_NOT_FOUND; // in case the list is empty
- for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
- ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex], NULL, 0, &ChildImageHandle);
- if (ReturnStatus != EFI_NOT_FOUND) {
- break;
- }
- }
- SPrint(ErrorInfo, 255, L"while loading %s", ImageTitle);
- if (CheckError(Status, ErrorInfo)) {
- if (ErrorInStep != NULL)
- *ErrorInStep = 1;
- goto bailout;
- }
-
// set load options
if (LoadOptions != NULL) {
- ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol, (VOID **) &ChildLoadedImage);
- if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
- if (ErrorInStep != NULL)
- *ErrorInStep = 2;
- goto bailout_unload;
- }
-
if (LoadOptionsPrefix != NULL) {
MergeStrings(&FullLoadOptions, LoadOptionsPrefix, 0);
MergeStrings(&FullLoadOptions, LoadOptions, L' ');
MergeStrings(&FullLoadOptions, LoadOptions, 0);
} // if/else
// NOTE: We also include the terminating null in the length for safety.
- ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
- ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
- if (Verbose)
- Print(L"Using load options '%s'\n", FullLoadOptions);
- }
-
- // close open file handles
- UninitRefitLib();
+ } // if (LoadOptions != NULL)
+ if (Verbose)
+ Print(L"Starting %s\nUsing load options '%s'\n", ImageTitle, FullLoadOptions);
- // turn control over to the image
- // TODO: (optionally) re-enable the EFI watchdog timer!
- ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
- // control returns here when the child image calls Exit()
- SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
+ // load the image into memory (and execute it, in the case of a MOK image).
+ ReturnStatus = Status = EFI_NOT_FOUND; // in case the list is empty
+ for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
+ ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
+ NULL, 0, &ChildImageHandle);
+ // ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
+ // ImageData, ImageSize, &ChildImageHandle);
+ // TODO: Commented-out version above is more efficient if the below FindVolumeAndFilename()
+ // and ReadFile() calls (and surrounding logic) are moved earlier; however, this causes
+ // some computers, including my 32-bit Mac Mini and 64-bit Intel machine, to fail when
+ // launching a Linux kernel, with a "Failed to handle fs_proto" error message from the
+ // kernel. Find out what's causing this and fix it.
+ if (ReturnStatus == EFI_ACCESS_DENIED) {
+ // TODO: I originally had the next few lines a
+ FindVolumeAndFilename(DevicePaths[DevicePathIndex], &DeviceVolume, &loader);
+ if (DeviceVolume != NULL) {
+ Status = ReadFile(DeviceVolume->RootDir, loader, &File, &ImageSize);
+ ImageData = File.Buffer;
+ } else {
+ Status = EFI_NOT_FOUND;
+ Print(L"Error: device volume not found!\n");
+ } // if/else
+ ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions, DeviceVolume);
+ if (ReturnStatus == EFI_SUCCESS) {
+ UseMok = TRUE;
+ } // if
+ }
+ if (ReturnStatus != EFI_NOT_FOUND) {
+ break;
+ }
+ }
+ SPrint(ErrorInfo, 255, L"while loading %s", ImageTitle);
if (CheckError(Status, ErrorInfo)) {
if (ErrorInStep != NULL)
- *ErrorInStep = 3;
+ *ErrorInStep = 1;
+ goto bailout;
}
- // re-open file handles
- ReinitRefitLib();
+ if (!UseMok) {
+ ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol,
+ (VOID **) &ChildLoadedImage);
+ if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
+ if (ErrorInStep != NULL)
+ *ErrorInStep = 2;
+ goto bailout_unload;
+ }
+ }
+
+ if (!UseMok) {
+ ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
+ ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
+ // turn control over to the image
+ // TODO: (optionally) re-enable the EFI watchdog timer!
+
+ // close open file handles
+ UninitRefitLib();
+ ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
+ // control returns here when the child image calls Exit()
+ SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
+ if (CheckError(Status, ErrorInfo)) {
+ if (ErrorInStep != NULL)
+ *ErrorInStep = 3;
+ }
+
+ // re-open file handles
+ ReinitRefitLib();
+ } // if
bailout_unload:
// unload the image, we don't care if it works or not...
- Status = refit_call1_wrapper(BS->UnloadImage, ChildImageHandle);
+ if (!UseMok)
+ Status = refit_call1_wrapper(BS->UnloadImage, ChildImageHandle);
bailout:
MyFreePool(FullLoadOptions);
return ReturnStatus;
if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) {
// check for Mac OS X boot loader
- if (!IsIn(L"System\\Library\\CoreServices", GlobalConfig.DontScan)) {
+ if (!IsIn(L"\\System\\Library\\CoreServices", GlobalConfig.DontScan)) {
StrCpy(FileName, MACOSX_LOADER_PATH);
if (FileExists(Volume->RootDir, FileName)) {
AddLoaderEntry(FileName, L"Mac OS X", Volume);
}
// check for XOM
- StrCpy(FileName, L"System\\Library\\CoreServices\\xom.efi");
+ StrCpy(FileName, L"\\System\\Library\\CoreServices\\xom.efi");
if (FileExists(Volume->RootDir, FileName)) {
AddLoaderEntry(FileName, L"Windows XP (XoM)", Volume);
}
} // if Mac directory not in GlobalConfig.DontScan list
// check for Microsoft boot loader/menu
- StrCpy(FileName, L"EFI\\Microsoft\\Boot\\Bootmgfw.efi");
- if (FileExists(Volume->RootDir, FileName) && !IsIn(L"EFI\\Microsoft\\Boot", GlobalConfig.DontScan)) {
+ StrCpy(FileName, L"\\EFI\\Microsoft\\Boot\\Bootmgfw.efi");
+ if (FileExists(Volume->RootDir, FileName) && !IsIn(L"\\EFI\\Microsoft\\Boot", GlobalConfig.DontScan)) {
AddLoaderEntry(FileName, L"Microsoft EFI boot", Volume);
}
while (DirIterNext(&EfiDirIter, 1, NULL, &EfiDirEntry)) {
if (StriCmp(EfiDirEntry->FileName, L"tools") == 0 || EfiDirEntry->FileName[0] == '.')
continue; // skip this, doesn't contain boot loaders
- SPrint(FileName, 255, L"EFI\\%s", EfiDirEntry->FileName);
+ SPrint(FileName, 255, L"\\EFI\\%s", EfiDirEntry->FileName);
ScanLoaderDir(Volume, FileName, MatchPatterns);
} // while()
Status = DirIterClose(&EfiDirIter);
Entry->me.ShortcutLetter = ShortcutLetter;
Entry->me.Image = Image;
Entry->LoaderPath = (LoaderPath) ? StrDuplicate(LoaderPath) : NULL;
-// Entry->DevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, Entry->LoaderPath);
Entry->DevicePath = FileDevicePath(DeviceHandle, Entry->LoaderPath);
Entry->UseGraphicsMode = UseGraphicsMode;
while ((Directory = FindCommaDelimited(GlobalConfig.DriverDirs, i++)) != NULL) {
CleanUpPathNameSlashes(Directory);
Length = StrLen(Directory);
- if (Length > 0)
+ if (Length > 0) {
NumFound += ScanDriverDir(Directory);
+ } // if
MyFreePool(Directory);
} // while
break;
case TAG_SHELL:
j = 0;
+ MyFreePool(FileName);
while ((FileName = FindCommaDelimited(SHELL_NAMES, j++)) != NULL) {
if (FileExists(SelfRootDir, FileName)) {
- AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL), 'S', FALSE);
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL),
+ 'S', FALSE);
}
} // while
break;
}
} // for
break;
+ case TAG_MOK_TOOL:
+ j = 0;
+ MyFreePool(FileName);
+ while ((FileName = FindCommaDelimited(MOK_NAMES, j++)) != NULL) {
+ if (FileExists(SelfRootDir, FileName)) {
+ SPrint(Description, 255, L"MOK Key Manager at %s", FileName);
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, Description,
+ BuiltinIcon(BUILTIN_ICON_TOOL_MOK_TOOL), 'S', FALSE);
+ }
+ } // while
+ if (FileExists(SelfDir, L"MokManager.efi")) {
+ MyFreePool(FileName);
+ FileName = StrDuplicate(SelfDirPath);
+ MergeStrings(&FileName, L"\\MokManager.efi", 0);
+ SPrint(Description, 255, L"MOK Key Manager at %s", FileName);
+ AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, Description,
+ BuiltinIcon(BUILTIN_ICON_TOOL_MOK_TOOL), 'S', FALSE);
+ }
+ break;
} // switch()
MyFreePool(FileName);
FileName = NULL;
MainMenu.EntryCount = 0;
ReadConfig();
ConnectAllDriversToAllControllers();
+ ScanVolumes();
ScanForBootloaders();
ScanForTools();
SetupScreen();
// further bootstrap (now with config available)
SetupScreen();
+ ScanVolumes();
LoadDrivers();
ScanForBootloaders();
ScanForTools();
static BOOLEAN EditOptions(LOADER_ENTRY *MenuEntry) {
UINTN x_max, y_max;
CHAR16 *EditedOptions;
- CHAR16 message[] = L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options";
+// CHAR16 message[] = L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options";
EG_PIXEL DarkBackgroundPixel = { 0x0, 0x0, 0x0, 0 };
BOOLEAN retval = FALSE;
egClearScreen(&DarkBackgroundPixel);
refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, y_max - 1);
- refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, message);
+// refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, message);
+ refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut,
+ L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options");
if (line_edit(MenuEntry->LoadOptions, &EditedOptions, x_max, 1)) {
MyFreePool(MenuEntry->LoadOptions);