From: srs5694 Date: Mon, 3 Dec 2012 01:17:23 +0000 (-0500) Subject: Version supports Secure Boot/MOK verification of binaries. X-Git-Url: https://code.delx.au/refind/commitdiff_plain/e0f6b77e5692ec112bb803202ae27f8c5d55de50 Version supports Secure Boot/MOK verification of binaries. --- diff --git a/CREDITS.txt b/CREDITS.txt index b4b157b..d8efcde 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -31,6 +31,9 @@ I've incorporated into the current version. Specifically: 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/) diff --git a/EfiLib/GenericBdsLib.h b/EfiLib/GenericBdsLib.h index e0e6af5..b4c9225 100644 --- a/EfiLib/GenericBdsLib.h +++ b/EfiLib/GenericBdsLib.h @@ -222,22 +222,22 @@ BdsLibBuildOptionFromShell ( IN OUT LIST_ENTRY *BdsBootOptionList ); -// -// Bds misc lib functions -// -/** - Get boot mode by looking up the configuration table and parsing the HOB list. - - @param BootMode The boot mode from PEI handoff HOB. - - @retval EFI_SUCCESS Successfully got boot mode. - -**/ -EFI_STATUS -EFIAPI -BdsLibGetBootMode ( - OUT EFI_BOOT_MODE *BootMode - ); +// // +// // Bds misc lib functions +// // +// /** +// Get boot mode by looking up the configuration table and parsing the HOB list. +// +// @param BootMode The boot mode from PEI handoff HOB. +// +// @retval EFI_SUCCESS Successfully got boot mode. +// +// **/ +// EFI_STATUS +// EFIAPI +// BdsLibGetBootMode ( +// OUT EFI_BOOT_MODE *BootMode +// ); /** diff --git a/EfiLib/Platform.h b/EfiLib/Platform.h index 2d89822..001a249 100644 --- a/EfiLib/Platform.h +++ b/EfiLib/Platform.h @@ -45,7 +45,7 @@ Headers collection for procedures //#include //#include -#include "lib.h" +//#include "lib.h" //#include "boot.h" //#include "BiosVideo.h" #include "../include/Bmp.h" diff --git a/Make.tiano b/Make.tiano index 03f189e..c02e7ff 100644 --- a/Make.tiano +++ b/Make.tiano @@ -36,6 +36,7 @@ include $(EDK2BASE)/Conf/target.txt 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) \ diff --git a/Makefile b/Makefile index 5cbc948..a742dc9 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ 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) diff --git a/NEWS.txt b/NEWS.txt index 00449be..c721998 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,19 @@ 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. diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index 7240cbc..e12dbc0 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -170,8 +170,8 @@ timeout 20 showtools - shell, gptsync, about, apple_recovery, exit, shutdown, and reboot - Specifies which tool tags to display on the second row. shell launches an EFI shell, gptsync launches a tool that creates a hybrid MBR, about displays information about the program, apple_recovery boots the OS X Recovery HD, exit terminates rEFInd, shutdown shuts down the computer (or reboots it, on UEFI PCs), and reboot reboots the computer. The tags appear in the order in which you specify them. The default is shell, about, apple_recovery, shutdown, reboot. Note that the shell, apple_recovery, and gptsync options all require the presence of programs not included with rEFInd. See the "Installing Additional Components" section of the Installing rEFInd page for pointers to the shell and gptsync programs. The apple_recovery option will appear only if you've got an Apple Recovery HD partition (which has a boot loader called com.apple.recovery.boot/boot.efi). + shell, gptsync, apple_recovery, mok_tool, about, exit, shutdown, and reboot + Specifies which tool tags to display on the second row. shell launches an EFI shell, gptsync launches a tool that creates a hybrid MBR, apple_recovery boots the OS X Recovery HD, mok_tool launches a tool to manage Machine Owner Keys (MOKs) on systems with Secure Boot active, about displays information about the program, exit terminates rEFInd, shutdown shuts down the computer (or reboots it, on UEFI PCs), and reboot reboots the computer. The tags appear in the order in which you specify them. The default is shell, apple_recovery, mok_tool, about, shutdown, reboot. Note that the shell, apple_recovery, mok_tool, and gptsync options all require the presence of programs not included with rEFInd. See the "Installing Additional Components" section of the Installing rEFInd page for pointers to the shell and gptsync programs. The apple_recovery option will appear only if you've got an Apple Recovery HD partition (which has a boot loader called com.apple.recovery.boot/boot.efi). See the Secure Boot page for information on Secure Boot and MOK management. textonly diff --git a/docs/refind/drivers.html b/docs/refind/drivers.html index dc33d56..132d9d3 100644 --- a/docs/refind/drivers.html +++ b/docs/refind/drivers.html @@ -15,7 +15,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

