From 19d316b6524fa49fd5ba2af56cdf77581fb4c58b Mon Sep 17 00:00:00 2001 From: srs5694 Date: Tue, 13 Aug 2013 18:57:53 -0400 Subject: [PATCH] Fix to hang when booting from Mac Firewire devices. --- NEWS.txt | 7 +++++++ docs/refind/installing.html | 2 ++ mkcdimage | 2 +- refind/main.c | 16 ++++++++++++---- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index 5cd1109..f4b8a4a 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,10 @@ +0.7.4 (?/??/2013): +------------------ + +- Fixed bug that could cause rEFInd to hang when launching boot loaders + under some conditions. (Launching from Firewire drives on Macs is the + known case, but there may be others.) + 0.7.3 (8/7/2013): ----------------- diff --git a/docs/refind/installing.html b/docs/refind/installing.html index 0e49b66..afa0241 100644 --- a/docs/refind/installing.html +++ b/docs/refind/installing.html @@ -904,6 +904,8 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

The biggest drawback to this approach is that you won't be able to edit the rEFInd configuration file or move rEFInd-related binaries from an EFI shell if you install it in this way, since Apple's HFS+ driver for EFI is read-only. (The same is true of rEFInd's HFS+ driver, so it won't help you overcome this limitation.) You may also be limited in making changes to your rEFInd configuration from Linux or other OSes, too, since Linux's HFS+ drivers disable write support by default on volumes with an active journal. You can force write access by using the force option to mount; however, this procedure is noted as being risky in the Linux HFS+ documentation, so I don't recommend doing this on a regular basis. As a compromise, you might try creating a small non-journaled HFS+ volume that's dedicated to holding rEFInd. You could even mount it as the Linux /boot partition, in which case it would also hold the Linux kernel and related files. You'll need to install rEFInd manually if you try this.

+

A variant of this solution is suggested in this blog post, which recommends placing rEFInd on an HFS+ volume on the first SATA channel. (In the blogger's case, that channel used to hold an optical drive, but that drive was replaced by a hard disk.)

+

Using the Fallback Filename

diff --git a/mkcdimage b/mkcdimage index 934199a..3c8b58f 100755 --- a/mkcdimage +++ b/mkcdimage @@ -46,7 +46,7 @@ ln ../../../refind/drivers_x64/* ./ cd .. mkdir drivers_ia32 cd drivers_ia32 -ln ../../../refind/drivers_x64/* ./ +ln ../../../refind/drivers_ia32/* ./ cd ../../.. # Get the size of the binaries to go in the El Torito image in kB diff --git a/refind/main.c b/refind/main.c index bb400e1..392bed2 100644 --- a/refind/main.c +++ b/refind/main.c @@ -151,7 +151,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.3"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.3.4"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -223,9 +223,16 @@ static BOOLEAN IsValidLoader(EFI_FILE *RootDir, CHAR16 *FileName) { CHAR8 Header[512]; UINTN Size = sizeof(Header); + if ((RootDir == NULL) || (FileName == NULL)) { + // Assume valid here, because Macs produce NULL RootDir (& maybe FileName) + // when launching from a Firewire drive. This should be handled better, but + // fix would have to be in StartEFIImageList() and/or in FindVolumeAndFilename(). + return TRUE; + } // if + Status = refit_call5_wrapper(RootDir->Open, RootDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) - return 0; + return FALSE; Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &Size, Header); refit_call1_wrapper(FileHandle->Close, FileHandle); @@ -287,8 +294,9 @@ static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths, for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) { FindVolumeAndFilename(DevicePaths[DevicePathIndex], &Volume, &Filename); // Some EFIs crash if attempting to load driver for invalid architecture, so - // protect for this condition.... - if ((LoaderType == TYPE_LEGACY) || IsValidLoader(Volume->RootDir, Filename)) { + // protect for this condition; but sometimes Volume comes back NULL, so provide + // an exception. (TODO: Handle this special condition better.) + if ((LoaderType == TYPE_LEGACY) || (Volume == NULL) || IsValidLoader(Volume->RootDir, Filename)) { // NOTE: Below commented-out line could be more efficient if file were read ahead of // time and passed as a pre-loaded image to LoadImage(), but it doesn't work on my // 32-bit Mac Mini or my 64-bit Intel box when launching a Linux kernel; the -- 2.39.2