# Build the Symbiote library itself.
all:
- make -C $(LIB_DIR) -j 6
- make -C $(LOADER_DIR) -j 6
+ make -C $(LIB_DIR)
+ make -C $(LOADER_DIR)
clean:
make -C $(LIB_DIR) clean
-0.2.5 (?/??/2012):
-------------------
+0.2.5 (4/9/2012):
+-----------------
+
+- Fixed bug that caused an inability to associate initial RAM disks with
+ Linux kernels stored in a volume's root directory.
+
+- Volume badges (that override default badges) are now stored in
+ .VolumeBadge.icns. Although undocumented, rEFInd formerly loaded custom
+ volume badges from .VolumeIcon.icns. This carryover from rEFIt was a
+ confusing name, given the next (new) feature, so I've changed and
+ documented the name....
+
+- Added ability to set a default icon for a loader stored in the root
+ directory of a volume: The icon is stored in .VolumeIcon.icns. This icon
+ is also used for Mac OS X volumes booted from the standard location.
- Fixed bug that caused icons to drop back to generic icons when rEFInd
was launched in certain ways (such as from an EFI shell in rEFInd's
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+<p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>Another way to hide a boot loader is to move it into rEFInd's own directory. In order to keep rEFInd from showing up in its own menu, it ignores boot loaders in its own directory. This obviously includes the rEFInd binary file itself, but also anything else you might store there.</p>
-<p>In addition to hiding boot loaders, you can adjust their icons. You can do this in either of two ways:</p>
+<p>In addition to hiding boot loaders, you can adjust their icons. You can do this in any of three ways for auto-detected boot loaders:</p>
<ul>
<li>You can name an icon file after your boot loader, but with an extension of <tt>.icns</tt>. For instance, if you're using <tt class="variable">loader</tt><tt>.efi</tt>, you would name the icon file <tt class="variable">loader</tt><tt>.icns</tt>. These icon files should be 128x128 images in <a href="http://en.wikipedia.org/wiki/Apple_Icon_Image_format">Apple's ICNS format.</a> You can create such files easily in OS X or convert PNG files to ICNS format with <a href="http://icns.sourceforge.net/">libicns.</a></li>
+<li>If you're booting OS X from its standard boot loader, or if you place a boot loader file in the root directory of a partition, you can create a file called <tt>.VolumeIcon.icns</tt> that holds an icon file. OS X uses this file for its volume icons, so rEFInd picks up these icons automatically, provided they include 128x128 bitmaps.</li>
+
</ul>
-<p>rEFInd assigns icons to the Windows and OS X boot loaders based on their conventional locations, so they get suitable icons even though they don't follow these rules.</p>
+<p>As a special case, rEFInd assigns icons to the Windows and OS X boot loaders based on their conventional locations, so they get suitable icons even though they don't follow these rules.</p>
+
+<p>In addition to the main OS tag icon, you can set the <i>badge</i> icon for a volume by creating a file called <tt>.VolumeBadge.icns</tt> in the root directory of a partition. This icon file must include a 32x32 bitmap. If present, it replaces the disk-type icons that are overlaid on the main OS icon. If you use this feature, the badge is applied to all the boot loaders read from the disk, not just those stored in the root directory or the Apple boot loader location. You could use this feature to set a custom badge for different specific disks or to help differentiate multiple OS X installations on one computer.</p>
<h2>Adjusting the Global Configuration</h2>
<body>
<h1>The rEFInd Boot Manager:<br />rEFInd Features</h1>
- <p class="subhead">by Roderick W. Smith, <a
+<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
-
+<p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>Launch EFI boot loaders or, on Macs, launch BIOS-based boot loaders. (I have yet to get the BIOS-launching feature to work on a UEFI-based PC, but it might work on a model I don't own.)</li>
-<li>Launch options for an EFI shell, disk partitioner, and other optional external components. (See the <a href="installing.html">Installing rEFInd</a> section for information on how to obtain and install these components.)</li>
+<li>Launch options for an external EFI shell or disk partitioner. (See the <a href="installing.html">Installing rEFInd</a> section for information on how to obtain and install these components.)</li>
<li>Set OS-specific boot options, such as to launch Mac OS X with verbose text-mode debug messages.</li>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
-<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.4/refind-src-0.2.4.zip/download">A
+<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.5/refind-src-0.2.5.zip/download">A
source code zip file</a></b>—This is useful if you want to
compile the software locally. Note that I use Linux with the <a
href="http://sourceforge.net/projects/gnu-efi">GNU-EFI</a> development
that toolchain is theoretically possible, but I've not attempted
it.</li>
-<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.4/refind-bin-0.2.4.zip/download">A
+<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.5/refind-bin-0.2.5.zip/download">A
binary zip file</a></b>—Download this if you want to install rEFInd on
an <i>x</i>86 or <i>x</i>86-64 computer and have no need to test rEFInd
first by booting it on an optical disc. This zip file package includes both
versions of rEFInd. Which you install depends on your architecture, as
described on the <a href="installing.html">Installing rEFInd</a> page.</li>
-<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.4/refind-cd-0.2.4.zip/download">A
+<li><b><a href="http://sourceforge.net/projects/refind/files/0.2.5/refind-cd-0.2.5.zip/download">A
CD-R image file</a></b>—This download contains the same files as the
zip file, but you can burn it to a CD-R to test rEFInd without installing it
first. (It boots on UEFI PCs, but fails on at least some Macs.) If you like
<p>If you download a zip file, you'll need to extract the files with a tool such as <tt>unzip</tt>, which is included with Linux and Mac OS X. Numerous Windows utilities also support this format, such as <a href="http://www.pkware.com/software/pkzip/">PKZIP</a> and <a href="http://www.7-zip.org/">7-Zip.</a></p>
+<p>You should be able to create a bootable USB flash drive from either the binary zip file or the CD-R image file; just treat the flash drive as if it were a hard disk and install rEFInd as described on the <a href="installing.html">installation page.</a> Using the fallback boot loader name of <tt>EFI/boot/bootx64.efi</tt> is likely to be the most useful way to install rEFInd to a removable medium.</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://aur.archlinux.org/packages.php?ID=57632">stable</a> and <a href="https://aur.archlinux.org/packages.php?ID=57966">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>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>
+
<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>
<hr />
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>
protective MBR. You can obtain the file from the <a
href="http://refit.sourceforge.net">original rEFIt package.</a></li>
-<li><b>diskpart.efi</b>—This is a disk partitioning utility that's
- similar to one of the same name in Microsoft Windows. You can obtain it
- from <a
- href="http://www.intel.com/technology/efi/agree_diskutil.htm">Intel's
- site</a> as part of a package with a few other tools. Place it in the
- <tt>efi/tools</tt> subdirectory of the ESP and rEFInd will detect it
- and give you the option to use it.</li>
-
</ul>
<p>I've seen links to other versions of these tools from time to time on the Web, so if you try one of these programs and it crashes or behaves strangely, try performing a Web search; you may turn up something that works better for you than the one to which I've linked.</p>
</head>
<body>
- <h1>The rEFInd Boot Manager:<br />Methods of Booting Linux</h1>
+<h1>The rEFInd Boot Manager:<br />Methods of Booting Linux</h1>
- <p class="subhead">by Roderick W. Smith, <a
+<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/19/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+<p>Originally written: 3/19/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>The Linux <a href="http://www.rodsbooks.com/efi-bootloaders/efistub.html">EFI stub loader</a> is a way to turn a Linux kernel into an EFI application. In a sense, the kernel becomes its own boot loader. This approach to booting Linux is very elegant in some ways, but as described on the page to which I just linked, it has its disadvantages, too. One challenge to booting in this way is that modern Linux installations typically require that the kernel be passed a number of options at boot time. These tell the kernel where the Linux root (<tt>/</tt>) filesystem is, where the initial RAM disk is, and so on. Without these options, Linux won't boot. These options are impossible for a generic boot loader to guess without a little help. It's possible to build a kernel with a default set of options, but this is rather limiting. Thus, rEFInd provides configuration options to help.</p>
-<p>With all versions of rEFInd, you can create manual boot loader stanzas in the <tt>refind.conf</tt> file to identify a Linux kernel and to pass it all the options it needs. This approach is effective and flexible, but it requires editing a single configuration file. If a computer boots two different Linux distributions, and if both were to support rEFInd, problems might arise as each one tries to modify its own rEFInd configuration; or the one that controls rEFInd might set inappropriate options for another distribution. This is a problem that's been a minor annoyance for years under BIOS, since the same potential for poor configuration applies to LILO, GRUB Legacy, and GRUB 2 on BIOS. The most reliable solution there is to chainload one boot loader to another. The same solution is possible under EFI, but rEFInd offers another possibility.</p>
+<p>With all versions of rEFInd, you can create manual boot loader stanzas
+in the <tt>refind.conf</tt> file to identify a Linux kernel and to pass it
+all the options it needs. This approach is effective and flexible, but it
+requires editing a single configuration file for all the OSes you want to
+define in this way. If a computer boots two different Linux distributions,
+and if both were to support rEFInd, problems might arise as each one tries
+to modify its own rEFInd configuration; or the one that controls rEFInd
+might set inappropriate options for another distribution. This is a problem
+that's been a minor annoyance for years under BIOS, since the same
+potential for poor configuration applies to LILO, GRUB Legacy, and GRUB 2
+on BIOS. The most reliable solution there is to chainload one boot loader
+to another. The same solution is possible under EFI, but rEFInd offers
+another possibility.</p>
<p>rEFInd 0.2.1 and later supports semi-automatic Linux EFI stub loader detection. This feature works as part of the standard boot loader scan operation, but it extends it as follows:</p>
<ol>
-<li>rEFInd looks for boot loaders whose names include the strings <tt>bzImage</tt> or <tt>vmlinuz</tt> and that end in <tt>.efi</tt>. For instance, <tt>bzImage-3.3.0.efi</tt> or <tt>vmlinuz-3.3.0-fc17.efi</tt> would match, and trigger subsequent steps in this procedure. Note that to use this system, you <i>must</i> give your kernel file a <tt>.efi</tt> extension, at least on the ESP (or other boot loader partition, for Macs)!</li>
+<li>rEFInd looks for boot loaders whose names include the strings <tt>bzImage</tt> or <tt>vmlinuz</tt> and that end in <tt>.efi</tt>. For instance, <tt>bzImage-3.3.0.efi</tt> or <tt>vmlinuz-3.3.0-fc17.efi</tt> would match, and trigger subsequent steps in this procedure. Note that to use this system, you <i>must</i> give your kernel file a <tt>.efi</tt> extension, at least on the ESP (or other boot loader partition)!</li>
<p class="sidebar">A kernel whose filename lacks a version string matches an initial RAM disk that also lacks a version string in its filename. Note that you can reliably use only <i>one</i> kernel and initial RAM disk per directory that lack version numbers in their filenames.</p>
</ul>
+<p class="sidebar"><b>Tip for distribution maintainers:</b> If you maintain an <tt>EFI/<tt class="variable">distname</tt></tt> directory for your kernels, you can place your version of rEFInd in a directory called <tt>EFI/<tt class="variable">distname</tt>/refind</tt>. This will avoid collisions with duplicate rEFInd installations from other distributions.</p>
+
<p>On the whole, this method of configuration has a lot going for it. For distribution maintainers, if you place your Linux kernel files (with EFI stub support) on the ESP, with suitable filenames, matching initial RAM disk files, and a <tt>refind_linux.conf</tt> file, then any rEFInd 0.2.3 or later installation should detect your files, even if the user installs another distribution with another rEFInd that takes over from yours. (If the user, or this other rEFInd installation, disables auto-detection, this won't work.)</p>
<p>For end users, this method is simpler than maintaining manual configurations in <tt>refind.conf</tt> (or equivalents for ELILO or GRUB). To install a new kernel, you need only copy it and its initial RAM disk, under suitable names, to a scanned directory on the ESP. There's no need to touch any configuration file, provided you've already set up <tt>refind_linux.conf</tt> in your kernel's directory. You will, however, have to adjust <tt>refind_linux.conf</tt> if you make certain changes, such as if your root directory identifier changes.</p>
</head>
<body>
- <h1>The rEFInd Boot Manager:<br />Revisions</h1>
+<h1>The rEFInd Boot Manager:<br />Revisions</h1>
- <p class="subhead">by Roderick W. Smith, <a
+<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Last Web page update: 4/5/2012</p>
+<p>Last Web page update: 4/9/2012</p>
<p>I'm a technical writer and consultant specializing in Linux technologies. This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
<ul>
+<li><b>0.2.5 (4/9/2012)</b>—Icon-handling improvements are key in this version. I've fixed a bug that caused icons to be replaced with ugly "not-found" default icons when rEFInd was launched in certain ways. I've also added support for <tt>.VolumeIcon.icns</tt> and <tt>.VolumeBadge.icns</tt> files to set loader tags and disk-type badges, respectively. (See the <a href="configfile.html">configuration page</a> for details.) I've also fixed a bug that prevented rEFInd from finding the correct initial RAM disk for Linux kernels stored in the root directory of a partition.</li>
+
<li><b>0.2.4 (4/5/2012)</b>—This version adds support for a new location for EFI shells (<tt>shell<tt class="variable">arch</tt>.efi</tt> in the ESP's root directory. It also adds two new <tt>refind.conf</tt> options: <tt>showtools</tt> and <tt>max_tags</tt>, and removes another one (<tt>disable</tt>). The options available in <tt>hideui</tt> are now essentially a combination of what <tt>disable</tt> and <tt>hideui</tt> did, minus functionality now present in <tt>showtools</tt>. I made these changes to reduce redundancy and to increase flexibility. See the <a href="configfile.html">Configuring the Boot Manager</a> page for details.</li>
<li><b>0.2.3 (3/26/2012)</b>—I've changed the Linux kernel configuration filename from <tt>linux.conf</tt> to <tt>refind_linux.conf</tt> with this version, to avoid a name collision with a planned future Linux kernel ability to read its options from a file called <tt>linux.conf</tt>. This version also includes a tentative bug fix for a problem that caused rEFInd to hang upon launching the second program (say, a boot loader after using a shell) on some systems; but on some computers, this fix causes an (apparently harmless) error message about "(re)opening our installation volume" upon returning from the first program. I've also added a logo for Arch Linux.</li>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>
<hr />
-<p>rEFInd is far from perfect. It's based on rEFIt, which has an <a href="https://sourceforge.net/tracker/?group_id=161917&atid=821764">list of active bugs</a> on its project page on Sourceforge. I have not studied this bug list in detail for rEFInd's first release, although I've probably fixed a few of those bugs because I encountered them myself. Other bugs I may never fix because I lack the necessary hardware for testing.</p>
+<p>rEFInd is far from perfect. It's based on rEFIt, which has a <a href="https://sourceforge.net/tracker/?group_id=161917&atid=821764">list of active bugs</a> on its project page on Sourceforge. I have not studied this bug list in detail for rEFInd's first release, although I've probably fixed a few of those bugs because I encountered them myself. Other bugs I may never fix because I lack the necessary hardware for testing.</p>
<p>This page exists to document some of rEFInd's known bugs and limitations, as well as features I hope to add in the future. Some of the items on this list are things that you may be able to help with, so if you'd like to contribute, feel free to drop me a line!</p>
<li>The code could be more flexible in its handling of the sizes of various graphical elements, and particularly drawn text. Prior to version 0.2.2, submenu text was invisible on UEFI-based PCs with 800x600 and smaller displays because of an inability to properly crop the graphics fields that hold the text. With version 0.2.2, I've put a band-aid on this problem by reducing the field size so that it now works on 800x600 displays, but smaller displays still suffer from this problem. This is just an example of the inflexibility of certain layout issues within rEFInd.</li>
+<li>Although the ICNS file format used by rEFInd supports multiple image sizes, if a size that rEFInd needs isn't present in the file, rEFInd can't use the icon. The ability to scale images to the desired size would be useful.</li>
+
<li>I want to be able to specify the volume on which a boot loader resides in <tt>refind.conf</tt>. (As it is, manually-defined options can only launch boot loader files on the same volume as rEFInd.)</li>
<li>It would be useful to be able to specify paths to boot loaders and/or initial RAM disks relative to the rEFInd directory (or the boot loader's directory, in the case of initrds).</li>
<p class="subhead">by Roderick W. Smith, <a
href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
- <p>Originally written: 3/14/2012; last Web page update: 4/5/2012, referencing rEFInd 0.2.4</p>
+ <p>Originally written: 3/14/2012; last Web page update: 4/9/2012, referencing rEFInd 0.2.5</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>
EG_IMAGE * egCopyImage(IN EG_IMAGE *Image)
{
EG_IMAGE *NewImage;
-
+
NewImage = egCreateImage(Image->Width, Image->Height, Image->HasAlpha);
if (NewImage == NULL)
return NULL;
-
+
CopyMem(NewImage->PixelData, Image->PixelData, Image->Width * Image->Height * sizeof(EG_PIXEL));
return NewImage;
}
} else if ((StriCmp(Format, L"ICNS") == 0) || (StriCmp(Format, L"icns") == 0)) {
NewImage = egDecodeICNS(FileData, FileDataLength, IconSize, WantAlpha);
} // if/else
-
+
return NewImage;
}
UINT8 *FileData;
UINTN FileDataLength;
EG_IMAGE *NewImage;
-
+
if (BaseDir == NULL || FileName == NULL)
return NULL;
-
+
// load file
Status = egLoadFile(BaseDir, FileName, &FileData, &FileDataLength);
if (EFI_ERROR(Status))
return NULL;
-
+
// decode it
NewImage = egDecodeAny(FileData, FileDataLength, egFindExtension(FileName), 128, WantAlpha);
FreePool(FileData);
-
+
return NewImage;
}
UINT8 *FileData;
UINTN FileDataLength;
EG_IMAGE *NewImage;
-
+
if (BaseDir == NULL || FileName == NULL)
return NULL;
-
+
// load file
Status = egLoadFile(BaseDir, FileName, &FileData, &FileDataLength);
if (EFI_ERROR(Status)) {
// Print(L"In egLoadIcon(), Status = %d after egLoadFile(); aborting load!\n", Status);
return NULL;
}
-
+
// decode it
NewImage = egDecodeAny(FileData, FileDataLength, egFindExtension(FileName), IconSize, TRUE);
// Print(L"Done with egDecodeAny(), used extension '%s'\n", egFindExtension(FileName));
// if (NewImage == NULL)
// Print(L"Returning NULL from egLoadIcon()\n");
FreePool(FileData);
-
+
return NewImage;
}
// not an icns file...
return NULL;
}
-
+
FetchPixelSize = IconSize;
for (;;) {
DataPtr = NULL;
DataLen = 0;
MaskPtr = NULL;
MaskLen = 0;
-
+
Ptr = FileData + 8;
BufferEnd = FileData + FileDataLength;
// iterate over tagged blocks in the file
BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7];
if (Ptr + BlockLen > BufferEnd) // block continues beyond end of file
break;
-
+
// extract the appropriate blocks for each pixel size
if (FetchPixelSize == 128) {
if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') {
MaskPtr = Ptr + 8;
MaskLen = BlockLen - 8;
}
-
+
} else if (FetchPixelSize == 48) {
if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') {
DataPtr = Ptr + 8;
MaskPtr = Ptr + 8;
MaskLen = BlockLen - 8;
}
-
+
} else if (FetchPixelSize == 32) {
if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') {
DataPtr = Ptr + 8;
MaskPtr = Ptr + 8;
MaskLen = BlockLen - 8;
}
-
+
} else if (FetchPixelSize == 16) {
if (Ptr[0] == 'i' && Ptr[1] == 's' && Ptr[2] == '3' && Ptr[3] == '2') {
DataPtr = Ptr + 8;
MaskPtr = Ptr + 8;
MaskLen = BlockLen - 8;
}
-
+
}
-
+
Ptr += BlockLen;
}
-
+
/* FUTURE: try to load a different size and scale it later
if (DataPtr == NULL && FetchPixelSize == 32) {
FetchPixelSize = 128;
*/
break;
}
-
+
if (DataPtr == NULL)
return NULL; // no image found
-
+
// allocate image structure and buffer
NewImage = egCreateImage(FetchPixelSize, FetchPixelSize, WantAlpha);
if (NewImage == NULL)
return NULL;
PixelCount = FetchPixelSize * FetchPixelSize;
-
+
if (DataLen < PixelCount * 3) {
-
+
// pixel data is compressed, RGB planar
CompData = DataPtr;
CompLen = DataLen;
if (CompLen > 0) {
Print(L" egLoadICNSIcon: %d bytes of compressed data left\n", CompLen);
}
-
+
} else {
-
+
// pixel data is uncompressed, RGB interleaved
SrcPtr = DataPtr;
DestPtr = NewImage->PixelData;
DestPtr->g = *SrcPtr++;
DestPtr->b = *SrcPtr++;
}
-
+
}
-
+
// add/set alpha plane
if (MaskPtr != NULL && MaskLen >= PixelCount && WantAlpha)
egInsertPlane(MaskPtr, PLPTR(NewImage, a), PixelCount);
else
egSetPlane(PLPTR(NewImage, a), WantAlpha ? 255 : 0, PixelCount);
-
+
// FUTURE: scale to originally requested size if we had to load another size
-
+
return NewImage;
}
# Create a bootable USB flash drive image, using the FAT filesystem
# created above and a stored partition table image (plus some empty
# sectors)....
+#
+# Note: Seems to work on only a few systems, so I'm not distributing
+# the resulting images yet....
+#
rm ../../refind-flashdrive-$Version.*
cat $StartDir/flashparts.img refind-bin-$Version.img > refind-flashdrive-$Version.img
cp $StartDir/README-flashdrive.txt ./
cd ../
# Zip up the optical disc image....
-rm refind-cd-$Version.zip
+rm -f refind-cd-$Version.zip
zip -9 refind-cd-$Version.zip refind-cd-$Version.iso
-#rm -r temp/
+rm -r temp/
File->End8Ptr = File->Current8Ptr + File->BufferSize;
File->Current16Ptr = (CHAR16 *)File->Buffer;
File->End16Ptr = File->Current16Ptr + (File->BufferSize >> 1);
-
+
// detect encoding
File->Encoding = ENCODING_ISO8859_1; // default: 1:1 translation of CHAR8 to CHAR16
if (File->BufferSize >= 4) {
}
// TODO: detect other encodings as they are implemented
}
-
+
return EFI_SUCCESS;
}
if (*p == 0 || *p == '#')
LineFinished = TRUE;
*p++ = 0;
-
+
AddListElement((VOID ***)TokenList, &TokenCount, (VOID *)StrDuplicate(Token));
}
-
+
FreePool(Line);
}
return (TokenCount);
TokenCount = ReadTokenLine(&File, &TokenList);
if (TokenCount == 0)
break;
-
+
if (StriCmp(TokenList[0], L"timeout") == 0) {
HandleInt(TokenList, TokenCount, &(GlobalConfig.Timeout));
EFI_HANDLE DeviceHandle;
EFI_FILE *RootDir;
CHAR16 *VolName;
+ EG_IMAGE *VolIconImage;
EG_IMAGE *VolBadgeImage;
UINTN DiskKind;
BOOLEAN IsAppleLegacy;
// Maximum size for disk sectors
#define SECTOR_SIZE 4096
+// Default names for volume badges (mini-icon to define disk type) and icons
+#define VOLUME_BADGE_NAME L".VolumeBadge.icns"
+#define VOLUME_ICON_NAME L".VolumeIcon.icns"
+
// functions
static EFI_STATUS FinishInitRefitLib(VOID);
CopyMem(Volume->MbrPartitionTable, MbrTable, 4 * 16);
}
}
-
+
} else {
#if REFIT_DEBUG > 0
CheckError(Status, L"while reading boot sector");
UINTN PartialLength;
EFI_FILE_SYSTEM_INFO *FileSystemInfoPtr;
BOOLEAN Bootable;
-
+
// get device path
Volume->DevicePath = DuplicateDevicePath(DevicePathFromHandle(Volume->DeviceHandle));
#if REFIT_DEBUG > 0
#endif
}
#endif
-
+
Volume->DiskKind = DISK_KIND_INTERNAL; // default
-
+
// get block i/o
Status = refit_call3_wrapper(BS->HandleProtocol, Volume->DeviceHandle, &BlockIoProtocol, (VOID **) &(Volume->BlockIO));
if (EFI_ERROR(Status)) {
if (Volume->BlockIO->Media->BlockSize == 2048)
Volume->DiskKind = DISK_KIND_OPTICAL;
}
-
+
// scan for bootcode and MBR table
Bootable = FALSE;
ScanVolumeBootcode(Volume, &Bootable);
-
+
// detect device type
DevicePath = Volume->DevicePath;
while (DevicePath != NULL && !IsDevicePathEndType(DevicePath)) {
NextDevicePath = NextDevicePathNode(DevicePath);
-
+
if (DevicePathType(DevicePath) == MESSAGING_DEVICE_PATH &&
(DevicePathSubType(DevicePath) == MSG_USB_DP ||
DevicePathSubType(DevicePath) == MSG_USB_CLASS_DP ||
Volume->DiskKind = DISK_KIND_OPTICAL; // El Torito entry -> optical disk
Bootable = TRUE;
}
-
+
if (DevicePathType(DevicePath) == MEDIA_DEVICE_PATH && DevicePathSubType(DevicePath) == MEDIA_VENDOR_DP) {
Volume->IsAppleLegacy = TRUE; // legacy BIOS device entry
// TODO: also check for Boot Camp GUID
Bootable = FALSE; // this handle's BlockIO is just an alias for the whole device
}
-
+
if (DevicePathType(DevicePath) == MESSAGING_DEVICE_PATH) {
// make a device path for the whole device
PartialLength = (UINT8 *)NextDevicePath - (UINT8 *)(Volume->DevicePath);
DiskDevicePath = (EFI_DEVICE_PATH *)AllocatePool(PartialLength + sizeof(EFI_DEVICE_PATH));
CopyMem(DiskDevicePath, Volume->DevicePath, PartialLength);
CopyMem((UINT8 *)DiskDevicePath + PartialLength, EndDevicePath, sizeof(EFI_DEVICE_PATH));
-
+
// get the handle for that path
RemainingDevicePath = DiskDevicePath;
//Print(L" * looking at %s\n", DevicePathToStr(RemainingDevicePath));
Status = refit_call3_wrapper(BS->LocateDevicePath, &BlockIoProtocol, &RemainingDevicePath, &WholeDiskHandle);
//Print(L" * remaining: %s\n", DevicePathToStr(RemainingDevicePath));
FreePool(DiskDevicePath);
-
+
if (!EFI_ERROR(Status)) {
//Print(L" - original handle: %08x - disk handle: %08x\n", (UINT32)DeviceHandle, (UINT32)WholeDiskHandle);
-
+
// get the device path for later
Status = refit_call3_wrapper(BS->HandleProtocol, WholeDiskHandle, &DevicePathProtocol, (VOID **) &DiskDevicePath);
if (!EFI_ERROR(Status)) {
Volume->WholeDiskDevicePath = DuplicateDevicePath(DiskDevicePath);
}
-
+
// look at the BlockIO protocol
Status = refit_call3_wrapper(BS->HandleProtocol, WholeDiskHandle, &BlockIoProtocol, (VOID **) &Volume->WholeDiskBlockIO);
if (!EFI_ERROR(Status)) {
-
+
// check the media block size
if (Volume->WholeDiskBlockIO->Media->BlockSize == 2048)
Volume->DiskKind = DISK_KIND_OPTICAL;
-
+
} else {
Volume->WholeDiskBlockIO = NULL;
//CheckError(Status, L"from HandleProtocol");
} //else
// CheckError(Status, L"from LocateDevicePath");
}
-
+
DevicePath = NextDevicePath;
} // while
-
+
if (!Bootable) {
#if REFIT_DEBUG > 0
if (Volume->HasBootCode)
#endif
Volume->HasBootCode = FALSE;
}
-
+
// default volume icon based on disk kind
ScanVolumeDefaultIcon(Volume);
-
+
// open the root directory of the volume
Volume->RootDir = LibOpenRoot(Volume->DeviceHandle);
if (Volume->RootDir == NULL) {
return;
}
-
+
// get volume name
FileSystemInfoPtr = LibFileSystemInfo(Volume->RootDir);
if (FileSystemInfoPtr != NULL) {
// - name derived from file system type or partition type
// get custom volume icon if present
- if (FileExists(Volume->RootDir, L".VolumeIcon.icns"))
- Volume->VolBadgeImage = LoadIcns(Volume->RootDir, L".VolumeIcon.icns", 32);
+ if (FileExists(Volume->RootDir, VOLUME_BADGE_NAME))
+ Volume->VolBadgeImage = LoadIcns(Volume->RootDir, VOLUME_BADGE_NAME, 32);
+ if (FileExists(Volume->RootDir, VOLUME_ICON_NAME)) {
+ Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAME, 128);
+ }
}
static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_INFO *MbrEntry)
UINT8 SectorBuffer[512];
BOOLEAN Bootable;
MBR_PARTITION_INFO *EMbrTable;
-
+
ExtBase = MbrEntry->StartLBA;
-
+
for (ExtCurrent = ExtBase; ExtCurrent; ExtCurrent = NextExtCurrent) {
// read current EMBR
Status = refit_call5_wrapper(WholeDiskVolume->BlockIO->ReadBlocks,
if (*((UINT16 *)(SectorBuffer + 510)) != 0xaa55)
break;
EMbrTable = (MBR_PARTITION_INFO *)(SectorBuffer + 446);
-
+
// scan logical partitions in this EMBR
NextExtCurrent = 0;
for (i = 0; i < 4; i++) {
NextExtCurrent = ExtBase + EMbrTable[i].StartLBA;
break;
} else {
-
+
// found a logical partition
Volume = AllocateZeroPool(sizeof(REFIT_VOLUME));
Volume->DiskKind = WholeDiskVolume->DiskKind;
Volume->BlockIO = WholeDiskVolume->BlockIO;
Volume->BlockIOOffset = ExtCurrent + EMbrTable[i].StartLBA;
Volume->WholeDiskBlockIO = WholeDiskVolume->BlockIO;
-
+
Bootable = FALSE;
ScanVolumeBootcode(Volume, &Bootable);
if (!Bootable)
Volume->HasBootCode = FALSE;
-
+
ScanVolumeDefaultIcon(Volume);
-
+
AddListElement((VOID ***) &Volumes, &VolumesCount, Volume);
-
+
}
}
}
if (SelfVolume == NULL)
Print(L"WARNING: SelfVolume not found");
-
+
// second pass: relate partitions and whole disk devices
for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
Volume = Volumes[VolumeIndex];
// check size
if ((UINT64)(MbrTable[PartitionIndex].Size) != Volume->BlockIO->Media->LastBlock + 1)
continue;
-
+
// compare boot sector read through offset vs. directly
Status = refit_call5_wrapper(Volume->BlockIO->ReadBlocks,
Volume->BlockIO, Volume->BlockIO->Media->MediaId,
SectorSum += SectorBuffer1[i];
if (SectorSum < 1000)
continue;
-
+
// TODO: mark entry as non-bootable if it is an extended partition
-
+
// now we're reasonably sure the association is correct...
Volume->IsMbrPartition = TRUE;
Volume->MbrPartitionIndex = PartitionIndex;
Volume->VolName = PoolPrint(L"Partition %d", PartitionIndex + 1);
break;
}
-
+
FreePool(SectorBuffer1);
FreePool(SectorBuffer2);
}
-
+
}
} /* VOID ScanVolumes() */
{
REFIT_VOLUME *Volume;
UINTN VolumeIndex;
-
+
for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
Volume = Volumes[VolumeIndex];
-
+
if (Volume->RootDir != NULL) {
refit_call1_wrapper(Volume->RootDir->Close, Volume->RootDir);
Volume->RootDir = NULL;
}
-
+
Volume->DeviceHandle = NULL;
Volume->BlockIO = NULL;
Volume->WholeDiskBlockIO = NULL;
UINTN VolumeIndex;
EFI_DEVICE_PATH *RemainingDevicePath;
EFI_HANDLE DeviceHandle, WholeDiskHandle;
-
+
for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
Volume = Volumes[VolumeIndex];
-
+
if (Volume->DevicePath != NULL) {
// get the handle for that path
RemainingDevicePath = Volume->DevicePath;
Status = refit_call3_wrapper(BS->LocateDevicePath, &BlockIoProtocol, &RemainingDevicePath, &DeviceHandle);
-
+
if (!EFI_ERROR(Status)) {
Volume->DeviceHandle = DeviceHandle;
VOID *Buffer;
UINTN LastBufferSize, BufferSize;
INTN IterCount;
-
+
for (;;) {
-
+
// free pointer from last call
if (*DirEntry != NULL) {
FreePool(*DirEntry);
*DirEntry = NULL;
}
-
+
// read next directory entry
LastBufferSize = BufferSize = 256;
Buffer = AllocatePool(BufferSize);
FreePool(Buffer);
break;
}
-
+
// check for end of listing
if (BufferSize == 0) { // end of directory listing
FreePool(Buffer);
break;
}
-
+
// entry is ready to be returned
*DirEntry = (EFI_FILE_INFO *)Buffer;
-
+
// filter results
if (FilterMode == 1) { // only return directories
if (((*DirEntry)->Attribute & EFI_FILE_DIRECTORY))
break;
} else // no filter or unknown filter -> return everything
break;
-
+
}
return Status;
}
FreePool(DirIter->LastFileInfo);
DirIter->LastFileInfo = NULL;
}
-
+
if (EFI_ERROR(DirIter->LastStatus))
return FALSE; // stop iteration
-
+
for (;;) {
DirIter->LastStatus = DirNextEntry(DirIter->DirHandle, &(DirIter->LastFileInfo), FilterMode);
if (EFI_ERROR(DirIter->LastStatus))
} else
break;
}
-
+
*DirEntry = DirIter->LastFileInfo;
return TRUE;
}
if (Second != NULL)
Length2 = StrLen(Second);
NewString = AllocatePool(sizeof(CHAR16) * (Length1 + Length2 + 2));
- NewString[0] = 0;
+ NewString[0] = L'\0';
if (NewString != NULL) {
if (*First != NULL) {
StrCat(NewString, *First);
{
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.2.4.2");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.2.5");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
if (ErrorInStep != NULL)
*ErrorInStep = 3;
}
-
+
// re-open file handles
ReinitRefitLib();
KernelVersion = FindNumbers(FileName);
Path = FindPath(LoaderPath);
+ MergeStrings(&Path, L"\\", 0); // Add trailing backslash; necessary for root directory
DirIterOpen(Volume->RootDir, Path, &DirIter);
while ((DirIterNext(&DirIter, 2, L"init*", &DirEntry)) && (InitrdName == NULL)) {
InitrdVersion = FindNumbers(DirEntry->FileName);
if (KernelVersion != NULL) {
if (StriCmp(InitrdVersion, KernelVersion) == 0)
- InitrdName = PoolPrint(L"%s\\%s", Path, DirEntry->FileName);
+ InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
} else {
if (InitrdVersion == NULL)
- InitrdName = PoolPrint(L"%s\\%s", Path, DirEntry->FileName);
+ InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
} // if/else
if (InitrdVersion != NULL)
FreePool(InitrdVersion);
// that will (with luck) work fairly automatically.
VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume) {
CHAR16 IconFileName[256];
- CHAR16 *FileName, *OSIconName = NULL, *Temp;
+ CHAR16 *FileName, *PathOnly, *OSIconName = NULL, *Temp;
CHAR16 ShortcutLetter = 0;
FileName = Basename(LoaderPath);
+ PathOnly = FindPath(LoaderPath);
// locate a custom icon for the loader
StrCpy(IconFileName, LoaderPath);
ReplaceExtension(IconFileName, L".icns");
if (FileExists(Volume->RootDir, IconFileName)) {
Entry->me.Image = LoadIcns(Volume->RootDir, IconFileName, 128);
- } // if
+ } else if ((StrLen(PathOnly) == 0) && (Volume->VolIconImage != NULL)) {
+ Entry->me.Image = Volume->VolIconImage;
+ } // icon matched to loader or volume
Temp = FindLastDirName(LoaderPath);
MergeStrings(&OSIconName, Temp, L',');
Entry->OSType = 'R';
ShortcutLetter = 'R';
} else if (StriCmp(LoaderPath, MACOSX_LOADER_PATH) == 0) {
+ if (Volume->VolIconImage != NULL) { // custom icon file found
+ Entry->me.Image = Volume->VolIconImage;
+ }
MergeStrings(&OSIconName, L"mac", L',');
Entry->UseGraphicsMode = TRUE;
Entry->OSType = 'M';
Entry->me.ShortcutLetter = ShortcutLetter;
if (Entry->me.Image == NULL)
Entry->me.Image = LoadOSIcon(OSIconName, L"unknown", FALSE);
+ if (PathOnly != NULL)
+ FreePool(PathOnly);
} // VOID SetLoaderDefaults()
// Add a specified EFI boot loader to the list, using automatic settings