From: srs5694 Date: Sat, 22 Dec 2012 00:31:54 +0000 (-0500) Subject: Tweaks to graphics mode-setting code; added --root option to install.sh X-Git-Url: https://code.delx.au/refind/commitdiff_plain/99a75c0d391580161f651db61bb43afb46f4e5cd Tweaks to graphics mode-setting code; added --root option to install.sh --- diff --git a/NEWS.txt b/NEWS.txt index 0412d80..cf8bb58 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,16 @@ 0.6.1 (12/??/2012): ------------------- +- Thanks to Stefan Agner, the ext4fs driver now supports the "meta_bg" + filesystem feature, which distributes metadata throughout the disk. This + feature isn't used by default, but can be set at filesystem creation time + by passing the "-O meta_bg,^resize_inode" option to mke2fs. (Using + "^resize_inode" is necessary because meta_bg is incompatible with + resize_inode, which IS used by default.) This feature can be used on + ext3fs and ext2fs as well as on ext4fs, so the ext4fs driver can now + handle some ext3fs and ext2fs partitions that the ext2fs driver can't + handle. + - Fixed some screen resolution-setting bugs. - Added the "words" that make up a filesystem's label (delimited by spaces, diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index 2f33216..40836a4 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -185,12 +185,12 @@ timeout 20 textmode text mode number - Sets the text-mode video resolution to be used in conjunction with textonly or for the line editor and program-launch screens. This option takes a single-digit code. Mode 0 is guaranteed to be present and should be 80x25. Mode 1 is supposed to be either invalid or 80x50, but some systems use this number for something else. Higher values are system-specific. If you set this option to an invalid value, rEFInd pauses during startup to tell you of that fact. Note that on some computers, setting this value without also using textonly results in an incorrect graphics video mode being set. Pressing the Esc key corrects the problem. + Sets the text-mode video resolution to be used in conjunction with textonly or for the line editor and program-launch screens. This option takes a single-digit code. Mode 0 is guaranteed to be present and should be 80x25. Mode 1 is supposed to be either invalid or 80x50, but some systems use this number for something else. Higher values are system-specific. If you set this option to an invalid value, rEFInd pauses during startup to tell you of that fact. Note that setting textmode can sometimes force your graphics-mode resolution to a higher value than you specify in resolution. resolution one or two integer values - Sets the video resolution used by rEFInd; takes either a width and a height or a single UEFI video mode number as options. For instance, resolution 1024 768 sets the resolution to 1024x768. On UEFI systems, resolution 1 sets video mode 1, the resolution of which varies from system to system. If you set a resolution that doesn't work on a UEFI-based system, rEFInd displays a message along with a list of valid modes. On an system built around EFI 1.x (such as a Mac), setting an incorrect resolution fails silently; you'll get the system's default resolution. You'll also get the system's default resolution if you set both resolution values to 0 or if you pass anything but two numbers. (Note that passing a resolution with an x, as in 1024x768, will be interpreted as one option and so will cause the default resolution to be used.) Also, be aware that it is possible to set a valid resolution for your video card that's invalid for your monitor. If you do this, your monitor will go blank until you've booted an OS that resets the video mode. + Sets the video resolution used by rEFInd; takes either a width and a height or a single UEFI video mode number as options. For instance, resolution 1024 768 sets the resolution to 1024x768. On UEFI systems, resolution 1 sets video mode 1, the resolution of which varies from system to system. If you set a resolution that doesn't work on a UEFI-based system, rEFInd displays a message along with a list of valid modes. On an system built around EFI 1.x (such as a Mac), setting an incorrect resolution fails silently; you'll get the system's default resolution. You'll also get the system's default resolution if you set both resolution values to 0 or if you pass anything but two numbers. (Note that passing a resolution with an x, as in 1024x768, will be interpreted as one option and so will cause the default resolution to be used.) If you get a higher resolution than you request, try commenting out or changing the textmode value, since it can force the system to use a higher graphics resolution than you specify with resolution. Also, be aware that it is possible to set a valid resolution for your video card that's invalid for your monitor. If you do this, your monitor will go blank until you've booted an OS that resets the video mode. use_graphics_for diff --git a/docs/refind/installing.html b/docs/refind/installing.html index 03f54cc..3ce06e1 100644 --- a/docs/refind/installing.html +++ b/docs/refind/installing.html @@ -224,8 +224,9 @@ Installation has completed successfully.