Originally written: 4/19/2012; last Web page update: -11/6/2012, referencing rEFInd 0.4.7

+11/15/2012, referencing rEFInd 0.4.7

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!

@@ -160,7 +160,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

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 "Notes on Specific Drivers;" however, these problems are very minor on most systems.

- +

If you want to use one or more of these drivers, you can install them from the rEFInd binary package from the refind/drivers_arch directory, where arch is a CPU architecture code—x64 or ia32. The files are named after the filesystems they handle, such as ext2_x64.efi for the 64-bit ext2fs driver. You should copy the files for the filesystems you want to use to the drivers or drivers_arch 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.

@@ -173,7 +173,7 @@ fs0: load reiserfs_x64.efi fs0: map -r -

If you build rEFInd from source, you should be aware that the drivers rely on TianoCore's development kit, whereas rEFInd itself uses GNU-EFI. 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 BUILDING.txt 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 Getting rEFInd page for details) or use drivers from another source.

+

If you build rEFInd from source, you should be aware that the drivers rely on TianoCore's development kit, whereas rEFInd itself can use either TianoCore's kit or GNU-EFI. 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 BUILDING.txt 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 Getting rEFInd page for details) or use drivers from another source.

Finding Additional EFI Drivers

@@ -181,7 +181,7 @@ fs0: map -r
    -
  • rEFIt's ext2fs and ReiserFS drivers—You can gain read-only access to ext2fs, ext3fs, and ReiserFS volumes with these drivers. You can use the binaries in the refit-bin-0.14/efi/tools/drivers 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 thin program for this job.
  • +
  • rEFIt's ext2fs and ReiserFS drivers—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 refit-bin-0.14/efi/tools/drivers 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 thin program for this job.
  • Clover EFI's ISO-9660, ext2fs, and HFS+ drivers—This project is an offshoot of TianoCore, the main UEFI project. It's primarily a Hackintosh boot loader, but it includes drivers for ISO-9660, ext2fs, and HFS+; however, building them requires a fair amount of expertise. These drivers served as a starting point for rEFInd's drivers.
  • @@ -189,6 +189,8 @@ fs0: map -r
  • VirtualBox's HFS+ and ISO-9660 drivers—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 MinGW, 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.
  • +
  • Ext2Pkg—This driver, based on bitbucket and with a backup on github, 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 git 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.
  • +

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 Unknown. (I fixed that bug for rEFInd's version, and it wasn't present in the original rEFIt drivers.)

@@ -201,9 +203,9 @@ fs0: map -r

Notes on Specific Drivers

-

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 /boot partition; however, if you're willing to use ext3fs or ReiserFS on your root (/) 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.

+

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 /boot partition; however, if you're willing to use ext3fs or ReiserFS on your root (/) 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.

-

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 /boot 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 /etc/fstab entry for a new UUID value, though. As noted earlier, be sure to use notail as an option in /etc/fstab for ReiserFS if you want to read it from EFI.) You can even use HFS+ on a Linux /boot partition, although this makes the most sense on a Mac, which has its own EFI HFS+ driver.

+

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 /boot 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 /etc/fstab entry for a new UUID value, though. As noted earlier, be sure to use notail as an option in /etc/fstab for ReiserFS if you want to read it from EFI.) You can even use HFS+ on a Linux /boot 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 /boot partition and not deal with drivers at all. Mounting your ESP at /boot is a practical solution for many users.

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.

diff --git a/docs/refind/getting.html b/docs/refind/getting.html index d5d5ad4..811ebf5 100644 --- a/docs/refind/getting.html +++ b/docs/refind/getting.html @@ -166,9 +166,39 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

Getting rEFInd from Your OS's Repositories

-

If you use Arch Linux, you can obtain rEFInd from its repositories, in both stable and git (experimental) releases. The git release is likely to include pre-release bug fixes and new features, but those features may be poorly tested or undocumented.

+

I know of a small number of pre-packaged versions of rEFInd, either in official OS repositories or in ancillary repositories:

-

You can also obtain rEFInd from the Nix Packages collection, which creates packages for a number of OSes using its own packaging system.

