From: srs5694 Date: Sat, 29 Mar 2014 02:40:18 +0000 (-0400) Subject: Fixed filesystem driver bugs. X-Git-Url: https://code.delx.au/refind/commitdiff_plain/3ea2147587e27beae55294420d52e4a10b6331b2 Fixed filesystem driver bugs. --- diff --git a/NEWS.txt b/NEWS.txt index ee7d361..a7fab5f 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,14 @@ 0.7.9 (?/??/2014): ------------------ +- Fixed some EFI filesystem driver bugs that could cause lockups under + some circumstances. These bugs could affect any of the filesystem + drivers. + +- Added "gdisk" option to the "showtools" configuration file token. When + active, this adds gdisk.efi or gdisk_{arch}.efi, if present in the + EFI\tools directory, to the tools row. + - Fixed mistaken identification of the MOK utility as the "MOK utility utility." diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index c246c43..95f2cb0 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -184,9 +184,9 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

  • You can give the filesystem from which the boot loader is loaded a name that matches the OS name component of the icon filename. For instance, if you call your boot filesystem CentOS, it matches the os_centos.icns icon. This match is performed on a word-by-word basis within the name, with "words" being delimited by spaces, dashes (-), and underscores (_). Thus, a volume called Debian-boot will match os_debian.icns or os_boot.icns.
  • -
  • Certain boot loaders have hard-coded icons associated with them. For instance, filenames beginning with vmlinuz or bzImage acquire Linux "Tux" icons and the bootmgfw.efi loader acquires a Windows icon. For the most part, these are the associations you want to overcome with the preceding rules, but sometimes renaming a boot loader to a more conventional name is the better approach.
  • +
  • rEFInd attempts to guess the Linux distribution based on data in the /etc/os-release file. This file will only be accessible if a separate /boot partition is not used, though. Manually adjusting the os-release file to change an OS icon in rEFInd is not recommended.
  • -
  • rEFInd attempts to guess the Linux distribution based on clues in the kernel's filename and data in the /etc/os-release file. This file will only be accessible if a separate /boot partition is not used, though. Fedora and Red Hat kernels can be identified by the presence of .fc or .el strings in their filenames, and so acquire suitable icons automatically. Manually adjusting the os-release file to change an OS icon in rEFInd is not recommended. Renaming a locally-compiled kernel so that it acquires a Fedora or Red Hat icon is reasonable, but I don't recommend renaming precompiled kernels unless you also manually copy them to the ESP.
  • +
  • Certain boot loaders have hard-coded icons associated with them. For instance, filenames beginning with vmlinuz or bzImage acquire Linux "Tux" icon and the bootmgfw.efi loader acquires a Windows icon. Fedora and Red Hat kernels can be identified by the presence of .fc or .el strings in their filenames, and so acquire suitable icons automatically. For the most part, these are the associations you want to overcome with the preceding rules, but sometimes renaming a boot loader to a more conventional name is the better approach. Renaming a locally-compiled kernel so that it acquires a Fedora or Red Hat icon is reasonable, but I don't recommend renaming precompiled kernels unless you also manually copy them to the ESP.
  • @@ -270,8 +270,8 @@ timeout 20 showtools - shell, memtest, gptsync, apple_recovery, mok_tool, about, exit, shutdown, reboot, and firmware - Specifies which tool tags to display on the second row. shell launches an EFI shell, memtest (or memtest86 launches the Memtest86 program, gptsync launches a tool that creates a hybrid MBR, apple_recovery boots the OS X Recovery HD, windows_recovery boots a Windows recovery tool, 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 some UEFI PCs), reboot reboots the computer, and firmware reboots the computer into the computer's own setup utility. The tags appear in the order in which you specify them. The default is shell, memtest, apple_recovery, mok_tool, about, shutdown, reboot, firmware. Note that the shell, memtest, apple_recovery, and mok_tool options all require the presence of programs not included with rEFInd. The gptsync option requires use of a like-named program which, although it ships with rEFInd 0.6.9 and later, is not installed by default except under OS X. See the "Installing Additional Components" section of the Installing rEFInd page for pointers to the shell, Memtest86, 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). The firmware option works only on computers that support this option; on other computers, the option is quietly ignored. See the Secure Boot page for information on Secure Boot and MOK management. + shell, memtest, gdisk, gptsync, apple_recovery, mok_tool, about, exit, shutdown, reboot, and firmware + Specifies which tool tags to display on the second row. shell launches an EFI shell, memtest (or memtest86) launches the Memtest86 program, gdisk launches the partitioning tool of the same name, gptsync launches a tool that creates a hybrid MBR, apple_recovery boots the OS X Recovery HD, windows_recovery boots a Windows recovery tool, 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 some UEFI PCs), reboot reboots the computer, and firmware reboots the computer into the computer's own setup utility. The tags appear in the order in which you specify them. The default is shell, memtest, gdisk, apple_recovery, mok_tool, about, shutdown, reboot, firmware. Note that the shell, memtest, apple_recovery, and mok_tool options all require the presence of programs not included with rEFInd. The gptsync option requires use of a like-named program which, although it ships with rEFInd 0.6.9 and later, is not installed by default except under OS X. See the "Installing Additional Components" section of the Installing rEFInd page for pointers to the shell, Memtest86, 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). The firmware option works only on computers that support this option; on other computers, the option is quietly ignored. See the Secure Boot page for information on Secure Boot and MOK management. font diff --git a/docs/refind/features.html b/docs/refind/features.html index 44bb0ec..30e3258 100644 --- a/docs/refind/features.html +++ b/docs/refind/features.html @@ -229,7 +229,7 @@ lack a usable CSM.
  • Drivers for ISO-9660, HFS+, ext4fs, and Btrfs, which are not included in rEFIt. (The ISO-9660 driver is based on code from the rEFIt project, but was never completed by its original author. It was completed by Oracle for VirtualBox. The ext4fs driver is derived from the rEFIt ext2fs driver, and the Btrfs driver is derived from the rEFIt and GRUB 2.0 driver code.)
  • -
  • Beginning with version 0.5.0, the ability to "talk" to the shim boot loader to validate binaries supported by shim or its machine owner key (MOK) list when booting with Secure Boot active. As of version 0.6.0, this support is still crude and buggy; it should be considered an alpha-level feature at the moment.
  • +
  • Beginning with version 0.5.0, the ability to "talk" to the shim boot loader to validate binaries supported by shim or its machine owner key (MOK) list when booting with Secure Boot active.
  • The gptsync utility, included with rEFInd 0.6.9 and later, has safety checks to prevent creating a fresh hybrid MBR if the MBR side has been adjusted without adjusting the GPT side—a common source of problems. This update also prioritizes partition inclusion in the hybrid MBR, which can help on disks that have many partitions. OTOH, as of rEFInd 0.6.9, this version of gptsync is relatively untested.
  • diff --git a/docs/refind/installing.html b/docs/refind/installing.html index b459436..31d62f5 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: -3/9/2014, referencing rEFInd 0.7.8

    +3/23/2014, referencing rEFInd 0.7.8

    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!

    @@ -944,7 +944,9 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

    Most of the reports of sluggish Macintosh boots I've seen note that the user installed rEFInd to the ESP rather than to the OS X root partition. Some users have reported that re-installing rEFInd to the OS X root partition clears up the problem. This is obviously a straightforward solution to the problem, if it works. Note that rEFInd can launch boot loaders that are stored on any partition that the EFI can read no matter where it's installed; therefore, you'll still be able to launch boot loaders stored on the ESP (or elsewhere) if you install it in this way.

    -

    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 to create a small (~100MiB) HFS+ volume to be used exclusively by rEFInd. You can then install rEFInd to that volume with the --ownhfs option to install.sh, as in ./install.sh --ownhfs /dev/disk0s6 if the volume is /dev/disk0s6. This approach has the advantage that it can be managed via OS X's own Startup Disk tool in System Preferences.

    + +

    The biggest drawback to storing rEFInd on an HFS+ volume 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 on the OS X boot volume. This isn't as risky if you use a dedicated HFS+ rEFInd partition, though. You could even mount it as the Linux /boot partition, in which case it would also hold the Linux kernel and related files. If you use disk encryption, you can't store rEFInd on the OS X root (/) partition, but you could still use an (unencrypted) separate HFS+ partition.

    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.)

    diff --git a/filesystems/fsw_btrfs.c b/filesystems/fsw_btrfs.c index 1cfab95..c05547d 100644 --- a/filesystems/fsw_btrfs.c +++ b/filesystems/fsw_btrfs.c @@ -406,7 +406,7 @@ static fsw_status_t btrfs_read_superblock (struct fsw_volume *vol, struct btrfs_ break; err = fsw_block_get(vol, superblock_pos[i], 0, (void **)&buffer); - if (err == FSW_UNSUPPORTED) { + if (err) { fsw_block_release(vol, superblock_pos[i], buffer); break; } @@ -1862,7 +1862,7 @@ out: // struct fsw_fstype_table FSW_FSTYPE_TABLE_NAME(btrfs) = { - { FSW_STRING_TYPE_UTF8, 4, 4, "btrfs" }, + { FSW_STRING_TYPE_UTF8, 5, 5, "btrfs" }, sizeof(struct fsw_btrfs_volume), sizeof(struct fsw_btrfs_dnode), diff --git a/filesystems/fsw_efi.c b/filesystems/fsw_efi.c index 30982c3..49eccf9 100644 --- a/filesystems/fsw_efi.c +++ b/filesystems/fsw_efi.c @@ -556,6 +556,7 @@ fsw_status_t fsw_efi_read_block(struct fsw_volume *vol, fsw_u64 phys_bno, void * i = 0; do { if ((Caches[i].Volume == Volume) && + (Caches[i].CacheValid == TRUE) && (StartRead >= Caches[i].CacheStart) && ((StartRead + vol->phys_blocksize) <= (Caches[i].CacheStart + CACHE_SIZE))) { ReadCache = i; @@ -568,6 +569,7 @@ fsw_status_t fsw_efi_read_block(struct fsw_volume *vol, fsw_u64 phys_bno, void * if (LastRead == -1) LastRead = 1; ReadCache = 1 - LastRead; // NOTE: If NUM_CACHES > 2, this must become more complex + Caches[ReadCache].CacheValid = FALSE; if (Caches[ReadCache].Cache == NULL) Caches[ReadCache].Cache = AllocatePool(CACHE_SIZE); if (Caches[ReadCache].Cache != NULL) { @@ -586,7 +588,7 @@ fsw_status_t fsw_efi_read_block(struct fsw_volume *vol, fsw_u64 phys_bno, void * } // if cache memory allocated } // if (ReadCache < 0) - if (Caches[ReadCache].Cache != NULL) { + if (Caches[ReadCache].Cache != NULL && Caches[ReadCache].CacheValid == TRUE) { CopyMem(buffer, &Caches[ReadCache].Cache[StartRead - Caches[ReadCache].CacheStart], vol->phys_blocksize); } else { ReadOneBlock = TRUE; diff --git a/refind.conf-sample b/refind.conf-sample index ebca00f..8fca9fb 100644 --- a/refind.conf-sample +++ b/refind.conf-sample @@ -157,6 +157,7 @@ timeout 20 # EFI/memtest, EFI/tools/memtest86, or EFI/tools/memtest # gptsync - the (dangerous) gptsync.efi utility (requires external # program; see rEFInd documentation for details) +# gdisk - the gdisk partitioning program # apple_recovery - boots the Apple Recovery HD partition, if present # windows_recovery - boots an OEM Windows recovery tool, if present # (see also the windows_recovery_files option) @@ -169,9 +170,9 @@ timeout 20 # reboot - a tag to reboot the computer # firmware - a tag to reboot the computer into the firmware's # user interface (ignored on older computers) -# Default is shell,memtest,apple_recovery,windows_recovery,mok_tool,about,shutdown,reboot,firmware +# Default is shell,memtest,gdisk,apple_recovery,windows_recovery,mok_tool,about,shutdown,reboot,firmware # -#showtools shell, memtest, mok_tool, about, reboot, exit, firmware +#showtools shell, gdisk, memtest, mok_tool, about, reboot, exit, firmware # Boot loaders that can launch a Windows restore or emergency system. # These tend to be OEM-specific. diff --git a/refind/config.c b/refind/config.c index 58043ae..447638f 100644 --- a/refind/config.c +++ b/refind/config.c @@ -532,6 +532,8 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.ShowTools[i - 1] = TAG_SHELL; } else if (StriCmp(FlagName, L"gptsync") == 0) { GlobalConfig.ShowTools[i - 1] = TAG_GPTSYNC; + } else if (StriCmp(FlagName, L"gdisk") == 0) { + GlobalConfig.ShowTools[i - 1] = TAG_GDISK; } else if (StriCmp(FlagName, L"about") == 0) { GlobalConfig.ShowTools[i - 1] = TAG_ABOUT; } else if (StriCmp(FlagName, L"exit") == 0) { diff --git a/refind/global.h b/refind/global.h index c45acda..586ff9b 100644 --- a/refind/global.h +++ b/refind/global.h @@ -73,7 +73,8 @@ #define TAG_MOK_TOOL (13) #define TAG_FIRMWARE (14) #define TAG_MEMTEST (15) -#define NUM_TOOLS (16) +#define TAG_GDISK (16) +#define NUM_TOOLS (17) #define NUM_SCAN_OPTIONS 10 diff --git a/refind/lib.c b/refind/lib.c index dc187c6..7ee9c4c 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -637,7 +637,7 @@ static VOID ScanVolumeBootcode(REFIT_VOLUME *Volume, BOOLEAN *Bootable) // dummy FAT boot sector (created by iPartition) if ((FindMem(Buffer, 512, "Medienfehler", 12) >= 0) && - (FindMem(Buffer, 512, "Neustart: Taste dr\x81" "ken", 22) >= 0)) + (FindMem(Buffer, 512, "Neustart: Taste dr\x81" "cken", 22) >= 0)) Volume->HasBootCode = FALSE; // check for MBR partition table @@ -709,7 +709,7 @@ static CHAR16 *SizeInIEEEUnits(UINT64 SizeInBytes) { SPrint(TheValue, 255, L"%ld%s", SizeInIeee, Units); } // if return TheValue; -} // CHAR16 *SizeInSIUnits() +} // CHAR16 *SizeInIEEEUnits() // Return a name for the volume. Ideally this should be the label for the // filesystem it contains, but this function falls back to describing the diff --git a/refind/main.c b/refind/main.c index 566b87d..4f0b0b7 100644 --- a/refind/main.c +++ b/refind/main.c @@ -75,6 +75,7 @@ #if defined (EFIX64) #define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellx64.efi,\\shell.efi,\\shellx64.efi" #define GPTSYNC_NAMES L"\\EFI\\tools\\gptsync.efi,\\EFI\\tools\\gptsync_x64.efi" +#define GDISK_NAMES L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_x64.efi" #define MEMTEST_NAMES L"memtest86.efi,memtest86_x64.efi,memtest86x64.efi,bootx64.efi" #define DRIVER_DIRS L"drivers,drivers_x64" #define FALLBACK_FULLNAME L"EFI\\BOOT\\bootx64.efi" @@ -83,6 +84,7 @@ #elif defined (EFI32) #define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellia32.efi,\\shell.efi,\\shellia32.efi" #define GPTSYNC_NAMES L"\\EFI\\tools\\gptsync.efi,\\EFI\\tools\\gptsync_ia32.efi" +#define GDISK_NAMES L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_ia32.efi" #define MEMTEST_NAMES L"memtest86.efi,memtest86_ia32.efi,memtest86ia32.efi,bootia32.efi" #define DRIVER_DIRS L"drivers,drivers_ia32" #define FALLBACK_FULLNAME L"EFI\\BOOT\\bootia32.efi" @@ -91,6 +93,7 @@ #else #define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\shell.efi" #define GPTSYNC_NAMES L"\\EFI\\tools\\gptsync.efi" +#define GDISK_NAMES L"\\EFI\\tools\\gdisk.efi" #define MEMTEST_NAMES L"memtest86.efi" #define DRIVER_DIRS L"drivers" #define FALLBACK_FULLNAME L"EFI\\BOOT\\boot.efi" /* Not really correct */ @@ -134,8 +137,8 @@ static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0, { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE }, BANNER_NOSCALE, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, - TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 } + { TAG_SHELL, TAG_MEMTEST, TAG_GDISK, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL, + TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 } }; EFI_GUID GlobalGuid = EFI_GLOBAL_VARIABLE; @@ -156,7 +159,7 @@ static VOID AboutrEFInd(VOID) { if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.8.2"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.8.4"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith"); @@ -2297,6 +2300,18 @@ static VOID ScanForTools(VOID) { FileName = NULL; break; + case TAG_GDISK: + j = 0; + while ((FileName = FindCommaDelimited(GDISK_NAMES, j++)) != NULL) { + if (FileExists(SelfRootDir, FileName)) { + AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"disk partitioning tool", + BuiltinIcon(BUILTIN_ICON_TOOL_PART), 'G', FALSE); + } // if + MyFreePool(FileName); + } // while + FileName = NULL; + break; + case TAG_APPLE_RECOVERY: FileName = StrDuplicate(L"\\com.apple.recovery.boot\\boot.efi"); for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {