From rEFIt to rEFInd ==================== rEFInd is derived from rEFIt (http://refit.sourceforge.net), but the two programs support different build environments. rEFIt was created with Intel's EFI Application Toolkit (http://www.intel.com/technology/efi/toolkit_overview.htm) or TianoCore's EFI Toolkit (https://efi-toolkit.tianocore.org), along with Microsoft's Visual C compiler. Compiling the source code provided on the rEFIt site under Linux never worked for me, although the documentation claimed it would. Apparently other Linux developers have run into the same problem; Debian provides a rEFIt package (http://packages.debian.org/sid/refit) that includes extensive patches to enable the program to compile under Linux using the GNU-EFI package (http://sourceforge.net/projects/gnu-efi/). Although GNU-EFI is less sophisticated than recent versions of TianoCore's toolkit, GNU-EFI is my preferred environment because versions of TianoCore that can build under Linux use a very different set of include files and support a somewhat different set of system calls than are used by rEFIt/rEFInd. Thus, converting to a new TianoCore toolkit would entail a lot of work. Using an older version would require building under Windows and using old versions of Microsoft's Visual C. I neither have this toolchain nor do I want to use it. For this reason, I used Debian's patched version of rEFIt as a starting point in forking rEFInd. Note that the drivers, added with rEFInd 0.4.0, require use of the TianoCore tool kit. Driver compilation is described in more detail later. I've dropped ancillary programs, such as the gptsync program, from rEFInd. You can still use these tools with rEFInd, but you'll need to install them separately. The patched version of rEFIt that I used as a starting point disabled the program's ability to load EFI drivers because of limitations in the GNU-EFI library. A combination of improvements in recent versions of the library and implementing a (now apparently abandoned) EFI function directly in rEFInd has enabled me to add this support back to rEFInd 0.2.7 and later. Requirements ============ To compile rEFInd, you'll need the following: * A Linux installation. Note that this installation does NOT need to be EFI-based. It can be 32- or 64-bit, but unless you use a cross-compiler (which I've not tested), it must be the appropriate bit width for your EFI implementation. (Normally that means 64-bit.) If you don't normally run Linux, you can run it in a VirtualBox or similar virtual machine. * A standard set of Linux development tools, based on GCC. * The GNU-EFI package (http://sourceforge.net/projects/gnu-efi/). You can install this from a package called "gnu-efi"; however, rEFInd relies on features that were added in (I think) 3.0l to provide driver-loading capabilities. The versions I've used and that work are 3.0p and 3.0q. As of 5/2012, most Linux distributions seem to deliver rather elderly versions of GNU-EFI, so you may need to download the latest source code, compile it, and install it locally. Since rEFInd version 0.2.7, the Makefiles assume this (see below). It's possible that you could use a non-Linux platform to compile rEFInd. To the best of my knowledge, the rEFInd code doesn't rely on anything Linux-specific in its build requirements, and GNU-EFI's Sourceforge page indicates that it works under Windows and OS X, too. Thus, you may be able to compile it on these platforms, but I've not tested it in this way. Under Windows, you would need to either create a project or Makefile for your non-GCC compiler or use a GCC port, such as MinGW (http://www.mingw.org). You'd probably need to adjust the Makefile in the latter case. Compiling rEFInd ================ With your development system set up, you can compile rEFInd as follows: 1) Download and uncompress the rEFInd source code archive. (If you're reading this file, you've probably already done this task.) 2) Open a Linux shell prompt 3) Change into the archive's main directory. You should see several files including this BUILDING.txt file and several subdirectories such as "refind", "libeg", and "include". 4) Type "make". With any luck, rEFInd will compile without error, leaving the "refind_ia32.efi" or "refind_x64.efi" file, depending on your platform, in the "refind" subdirectory. If rEFInd doesn't compile correctly, you'll need to track down the source of the problem. Double-check that you've got all the necessary development tools installed, including GCC, make, and GNU-EFI. You may also need to adjust the Makefile or Make.common file for your system. The most likely thing you'll need to change is the path to the various GNU-EFI include files and libraries. Since rEFInd 0.2.7, the default Make.common file includes the following definitions: EFIINC = /usr/local/include/efi GNUEFILIB = /usr/local/lib EFILIB = /usr/local/lib EFICRT0 = /usr/local/lib If you've installed GNU-EFI from a distribution's package, you may need to remove "local" from those paths, and perhaps change references to "lib" to "lib64". As noted earlier, though, as of 5/2012, most distributions provide out-of-date GNU-EFI implementations that will not work with rEFInd 0.2.7 and later. When I tried to compile rEFInd under Ubuntu 12.04 (i386), even with a locally-compiled GNU-EFI 3.0p or 3.0q, I got errors like this: main.o: In function `StartLegacy.isra.0': main.c:(.text+0x8b1): undefined reference to `__stack_chk_fail_local' lib.o: In function `ScanVolumeBootcode.part.3': lib.c:(.text+0xf2f): undefined reference to `__stack_chk_fail_local' lib.o: In function `ScanExtendedPartition.isra.4': The solution was to recompile GNU-EFI with the -fno-stack-protector GCC flag. In GNU-EFI, this can be added to the CFLAGS line in Make.defaults. Installing rEFInd ================= With rEFInd compiled, you can install it. The easiest way to do this is with the install.sh script, which works on both Linux and Mac OS X. Alternatively, you can type "make install" to install using this script. Note that this installation copies files to the ESP and uses "efibootmgr" (on Linux) or "bless" (on OS X) to add rEFInd to the firmware's boot loader list. The docs/refind/installing.html file provides more details on this script and its use. If install.sh doesn't work for you or if you prefer to do the job manually, you may. On a UEFI-based system, you'll want to copy files on the ESP as follows: * Create a directory for rEFInd, such as EFI/refind. * Copy refind/refind_ia32.efi or refind_x64.efi to the ESP's EFI/refind directory. * Copy refind.conf-sample to the EFI/refind directory as refind.conf. * Copy the icons subdirectory, including all its files, to EFI/refind. You'll then need to activate rEFInd in your EFI. This can be done with tools such as "efibootmgr" under Linux or "bless" under OS X. See the docs/refind/installing.html file for details. Note to Distribution Maintainers ================================ The install.sh script, and therefore the "install" target in the Makefile, installs the program directly to the ESP and it modifies the *CURRENT COMPUTER's* NVRAM. Thus, you should *NOT* use this target as part of the build process for your binary packages (RPMs, Debian packages, etc.). (Gentoo could use it in an ebuild, though....) You COULD, however, copy the files to a directory somewhere (/usr/share/refind or whatever) and then call install.sh as part of the binary package installation process. Placing the files in /boot/efi/EFI/{distname}/refind and then having a post-install script call efibootmgr is probably the better way to go, though. Compiling the EFI Filesystem Drivers ==================================== The EFI filesystem drivers in the filesystems subdirectory require the TianoCore UDK2010.SR1 toolkit. The drivers might compile with another version of the TianoCore toolkit, but I've not tested them with anything else. (My attempts to use GNU-EFI have failed; at best, I've gotten drivers that load but hang the system.) Unfortunately, the TianoCore toolkit is bulky and weird by Linux programming standards. I don't know of any Linux distribution packages for it in RPM, Debian package file, or other format; you MUST install the kit from source code using its own unusual compilation procedure. The installation documentation also omits a few steps. Here's how I installed the toolkit: 1) Download UDK2010.SR1 from https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=UDK2010. 2) Type "mkdir /usr/local/UDK2010". You can use another directory, but the Makefile for rEFInd's EFI drivers assumes this location. You'll need to edit the EDK2BASE line in the Makefile if you install somewhere else. 3) Type "cd /usr/local/UDK2010". 3) Unzip the downloaded file (UDK2010.SR1.Complete.MyWorkSpace.zip) in the current directory (/usr/local/UDK2010). This creates a handful of files, including a tarball and a couple of .zip files. 4) Type "unzip UDK2010.SR1.MyWorkSpace.zip". This extracts the platform-neutral portion of the development kit. 5) Type "cd MyWorkSpace". 6) Type "tar xvf ../BaseTools\(Unix\)_UDK2010.SR1.tar". This extracts the Linux/Unix-specific portions of the toolkit. 7) Follow the build instructions at https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Using_EDK_II_with_Native_GCC_4.4; however, a few changes are required, as detailed below.... 8) Type ". edksetup.sh BaseTools" (note the leading dot). This sets up some environment variables, so subsequent steps (NOT including compiling the rEFInd EFI drivers) must be typed in the shell you use for this step. 9) Edit Conf/target.txt and change the following: - ACTIVE_PLATFORM = MdeModulePkg/MdeModulePkg.dsc - TARGET = RELEASE (DEBUG might work, but I've not tested it). - TARGET_ARCH = X64 (on x86-64; leave this as IA32 on x86) - TOOL_CHAIN_TAG = GCC45 (or other value depending on your GCC version; type "gcc -v" to learn your GCC version number) The Makefile for the drivers reads some of these variables from this file and uses them when accessing directories, so be sure to type these entries in the case specified. 11) Type "make -C /usr/local/UDK2010/MyWorkSpace/BaseTools/Source/C". (This step is not documented on the EDK Web page.) 10) Type "build" to build the main set of EDK2 files. This process is likely to take a few minutes. Once the toolkit is installed, you can build the filesystem drivers. If you installed in a location other than the one I've specified, you must edit the Makefile's EDK2BASE variable. You can then type "make" to build all the drivers, or specify a filesystem type to build just it. The drivers all rely on filesystem wrapper code created by rEFIt's author, Christoph Phisterer. Most of the drivers seem to have passed through Oracle's VirtualBox project ((https://www.virtualbox.org) and the Clover boot loader project (https://sourceforge.net/projects/cloverefiboot/). Most of the drivers are based on code from the Linux kernel.