+
    + +
  • Arch Linux—You can obtain rEFInd from the Arch + repositories, in both stable + and git + (experimental) 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.
  • + +
  • The Nix Packages + collection—This site creates packages for a number of + OSes using its own packaging system.
  • + +
  • OpenSUSE + Build Service (OBS)—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 /usr/share/refind directory, and a copy of + install.sh as /usr/sbin/refind_install. + 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 .zip file from Sourceforge + instead.
  • + +

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 drop me a line.

diff --git a/docs/refind/index.html b/docs/refind/index.html index acee878..c8ed71d 100644 --- a/docs/refind/index.html +++ b/docs/refind/index.html @@ -124,6 +124,8 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

  • Options for Booting Linux—Methods of booting Linux, particularly with the EFI stub loader (distribution maintainers should read this!)
  • +
  • Managing Secure Boot—Some pointers on using rEFInd on a computer with Secure Boot active
  • +
  • Revisions—Information on the history of rEFInd releases
  • The Future of rEFInd—Current bugs that need squashing and features that I hope to one day add
  • diff --git a/docs/refind/installing.html b/docs/refind/installing.html index 42fbe8a..0a2f848 100644 --- a/docs/refind/installing.html +++ b/docs/refind/installing.html @@ -15,7 +15,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

    Originally written: 3/14/2012; last Web page update: -11/7/2012, referencing rEFInd 0.4.7

    +11/15/2012, referencing rEFInd 0.4.7

    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!

    @@ -257,10 +257,10 @@ Filesystem 1K-blocks Used Available Use% Mounted on
  • Rename the configuration file by typing mv refind.conf-sample refind.conf. Consult the Editing the rEFInd Configuration File page for information on how to adjust your options.
  • - + -
  • On a UEFI-based system, type efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd 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.
  • +
  • On a UEFI-based system, type efibootmgr -c -l \\EFI\\refind\\refind_x64.efi -L rEFInd 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 /dev/sda1 or if your configuration is otherwise unusual; consult the efibootmgr man page for details. You may need to install this program on some systems; it's a standard part of most distributions' repositories.
  • If other boot loaders are already installed, you can use efibootmgr to adjust their boot order. For instance, efibootmgr -o 3,7,2 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.
  • @@ -372,6 +372,8 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

    Installing rEFInd Manually Using Windows

    + +

    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:

      @@ -434,8 +436,6 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

      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.

      -

      If your computer seems to insist on booting an EFI boot loader called EFI/Microsoft/BOOT/bootmgfw.efi, be aware that it might not actually be looking for that filename, but for a boot manager with the EFI description Microsoft Boot Manager. Changing the description of the "real" EFI/Microsoft/BOOT/bootmgfw.efi using efibootmgr 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.

      -

      Upgrading rEFInd

      @@ -534,6 +534,47 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi
    + +

    Uninstalling rEFInd

    +
    + +

    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 root, should do the trick:

    + +
    +# rm -r /boot/efi/EFI/refind
    +
    + +

    This example assumes that your ESP is mounted at /boot/efi and that rEFInd is installed in EFI/refind on that partition. If you've mounted your ESP elsewhere, or installed rEFInd elsewhere, you should adjust the command appropriately.

    + +

    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 sudo to acquire root privileges. Thus, you'd probably use a command like the following in OS X:

    + +
    +$ sudo rm -r /EFI/refind
    +
    + +

    Many variants of both of these commands are possible on both OS X and Linux. For instance, you'd probably use sudo 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 rm command.

    + +

    From Windows, you must reverse the directions for installing in Windows—type mountvol S: /S to mount your ESP as S:, then navigate to the S:\EFI directory and delete the refind subdirectory.

    + +

    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 efibootmgr utility in Linux:

    + +
    +# efibootmgr --verbose
    +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     .
    +# efibootmgr --delete-bootnum --bootnum 0000
    +Timeout: 10 seconds
    +BootOrder: 0007
    +Boot0007* CD/DVD Drive
    + + + +

    This example shows use of efibootmgr's --verbose (-v) option to display boot loaders so as to identify which one is rEFInd, followed by --delete-bootnum (-B) to delete a boot program and --bootnum (-b) 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 BootOrder 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 --bootorder (-o) option; consult efibootmgr's man page for details.

    + +

    If you're not using Linux, you may be able to find a utility that serves a similar function. The OS X bless 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 bcdedit command, described in the section on installing rEFInd under Windows, may work, although I've not attempted this.

    +

    copyright © 2012 by Roderick W. Smith

    diff --git a/docs/refind/linux.html b/docs/refind/linux.html index 18d4c1a..0229af0 100644 --- a/docs/refind/linux.html +++ b/docs/refind/linux.html @@ -246,7 +246,7 @@ total 17943

    Go to the main rEFInd page

    -

    Learn about rEFInd's history

    +

    Learn how to manage Secure Boot

    Return to my main Web page.

    diff --git a/include/refit_call_wrapper.h b/include/refit_call_wrapper.h index 49b0b7f..68cd8a5 100644 --- a/include/refit_call_wrapper.h +++ b/include/refit_call_wrapper.h @@ -58,6 +58,9 @@ #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__ */ diff --git a/refind.conf-sample b/refind.conf-sample index 0a89036..f9720b8 100644 --- a/refind.conf-sample +++ b/refind.conf-sample @@ -91,13 +91,15 @@ timeout 20 # 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 @@ -285,3 +287,16 @@ menuentry "Windows via shell script" { 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 +} diff --git a/refind.inf b/refind.inf index 5df54c2..fce0853 100644 --- a/refind.inf +++ b/refind.inf @@ -40,6 +40,7 @@ refind/menu.c refind/screen.c refind/driver_support.c + refind/mok.c libeg/image.c libeg/load_bmp.c libeg/load_icns.c @@ -48,7 +49,7 @@ [Packages] MdePkg/MdePkg.dec -# MdeModulePkg/MdeModulePkg.dec + MdeModulePkg/MdeModulePkg.dec IntelFrameworkPkg/IntelFrameworkPkg.dec IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec @@ -66,6 +67,7 @@ HobLib MemoryAllocationLib IoLib + PerformanceLib [Guids] gEfiAcpiTableGuid @@ -133,6 +135,10 @@ gEfiLegacyBiosProtocolGuid # PROTOCOL TO_START + gEfiLoadFile2ProtocolGuid + gEfiLoadFileProtocolGuid + gEfiHiiPackageListProtocolGuid + [FeaturePcd] gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport diff --git a/refind/AutoGen.c b/refind/AutoGen.c index 6f83c03..6423efc 100644 --- a/refind/AutoGen.c +++ b/refind/AutoGen.c @@ -60,7 +60,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiPciIoProtocolGuid = { 0x4CF5B200, 0x6 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 }}; @@ -71,103 +71,84 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiHiiProtocolGuid = { 0xd7ad636e, 0xb99 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 @@ -206,57 +187,57 @@ HobLibConstructor ( ); -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 @@ -270,13 +251,37 @@ ExitDriver ( 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; -} diff --git a/refind/Make.tiano b/refind/Make.tiano index fa4ad1d..4d5fd91 100644 --- a/refind/Make.tiano +++ b/refind/Make.tiano @@ -26,9 +26,15 @@ ALL_EFILIBS = $(EFILIB)/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevel $(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) diff --git a/refind/Makefile b/refind/Makefile index 970c0ab..eb98140 100644 --- a/refind/Makefile +++ b/refind/Makefile @@ -26,7 +26,7 @@ LOCAL_CPPFLAGS = -I$(SRCDIR) -I$(SRCDIR)/../include -I$(SRCDIR)/../libeg 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) diff --git a/refind/config.c b/refind/config.c index e1b5c46..3919127 100644 --- a/refind/config.c +++ b/refind/config.c @@ -67,19 +67,21 @@ static REFIT_MENU_ENTRY MenuEntryReturn = { L"Return to Main Menu", TAG_RETURN // 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); @@ -89,14 +91,18 @@ static EFI_STATUS ReadFile(IN EFI_FILE_HANDLE BaseDir, CHAR16 *FileName, REFIT_F 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); @@ -126,7 +132,7 @@ static EFI_STATUS ReadFile(IN EFI_FILE_HANDLE BaseDir, CHAR16 *FileName, REFIT_F } // TODO: detect other encodings as they are implemented } - + return EFI_SUCCESS; } @@ -312,10 +318,12 @@ VOID ReadConfig(VOID) 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) @@ -385,6 +393,8 @@ VOID ReadConfig(VOID) 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); } @@ -642,11 +652,11 @@ VOID ScanUserConfigured(VOID) 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; @@ -686,7 +696,7 @@ VOID ScanUserConfigured(VOID) 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; @@ -697,7 +707,7 @@ REFIT_FILE * ReadLinuxOptionsFile(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume 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) diff --git a/refind/config.h b/refind/config.h index 6da2419..a23873c 100644 --- a/refind/config.h +++ b/refind/config.h @@ -74,6 +74,7 @@ typedef struct { #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); diff --git a/refind/global.h b/refind/global.h index 24f33f3..ac9bc7a 100644 --- a/refind/global.h +++ b/refind/global.h @@ -58,18 +58,19 @@ #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 diff --git a/refind/icns.c b/refind/icns.c index a7ec2e6..a9b3f01 100644 --- a/refind/icns.c +++ b/refind/icns.c @@ -59,6 +59,7 @@ BUILTIN_ICON BuiltinIconTable[BUILTIN_ICON_COUNT] = { { 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 }, diff --git a/refind/icns.h b/refind/icns.h index e8945b2..bf8db1f 100644 --- a/refind/icns.h +++ b/refind/icns.h @@ -65,10 +65,11 @@ EG_IMAGE * BuiltinIcon(IN UINTN Id); #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 diff --git a/refind/lib.c b/refind/lib.c index 0dd5439..03d90d5 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -94,7 +94,7 @@ static VOID UninitVolumes(VOID); // // 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 @@ -106,20 +106,23 @@ VOID CleanUpPathNameSlashes(IN OUT CHAR16 *PathName) { 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'\\'; @@ -1086,7 +1089,7 @@ EFI_STATUS DirIterClose(IN OUT REFIT_DIR_ITER *DirIter) } if (DirIter->CloseDirHandle) refit_call1_wrapper(DirIter->DirHandle->Close, DirIter->DirHandle); - return DirIter->LastStatus; + return DirIter->LastStatus; } // @@ -1286,6 +1289,62 @@ CHAR16 *FindPath(IN CHAR16* FullPath) { 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, @@ -1400,3 +1459,20 @@ BOOLEAN EjectMedia(VOID) { 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) diff --git a/refind/lib.h b/refind/lib.h index b67ae7f..1e74ac9 100644 --- a/refind/lib.h +++ b/refind/lib.h @@ -108,6 +108,7 @@ VOID MergeStrings(IN OUT CHAR16 **First, IN CHAR16 *Second, CHAR16 AddChar); 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); @@ -115,4 +116,6 @@ VOID MyFreePool(IN OUT VOID *Pointer); BOOLEAN EjectMedia(VOID); +CHAR16 * GuidAsString(EFI_GUID *GuidData); + #endif \ No newline at end of file diff --git a/refind/main.c b/refind/main.c index df81018..acc37cb 100644 --- a/refind/main.c +++ b/refind/main.c @@ -35,11 +35,11 @@ */ /* * 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" @@ -48,6 +48,7 @@ #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" @@ -60,7 +61,7 @@ // // 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" @@ -72,6 +73,8 @@ #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 @@ -95,7 +98,7 @@ static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, 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. @@ -115,7 +118,7 @@ static VOID AboutrEFInd(VOID) 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"); @@ -163,40 +166,22 @@ static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths, { 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' '); @@ -209,31 +194,82 @@ static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths, 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; @@ -885,22 +921,22 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { 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); } @@ -912,7 +948,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *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); @@ -1468,7 +1504,6 @@ static LOADER_ENTRY * AddToolEntry(EFI_HANDLE DeviceHandle, IN CHAR16 *LoaderPat 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; @@ -1607,8 +1642,9 @@ static VOID LoadDrivers(VOID) 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 @@ -1744,9 +1780,11 @@ static VOID ScanForTools(VOID) { 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; @@ -1770,6 +1808,25 @@ static VOID ScanForTools(VOID) { } } // 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; @@ -1790,6 +1847,7 @@ VOID RescanAll(VOID) { MainMenu.EntryCount = 0; ReadConfig(); ConnectAllDriversToAllControllers(); + ScanVolumes(); ScanForBootloaders(); ScanForTools(); SetupScreen(); @@ -1846,6 +1904,7 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) // further bootstrap (now with config available) SetupScreen(); + ScanVolumes(); LoadDrivers(); ScanForBootloaders(); ScanForTools(); diff --git a/refind/menu.c b/refind/menu.c index 423e8ed..5f76da4 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -923,7 +923,7 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT 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; @@ -935,7 +935,9 @@ static BOOLEAN EditOptions(LOADER_ENTRY *MenuEntry) { 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);