• Booting openSUSE on UEFI BIOS with ELILO and Grub2 (part II - Windows dual-boot )

    When you install Windows 7 64bit on a blank hard disk in a UEFI sytem, the setup creates 3 partitions:

    • The EFI system partition (ESP):
      A 100MB FAT32 partition, where the bootloaders are stored. Linux creates this partition as well if it doesn't exist, usually in FAT16. Windows7 requires the ESP to be in FAT32 though. In openSUSE, it is possible to change the FAT size from 16 to 32 in the File system Options during setup, and you should do that if you intend to install Windows after Linux.
    • The Microsoft Reserved Partition (MSR):
      A 128 MB partition without partition ID, located between the ESP and the Windows data partition. It doesn't appear in Windows diskmanager but shows up in Linux parted/gparted and in the Windows command line utility diskpart.
    • The Windows data partition for everything, operating system and user data.

    A typical EFI-based Windows 7 installation looks like this in Linux parted and in Windows diskpart:

    Code:
    # parted -l  
    Model: ATA WDC WD5000AAKX-0 (scsi)
    Disk /dev/sda: 500GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    
    Number  Start   End    Size   File system  Name                          Flags
     1      1049kB  106MB  105MB  fat32        EFI system partition          boot
     2      106MB   240MB  134MB               Microsoft reserved partition  msftres
     3      240MB   500GB  500GB  ntfs         Basic data partition
    Code:
    Microsoft DiskPart version 6.1.7601
    Copyright (C) 1999-2008 Microsoft Corporation.
    On computer: EMMA
    
    DISKPART> select disk 0
    
    Disk 0 is now the selected disk.
    
    DISKPART> list partition
    
        Partition ###  Type                Size      Offset
        -------------  ------------------  -------   ----------
        Partition 1    System               100 MB   1024 KB
        Partition 2    Reserved             128 MB    101 MB
        Partition 3    Primary              465 GB    229 MB
    
    DISKPART>
    Notice that the example above illustrates a OEM vanilla Windows 7 and doesn't include a recovery partition (Windows RE), unlike most installations from manufacturers.

    To install Linux on such a computer in order to dual boot with Windows 7, you would defragment and shrink the data partition under Windows first, and either leave the freed space unallocated or alternatively create all the partitions you need for Linux (at least swap, / and /home) but without assigning drive letter or drive path nor formatting the volume. The latter is a safe approach, especially if you are familiar with the Windows disk manager. Then you would boot the Linux DVD (but not Live CD) in UEFI mode and proceed with the installation.

    In some cases – and probably most often – you 'll have to call the BIOS setup every time and assign boot priority to the UEFI CD/DVD device. Otherwise it will boot the UEFI-unaware device and run a traditional MBR setup. This applies to both Windows and Linux.

    If, during Windows or Linux setup, a partition you just created shows up as “logical” or there is a mention anywhere of an extended partition, you are NOT using GUID partitioning scheme but legacy MBR. You should abort the installation at this point if this is not what you want and reboot in UEFI mode (or with the UEFI CD/DVD set as first boot device in UEFI BIOS). In some cases, it might be necessary to blank the MBR or the first track before reinstalling.

    A partition layout for Windows + 3 Linux distros like the one discussed in part I of this tutorial could look like this in Window diskmanager and Linux gparted, respectively:



    sda4 to sda8 are the partitions we intend to use for Linux (openSUSE, Ubuntu and Fedora). You might have created less or more partitions, depending on what you plan to install. But you will usually have at least 3 (sda4 to sd6).

    Notice that all these partitions are "primary". There are no extended and therefore no logical partitions in GUID partition table (GPT).


    Pre-installation backup steps

    Back up protective MBR and GPT

    Before installing Linux, it is highly recommended to save your protective MBR and GUID partition table. You can do it from a Linux live system, such as openSUSE or Ubuntu live CDs with the utility gdisk. Proceed as follows:

    • Install gdisk on the live CD
    - Ubuntu:

    Code:
    $ cd /tmp
    $ wget http://download.opensuse.org/repositories/home:/srs5694/xUbuntu_11.10/amd64/gptfdisk_0.8.1-1_amd64.deb   
    $ sudo dpkg -i  gptfdisk_0.8.1-1_amd64.deb
    - openSUSE:

    Code:
    $ sudo zypper in http://download.opensuse.org/repositories/home:/srs5694/openSUSE_12.1/x86_64/gdisk-0.8.1-77.1.x86_64.rpm
    • Create a backup with sgdisk (in the example below, of the first HD's GPT):
    Code:
    $ sudo /usr/sbin/sgdisk -b sda-backup.gpt /dev/sda
    • Copy the file sda-backup.gpt to another computer or save it on an external medium.

      You can read more info on gdisk author's site: Repairing GPT Disks


    Back up the content of the EFI system partition

    Another advisable precaution is to back up Windows bootloaders in the ESP, usually the first partition.
    Here's how to achieve that from a Linux live system:

    • Back up the ESP.
    Code:
    $ sudo mount -t vfat /dev/sda1  /mnt
    $ sudo tar -C /mnt -cvzf /tmp/esp.tgz EFI
    $ sudo umount /mnt
    • Copy the archive esp.tgz to another computer or save it on an external medium.


    Installation

    Use Create partition setup under openSUSE and select/format/mount the partitions you need in the Expert Partitioner. Mount the EFI boot partition in /boot/efi but DO NOT FORMAT it, even if YaST suggests to do so. You'll have to right click/edit the EFI partition and choose "Do not format partition". For more details about Linux installation, refer to Booting openSUSE on UEFI BIOS with ELILO and Grub2 - part I Linux only multi-booting.

    To install Grub2, either manually or with updateGrub2, proceed as described in the article linked above.

    Chainloading Windows

    updateGrub2 should automatically add an entry to chainload Windows. If you installed Grub2 by other means, you should add it manually, as follows:

    • Get the UUID of the EFI system partition, as in the example below:

    Code:
    # grub2-probe --target=fs_uuid /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
    82cf-1f92
    • Write the following lines at the end of /etc/grub.d/40_custom - replacing the UUID in this example with the one of your ESP - but do NOT delete or change other text in this file.

    Code:
    menuentry "Microsoft Windows x86_64 UEFI-GPT" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid
        insmod chain
        search --fs-uuid --no-floppy --set=root 82cf-1f92 
        chainloader (${root})/efi/Microsoft/Boot/bootmgfw.efi
    }
    Chainloading Linux bootloaders.

    updateGrub2 will detect and add other Linux bootloaders. The chainloader entries are similar to the Windows one, except for the path of the bootloader. Here's an entry to chainload Fedora's Grub from openSUSE:

    Code:
    menuentry "Fedora 16" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid
        insmod chain
        search --fs-uuid --no-floppy --set=root 82cf-1f92
        chainloader (${root})/EFI/fedora/grubx64.efi
    }
    grubx64.efi is the name of Grub2-efi bootloader in openSUSE, Fedora, Ubuntu and probably most others. Currently, updateGrub2 only looks for this bootloader. It won't chainload ELILO or Fedora's Legacy Grub-efi. But you can manually add an entry to chainload ELILO or another bootloader.

    • Look for bootloaders in the EFI system partition:

    Code:
    # find /boot/efi/efi -name "*.efi"
    /boot/efi/efi/Microsoft/Boot/bootmgfw.efi
    /boot/efi/efi/Microsoft/Boot/bootmgr.efi
    /boot/efi/efi/Microsoft/Boot/memtest.efi
    /boot/efi/efi/Boot/bootx64.efi
    /boot/efi/efi/SuSE/elilo.efi
    /boot/efi/efi/opensuse/grubx64.efi
    /boot/efi/efi/opensuse/grub.efi
    /boot/efi/efi/ubuntu/grubx64.efi
    /boot/efi/efi/redhat/grub.efi
    /boot/efi/efi/fedora/grubx64.efi
    • The UUID of the ESP will be the same for all bootloaders, since they are on the same partition - although it is possible to use multiple ESPs.

    Code:
    # grub2-probe --target=fs_uuid /boot/efi/efi/SuSE/elilo.efi
    82cf-1f92
    • Write this entry in /etc/grub.d/40_custom

    Code:
    menuentry "ELILO" {
        insmod part_gpt
        insmod fat
        insmod search_fs_uuid
        insmod chain
        search --fs-uuid --no-floppy --set=root 82cf-1f92
        chainloader (${root})/efi/SuSE/elilo.efi
    }
    Notice that the paths in the EFI System partition (FAT) are case insensitive. Thus "efi/SuSE/elilo.efi" is the same as "EFI/suse/elilo.efi"

    • Refresh Grub menu

    Code:
    # updateGrub2
    • When you reboot, you will see "ELILO" in Grub boot menu.

    Reviving ELILO bootloader

    Alternatively you could also add the ELILO boot entry back in the firmware, as described in part I of this tutorial in section "Troubleshooting". It would allow you to use ELILO if Grub2 fails to boot for some reason. You would just have to call the BIOS setup and give ELILO boot priority. You don't need to reinstall ELILO but only write the boot entry in UEFI BIOS. Here's the command again and the output it produces:

    Code:
    #  efibootmgr --create --gpt --disk /dev/sda --part 1 --write-signature  --label "openSUSE 12.1 (elilo)" --loader "\\efi\\SuSE\\elilo.efi"
    BootCurrent: 0000
    Timeout: 3 seconds
    BootOrder: 0007,0000,0005,0004,0006,0003,0001,0002
    Boot0000* opensuse
    Boot0001* Hard Drive
    Boot0002* Removable Drive
    Boot0003* CD/DVD Drive
    Boot0004* ubuntu
    Boot0005* fedora
    Boot0006* Windows Boot Manager
    Boot0007* openSUSE 12.1 (elilo)
    From now on this machine will boot in ELILO. This is probably not what you want. So you'll have to change the boot order with efibootmgr:

    Code:
    # efibootmgr -o 0,4,5,6,7,3,1,2
    BootCurrent: 0007
    Timeout: 3 seconds
    BootOrder: 0000,0004,0005,0006,0007,0003,0001,0002
    Boot0000* opensuse
    Boot0001* Hard Drive
    Boot0002* Removable Drive
    Boot0003* CD/DVD Drive
    Boot0004* ubuntu
    Boot0005* fedora
    Boot0006* Windows Boot Manager
    Boot0007* openSUSE 12.1 (elilo)
    Or call the UEFI BIOS setup and drag "opensuse" or another one's Grub into the first position or set the boot order with another method your mainboard may use. Notice that we did label the ELILO's boot entry "openSUSE 12.1 (elilo)" in order to tell it from the other.



    Issues and solutions.

    openSUSE

    Occasionally, openSUSE 12.1 (as 11.4 before) overwrites the protective MBR with a hybrid MBR loosely based on the GUID partition table. I read it on Rod Smith's site (Booting from GPT), couldn't believe it, but after I installed openSUSE after Windows a dozen of times, I came to the same conclusion. If this happens, Windows will fail to start, saying that “A recent hardware of software change might be the cause” and recommend to launch “Startup Repair” - which you won't have if you installed Windows yourself.

    A quick look at fdisk output shows the changes made to the MBR:

    • before (protective MBR - desired for GPT ):

    Code:
    # fdisk -l
    WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.
    
    
    Disk /dev/sda: 500.1 GB, 500107862016 bytes
    256 heads, 63 sectors/track, 60563 cylinders, total 976773168 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0xcece46ad
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1               1  4294967295  2147483647+  ee  GPT
    • after (hybrid MBR - inappropriate here):

    Code:
    # fdisk -l
    
    WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.
    
    Disk /dev/sda: 500.1 GB, 500107862016 bytes
    255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x9ea43508
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1               1      206846      103423   ee  GPT
    /dev/sda2          206848      468991      131072   83  Linux
    /dev/sda3          468992   210184191   104857600    7  HPFS/NTFS/exFAT
    /dev/sda4       210184192   214386687     2101248   83  Linux
    You'll have to restore the protective MBR from the backup you made previously using gdisk (Repairing GPT Disks).


    Ubuntu

    Ubuntu 11.10 doesn't seem to convert the ESP to FAT 16 anymore - erasing all the bootloaders it contains - as previous Ubuntu versions did. I don't know why it adds 6 kernel entries for openSUSE, all refering to the desktop kernel, and only one for Fedora. You can edit grub.cfg manually to remove the duplicates. But you would have to do it every time after running update-grub. This is something that needs to be fixed in Ubuntu's os-prober. The added kernel boot entries also use device names and miss the kernel options, so that they might not even boot successfully in all circumstances. This doesn't only affect Grub2 on UEFI systems but on BIOS systems as well. Ubuntu's update-grub doesn't add Windows or other chainload entries. This is a feature I added in updateGrub2.

    To set a background image, install the package desktop-base and write the path of an image of your choice in the variable WALLPAPER in /usr/share/desktop-base/grub_background.sh. Alternatively you may also add the variable GRUB_BACKGROUND in /etc/grub/default. If you do so, you don't need to install desktop-base. Here's mine: http://img827.imageshack.us/img827/6821/ocelot.jpg. If you want to use it, you can

    • download this file

    Code:
    $ sudo wget -O /boot/grub/splash.jpg http://img827.imageshack.us/img827/6821/ocelot.jpg
    • add the following line in /etc/grub/default:
    Code:
    GRUB_BACKGROUND=/boot/grub/splash.jpg
    • and rewrite the menu configuration file:
    Code:
    $ sudo update-grub
    At next boot, you should see a cute cat in the menu's background. Customizing the menu colors is easier if you installed desktop-base by setting COLOR_NORMAL and COLOR_HIGHLIGHT in /usr/share/desktop-base/grub_background.sh. You have to set a black background color if you use a background image. Example:

    Code:
    COLOR_NORMAL=black/black
    COLOR_HIGHLIGHT=white/black
    Fedora

    Fedora's modified Legacy Grub is able to boot UEFI and is installed by default on UEFI systems, although Fedora16 now installs Grub2 on BIOS systems. Whether you keep using grub-efi or decide to install Grub2 on Fedora, you can benefit from updategrub, which is also available for Fedora 16 in OBS. You can add the repo and install the package with these commands:

    Code:
    # wget -O /etc/yum.repos.d  http://download.opensuse.org/repositories/home:/please_try_again:/Fedora/Fedora_16/home:please_try_again:Fedora.repo 
    # yum install updategrub
    Then you can use updategrub to add kernel boot entries (but not chainloaders) to grub-efi's boot menu (/boot/efi/EFI/redhat/grub.conf) and updateGrub2 to install Grub2 and add kernel and chainloader entries to its boot menu, as well as refresh the menu after a kernel update. I'm not sure grub2-efi does that automatically on Fedora, since it is not installed by default.

    To use updateGrub2 on a fresh Fedora, you have to install the package redhat-lsb. updateGrub2 will uninstall grub-efi first since the two packages conflict.


    Relevant links

    Installing Windows to an EFI-Based Computer
    A Description of the Diskpart Command-Line Utility
    Managing EFI Boot Loaders for Linux


    The future of UEFI multi-booting is uncertain. You have certainly heard about Microsoft's UEFI secure boot plans. As of today, dual and multi booting Windows and Linux on UEFI systems is possible and even rather simple. I hope this tutorial will be useful to those wondering how to get it done. However, in my experience with multi-booting all kinds of operating systems on PCs, from OS/2 to the latest Linuxes and Unixes, I have learned that the surest and safest way to multi-boot with Windows is to not boot Windows at all. ymmv.




    Addendum: Legacy or UEFI Windows installation?

    I should add that every time I installed Windows with UEFI on this motherboard (ASUS M5A97) onto a blank hard disk, it always performed an MBR installation, even though I explicitly selected the UEFI DVD device. On the second attempt, using the same hard disk without deleting the partitions beforehand, Windows complained that it couldn't install onto this disk because it contained an MBR. After I deleted the existing partitions within the setup, Windows proceeded with a UEFI installation.

    The two following images show a vanilla Windows OEM installation with MBR and one with UEFI, respectively. You can click on the pictures to view more details.

    Windows 7 - Legacy/MBR standard installation



    Code:
    # fdisk -l
    
    Disk /dev/sda: 120.0 GB, 120034123776 bytes
    255 heads, 63 sectors/track, 14593 cylinders, total 234441648 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0xa089e063
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
    /dev/sda2          206848   234438655   117115904    7  HPFS/NTFS/exFAT
    
    
    # parted -l 
    Model: ATA ADATA SSD S510 1 (scsi)
    Disk /dev/sda: 120GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    
    Number  Start   End    Size   Type     File system  Flags
     1      1049kB  106MB  105MB  primary  ntfs         boot, type=07
     2      106MB   120GB  120GB  primary  ntfs         type=07
    Windows 7 - UEFI/GPT standard installation



    Code:
    # fdisk -l
    
    Disk /dev/sdb: 120.0 GB, 120034123776 bytes
    256 heads, 63 sectors/track, 14536 cylinders, total 234441648 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x9080940a
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1  4294967295  2147483647+  ee  GPT
    
    WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! The util fdisk doesn't support GPT. Use GNU Parted.
    
    # parted -l 
    Model: ATA ADATA SSD S510 1 (scsi)
    Disk /dev/sdb: 120GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt_sync_mbr
    
    Number  Start   End    Size   File system  Name                          Flags
     1      1049kB  106MB  105MB  fat32        EFI system partition          boot
     2      106MB   240MB  134MB               Microsoft reserved partition  msftres
     3      240MB   120GB  120GB  ntfs         Basic data partition
    Notice that in both cases, most installations from manufacturers will also include a Windows Recovery partition (Windows RE).
    Comments 1 Comment
    1. benficus's Avatar
      benficus -
      Hi Angelo,
      thank you for this excellent description of UEFI-Boot (part I and II).
      Please add the ASRock X79 Extreme 4 board to your compatibility list.

      I changed the file 05_menu_color from COLOR_NORMAL="black/black" to COLOR_NORMAL="green/black" ;-)

      After starting Win 7 through grub2-efi the Win Bootmanager came back again and above all even elilo had its revival at the initial Boot-Screen of the board. So, I`m glad having many choices booting Win 7 or Opensuse ;-)

      greetings,
      reiner