In addition to these quirks, you should be aware of some options that install.sh supports to enable you to customize your installation in various ways. The syntax for install.sh is as follows:

-install.sh [--esp | --usedefault device-file] [--nodrivers | --alldrivers] \
-           [--shim shim-filename] [--localkeys]
+install.sh [--esp | --usedefault device-file | --root mount-point ] \
+           [--nodrivers | --alldrivers] [--shim shim-filename] \
+           [--localkeys]
 

The details of the options are summarized in Table 1. Using some of these options in unusual conditions can generate warnings and prompts to confirm your actions. In particular, using --shim or --localkeys when you're not booted in Secure Boot mode, or failing to use --shim when you are booted in Secure Boot mode, will generate a query and a request to confirm your installation. Consult the Managing Secure Boot page for more on this topic.

@@ -241,7 +242,11 @@ install.sh [--esp | --usedefault device-file] [--nodri --usedefault device-file - You can install rEFInd to a disk using the default/fallback filename of EFI/BOOT/bootx64.efi (and EFI/BOOT/bootia32.efi, if the 32-bit build is available) using this option. The device-file should be an unmounted ESP, or at least a FAT partition, as in --usedefault /dev/sdc1. Your computer's NVRAM entries will not be modified when installing in this way. The intent is that you can create a bootable USB flash drive or install rEFInd on a computer that tends to "forget" its NVRAM settings with this option. This option is mutually exclusive with --esp. + You can install rEFInd to a disk using the default/fallback filename of EFI/BOOT/bootx64.efi (and EFI/BOOT/bootia32.efi, if the 32-bit build is available) using this option. The device-file should be an unmounted ESP, or at least a FAT partition, as in --usedefault /dev/sdc1. Your computer's NVRAM entries will not be modified when installing in this way. The intent is that you can create a bootable USB flash drive or install rEFInd on a computer that tends to "forget" its NVRAM settings with this option. This option is mutually exclusive with --esp and --root (except for implicit use of --esp on Linux). + + + --root /mount-point + This option is intended to help install rEFInd from a "live CD" or other emergency system. To use it, you should mount your regular Linux installation at /mount-point, including your /boot directory (if it's separate) at /mount-point/boot and your ESP at that location or at /mount-point/boot/efi. The install.sh script then installs rEFInd to the appropriate location—/mount-point/boot/EFI/refind or /mount-point/boot/efi/EFI/refind, depending on where you've mounted your ESP. The script also adds an entry to your NVRAM for rEFInd at this location. You cannot use this option with either --esp or --usedefault, except for implicit use of --esp on Linux. --nodrivers diff --git a/filesystems/fsw_efi.c b/filesystems/fsw_efi.c index 3e96e62..4bcb90d 100644 --- a/filesystems/fsw_efi.c +++ b/filesystems/fsw_efi.c @@ -76,7 +76,7 @@ /** Helper macro for stringification. */ #define FSW_EFI_STRINGIFY(x) #x /** Expands to the EFI driver name given the file system type name. */ -#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.6.0 " FSW_EFI_STRINGIFY(t) L" File System Driver" +#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.6.1 " FSW_EFI_STRINGIFY(t) L" File System Driver" // function prototypes diff --git a/install.sh b/install.sh index e28fb41..0559d58 100755 --- a/install.sh +++ b/install.sh @@ -29,6 +29,7 @@ # # Revision history: # +# 0.6.1 -- Added --root option; minor bug fixes # 0.6.0 -- Changed --drivers to --alldrivers and added --nodrivers option; # changed default driver installation behavior in Linux to install # the driver needed to read /boot (if available) @@ -47,10 +48,9 @@ # Note: install.sh version numbers match those of the rEFInd package # with which they first appeared. +RootDir="/" TargetDir=/EFI/refind -EtcKeysDir=/etc/refind.d/keys LocalKeysBase="refind_local" -RLConfFile="/boot/refind_linux.conf" ShimSource="none" TargetX64="refind_x64.efi" TargetIA32="refind_ia32.efi" @@ -79,6 +79,9 @@ GetParams() { TargetIA32="bootia32.efi" shift ;; + --root) RootDir=$2 + shift + ;; --localkeys) LocalKeys=1 ;; --shim) ShimSource=$2 @@ -88,17 +91,29 @@ GetParams() { ;; --nodrivers) InstallDrivers="none" ;; - * ) echo "Usage: $0 [--esp | --usedefault {device-file}] [--nodrivers | --alldrivers] " - echo " [--shim {shim-filename}] [--localkeys]" + * ) echo "Usage: $0 [--esp | --usedefault {device-file} | --root {directory} ]" + echo " [--nodrivers | --alldrivers] [--shim {shim-filename}]" + echo " [--localkeys]" exit 1 esac shift done + if [[ $InstallToEspOnMac == 1 && $TargetDir == '/EFI/BOOT' ]] ; then echo "You may use --esp OR --usedefault, but not both! Aborting!" exit 1 fi -# exit 1 + if [[ $RootDir != '/' && $TargetDir == '/EFI/BOOT' ]] ; then + echo "You may use --usedefault OR --root, but not both! Aborting!" + exit 1 + fi + if [[ $RootDir != '/' && $InstallToEspOnMac == 1 ]] ; then + echo "You may use --root OR --esp, but not both! Aborting!" + exit 1 + fi + + RLConfFile="$RootDir/boot/refind_linux.conf" + EtcKeysDir="$RootDir/etc/refind.d/keys" } # GetParams() # Abort if the rEFInd files can't be found. @@ -343,7 +358,7 @@ InstallOnOSX() { elif [[ $InstallToEspOnMac == "1" ]] ; then MountOSXESP else - InstallDir="/" + InstallDir="$RootDir/" fi echo "Installing rEFInd to the partition mounted at '$InstallDir'" Platform=`ioreg -l -p IODeviceTree | grep firmware-abi | cut -d "\"" -f 4` @@ -385,15 +400,21 @@ InstallOnOSX() { # appropriate options haven't been set, warn the user and offer to abort. # If we're NOT in Secure Boot mode but the user HAS specified the --shim # or --localkeys option, warn the user and offer to abort. +# +# FIXME: Although I checked the presence (and lack thereof) of the +# /sys/firmware/efi/vars/SecureBoot* files on my Secure Boot test system +# before releasing this script, I've since found that they are at least +# sometimes present when Secure Boot is absent. This means that the first +# test can produce false alarms. A better test is highly desirable. CheckSecureBoot() { VarFile=`ls -d /sys/firmware/efi/vars/SecureBoot* 2> /dev/null` if [[ -n $VarFile && $TargetDir != '/EFI/BOOT' && $ShimSource == "none" ]] ; then echo "" - echo "CAUTION: The computer seems to have been booted with Secure Boot active, but" - echo "you haven't specified a valid shim.efi file source. The resulting installation" - echo "will not boot unless you disable Secure Boot. You may continue, but you should" - echo "consider using --shim to specify a working shim.efi file. You can read more" - echo "about this topic at http://www.rodsbooks.com/refind/secureboot.html." + echo "CAUTION: Your computer appears to support Secure Boot, but you haven't" + echo "specified a valid shim.efi file source. If you've disabled Secure Boot and" + echo "intend to leave it disabled, this is fine; but if Secure Boot is active, the" + echo "resulting installation won't boot. You can read more about this topic at" + echo "http://www.rodsbooks.com/refind/secureboot.html." echo "" echo -n "Do you want to proceed with installation (Y/N)? " read ContYN @@ -525,16 +546,22 @@ ReSignBinaries() { DeleteRefindDir=1 } -# Identifies the ESP's location (/boot or /boot/efi); aborts if -# the ESP isn't mounted at either location. +# Identifies the ESP's location (/boot or /boot/efi, or these locations under +# the directory specified by --root); aborts if the ESP isn't mounted at +# either location. # Sets InstallDir to the ESP mount point. FindLinuxESP() { - EspLine=`df /boot/efi | grep boot` + EspLine=`df $RootDir/boot/efi 2> /dev/null | grep boot/efi` + if [[ ! -n $EspLine ]] ; then + EspLine=`df $RootDir/boot | grep boot` + fi InstallDir=`echo $EspLine | cut -d " " -f 6` - EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3` + if [[ -n $InstallDir ]] ; then + EspFilesystem=`grep $InstallDir /etc/mtab | cut -d " " -f 3` + fi if [[ $EspFilesystem != 'vfat' ]] ; then - echo "/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be mounted at" - echo "/boot or /boot/efi and it must be VFAT! Aborting!" + echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be" + echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!" exit 1 fi echo "ESP was found at $InstallDir using $EspFilesystem" @@ -598,7 +625,7 @@ GenerateRefindLinuxConf() { # We want the default options used by the distribution, stored here.... source /etc/default/grub fi - RootFS=`df / | grep dev | cut -f 1 -d " "` + RootFS=`df $RootDir | grep dev | cut -f 1 -d " "` StartOfDevname=`echo $RootFS | cut -b 1-7` if [[ $StartOfDevname == "/dev/sd" || $StartOfDevName == "/dev/hd" ]] ; then # Identify root filesystem by UUID rather than by device node, if possible diff --git a/libeg/libeg.h b/libeg/libeg.h index a354aa3..15e561a 100644 --- a/libeg/libeg.h +++ b/libeg/libeg.h @@ -78,6 +78,7 @@ typedef struct { /* functions */ VOID egInitScreen(VOID); +BOOLEAN egGetResFromMode(UINTN *ModeWidth, UINTN *Height); VOID egGetScreenSize(OUT UINTN *ScreenWidth, OUT UINTN *ScreenHeight); CHAR16 * egScreenDescription(VOID); BOOLEAN egHasGraphicsMode(VOID); diff --git a/libeg/screen.c b/libeg/screen.c index 84062db..02b9f67 100644 --- a/libeg/screen.c +++ b/libeg/screen.c @@ -115,6 +115,23 @@ VOID egInitScreen(VOID) egDetermineScreenSize(); } +// Convert a graphics mode (in *ModeWidth) to a width and height (returned in +// *ModeWidth and *Height, respectively). +// Returns TRUE if successful, FALSE if not (invalid mode) +BOOLEAN egGetResFromMode(UINTN *ModeWidth, UINTN *Height) { + UINTN Size; + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info = NULL; + + Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, *ModeWidth, &Size, &Info); + if ((Status == EFI_SUCCESS) && (Info != NULL)) { + *ModeWidth = Info->HorizontalResolution; + *Height = Info->VerticalResolution; + return TRUE; + } + return FALSE; +} // BOOLEAN egGetResFromMode() + // Sets the screen resolution to the specified value, if possible. If *ScreenHeight // is 0 and GOP mode is detected, assume that *ScreenWidth contains a GOP mode // number rather than a horizontal resolution. If the specified resolution is not @@ -134,12 +151,17 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { if (GraphicsOutput != NULL) { // GOP mode (UEFI) if (*ScreenHeight == 0) { // User specified a mode number (stored in *ScreenWidth); use it directly + ModeNum = (UINT32) *ScreenWidth; + if (egGetResFromMode(ScreenWidth, ScreenHeight) && ( + refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum) == EFI_SUCCESS)) { + ModeSet = TRUE; + } // if ((*ScreenWidth == GraphicsOutput->Mode->Mode)) { // user requested current mode; do nothing // ModeSet = TRUE; // *ScreenWidth = Info->HorizontalResolution; // *ScreenHeight = Info->VerticalResolution; // } else { - ModeNum = (UINT32) *ScreenWidth; +/* ModeNum = (UINT32) *ScreenWidth; Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info); if (Status == EFI_SUCCESS) { Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum); @@ -148,7 +170,7 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { *ScreenWidth = Info->HorizontalResolution; *ScreenHeight = Info->VerticalResolution; } // if set mode OK - } // if queried mode OK + } // if queried mode OK */ // } // if/else // User specified width & height; must find mode -- but only if change is required.... @@ -300,7 +322,6 @@ VOID egSetGraphicsModeEnabled(IN BOOLEAN Enable) EFI_CONSOLE_CONTROL_SCREEN_MODE CurrentMode; EFI_CONSOLE_CONTROL_SCREEN_MODE NewMode; - egSetTextMode(GlobalConfig.RequestedTextMode); if (ConsoleControl != NULL) { refit_call4_wrapper(ConsoleControl->GetMode, ConsoleControl, &CurrentMode, NULL, NULL); diff --git a/refind/config.c b/refind/config.c index 441d2a4..b1e0929 100644 --- a/refind/config.c +++ b/refind/config.c @@ -353,8 +353,6 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.DontScanDirs = StrDuplicate(SelfDirPath); MyFreePool(GlobalConfig.DontScanFiles); GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES); -// egGetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight); -// GlobalConfig.RequestedTextMode = ST->ConOut->Mode->Mode; } if (!FileExists(SelfDir, FileName)) { diff --git a/refind/main.c b/refind/main.c index 07260ed..996f6a6 100644 --- a/refind/main.c +++ b/refind/main.c @@ -127,7 +127,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0.5"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0.6"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith"); diff --git a/refind/screen.c b/refind/screen.c index 2ac7ceb..b24e6f5 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -100,6 +100,7 @@ VOID InitScreen(VOID) AllowGraphicsMode = TRUE; } else { AllowGraphicsMode = FALSE; + egSetTextMode(GlobalConfig.RequestedTextMode); egSetGraphicsModeEnabled(FALSE); // just to be sure we are in text mode } GraphicsScreenDirty = TRUE; @@ -125,27 +126,34 @@ VOID SetupScreen(VOID) { UINTN NewWidth, NewHeight; + // Convert mode number to horizontal & vertical resolution values + if ((GlobalConfig.RequestedScreenWidth > 0) && (GlobalConfig.RequestedScreenHeight == 0)) + egGetResFromMode(&(GlobalConfig.RequestedScreenWidth), &(GlobalConfig.RequestedScreenHeight)); + + // Set the believed-to-be current resolution to the LOWER of the current + // believed-to-be resolution and the requested resolution. This is done to + // enable setting a lower-than-default resolution. if ((GlobalConfig.RequestedScreenWidth > 0) && (GlobalConfig.RequestedScreenHeight > 0)) { UGAWidth = (UGAWidth < GlobalConfig.RequestedScreenWidth) ? UGAWidth : GlobalConfig.RequestedScreenWidth; UGAHeight = (UGAHeight < GlobalConfig.RequestedScreenHeight) ? UGAHeight : GlobalConfig.RequestedScreenHeight; } + + // Set text mode. If this requires increasing the size of the graphics mode, do so. if (egSetTextMode(GlobalConfig.RequestedTextMode)) { egGetScreenSize(&NewWidth, &NewHeight); if ((NewWidth > UGAWidth) || (NewHeight > UGAHeight)) { UGAWidth = NewWidth; UGAHeight = NewHeight; } - if (UGAWidth > GlobalConfig.RequestedScreenWidth) { + if ((UGAWidth > GlobalConfig.RequestedScreenWidth) || (UGAHeight > GlobalConfig.RequestedScreenHeight)) { // Requested text mode forces us to use a bigger graphics mode - // TODO: Convert single mode # to width & height to check it GlobalConfig.RequestedScreenWidth = UGAWidth; GlobalConfig.RequestedScreenHeight = UGAHeight; } // if } if (GlobalConfig.RequestedScreenWidth > 0) { - if (!egSetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight)) - Print(L"Error setting screen size!\n"); + egSetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight); egGetScreenSize(&UGAWidth, &UGAHeight); } // if user requested a particular screen resolution @@ -164,7 +172,7 @@ VOID SetupScreen(VOID) VOID SwitchToText(IN BOOLEAN CursorEnabled) { - egSetGraphicsModeEnabled(FALSE); + egSetGraphicsModeEnabled(FALSE); refit_call2_wrapper(ST->ConOut->EnableCursor, ST->ConOut, CursorEnabled); // get size of text console if (refit_call4_wrapper(ST->ConOut->QueryMode, ST->ConOut, ST->ConOut->Mode->Mode, &ConWidth, &ConHeight) != EFI_SUCCESS) {