UEFI machine doesn't boot Ubuntu through NVRAM bootcatalog. How to fix?

9,257

Solution 1

The short answer

You can create a bootx64.efi binary from within the Ubuntu live media with grub-mkimage and write a custom grub.cfg to chainload the loaders you wan't to boot and copy both files to the EFI System Partition (ESP) into the directory \EFI\BOOT\.

If you don't know your way around in the terminal, the script available in the following section of this answer will do this for you. For more details have a look at the Technical details section in The longer answer.

Scripted for your convenience

Regarding this script:

  • Be warned that this script installs the grub-efi-amd64 package where it runs and therefore will break legacy MBR installs. Probably only run it from live media if possible.
  • Preferably you already know the device name of your ESP.
  • You just paste the code below into an open terminal Ctrl+Alt+t and run it Enter.
  • You can cancel scripts and programs in terminal with Crtl+c.
  • Files on the drive that the live media has been booted from are accessable through /isodevice. GUI: Computerisodevice in Nautilus/File Manager.
echo -en "\ec"; \
if [ -e "/boot/efi/EFI" ] && [ $(mount | grep -c "/boot/efi type vfat") -gt 0 ]; then \
    esp=$(mount | grep "/boot/efi type vfat" | sed -e 's/ on.*//'); \
    echo "The following device appears to be mounted as an EFI System Partition: $esp"; \
    read -p "Is that correct \"yes\" or \"no\"? Note, that answering \"no\" will unmount $esp! " correctesp; \
    if [ "$correctesp" == "no" ]; then \
        sudo umount "$esp"; \
    elif [ "x$correctesp" != "xyes" ]; then \
        echo "Invalid input, refusing to do anything."; \
    fi; \
fi; \
if ! [ -e "/boot/efi/EFI" ] && ! [ $(mount | grep -c "/boot/efi type vfat") -gt 0 ]; then \
    echo "Possible EFI System Partitions (ESP) found, but none appear to be mounted:"; \
    sudo blkid -t TYPE="vfat"; \
    read -p "Please enter the device name of your ESP (/dev/sd[a-z][1-9]): " esp; \
    sudo mkdir -p "/boot/efi"; \
    if [ "$(echo $esp | cut -c 1-5)" == "/dev/" ]; then \
        sudo mount "$esp" "/boot/efi"; \
    else \
        echo "Invalid input, refusing to do anything."; \
    fi; \
    sudo mkdir -p "/boot/efi/EFI"; \
    correctesp="yes"; \
fi; \
if [ -e "/boot/efi/EFI" ] && [ $(mount | grep -c "/boot/efi type vfat") -gt 0 ] && [ "$correctesp" == "yes" ]; then \
    project="$HOME/uefi-bootfix"; \
    mkdir -p "$project"; \
    echo "--- Begin installing grub-efi-amd64 package (could throw some dpkg errors) ---"; \
    sudo apt-get install -y grub-efi-amd64; \
    echo "--- End of installing grub-efi-amd64 ---"; \
    echo "--- Installing GRUB EFI image and configuration to ESP ---"; \
    grub-mkimage -o "$project/bootx64.efi" -p "/efi/boot" -O x86_64-efi fat iso9660 part_gpt part_msdos normal boot linux configfile loopback chain efifwsetup efi_gop efi_uga ls search search_label search_fs_uuid search_fs_file exfat ext2 ntfs btrfs hfsplus udf; \
    echo -e "set timeout=3\nmenuentry 'Ubuntu' {\n\tchainloader /efi/ubuntu/grubx64.efi\n}\nmenuentry 'Windows' {\n\tchainloader /efi/Microsoft/Boot/bootmgfw.efi\n}\nmenuentry 'Firmware Setup' {\n\tfwsetup\n}\nmenuentry 'ubuntu-14.04.1-desktop-amd64.iso' {\n\tset isofile="/efi/boot/ubuntu-14.04.1-desktop-amd64.iso"\n\tloopback loop $isofile\n\tlinux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$isofile noprompt noeject quiet splash\n\tinitrd (loop)/casper/initrd.lz\n}" > "$project/grub.cfg"; \
    sudo mkdir -p "/boot/efi/EFI/boot"; \
    if [ -e "/boot/efi/EFI/boot/bootx64.efi" ]; then \
        sudo cp -v "/boot/efi/EFI/boot/bootx64.efi" "/boot/efi/EFI/boot/bootx64_uefi-bootfix-backup-$(date +%F_%H-%M-%S).efi"; \
    fi; \
    sudo cp -v "$project/bootx64.efi" "/boot/efi/EFI/boot/bootx64.efi"; \
    sudo cp -v "$project/grub.cfg" "/boot/efi/EFI/boot/grub.cfg"; \
    echo "--- Done. ---"; \
fi

The longer answer

The problem

The UEFI specification recommends firmware implementers to boot via a default bootloader named \EFI\BOOT\BOOT{arch}.EFI for booting from external media, e.g. where relying on NVRAM entries in the platform – the computers' mainboard – to boot a particular operating system is not possible. Currently defined values for arch are x64 for AMD64, ia32 for i386 and ARM orA64 for ARM.

Windows and Fedora install such a bootloader on the ESP, while Ubuntu currently does not. The firmware in some computers – like budget-priced laptops – shows a behaviour where these devices seem to completly ignore correctly registered UEFI bootloaders in the NVRAM bootcatalog and default to booting from \EFI\BOOT\BOOT{arch}.EFI, which will usually result in booting Windows instead of Ubuntu.

Technical details

This configuration currently doesn't support Secure Boot and also hasn't been tested for Apple computers, as I don't own such a machine. (Help is much appreciated.)

If it hasn't been clear until now: This will also allow booting the OS installations on the disk in another UEFI-capable computer, similar to how it has been with legacy MBR.

Generating the bootx64.efi image with GRUB

grub-mkimage -o bootx64.efi -p /efi/boot -O x86_64-efi fat iso9660 part_gpt part_msdos normal boot linux configfile loopback chain efifwsetup efi_gop efi_uga ls search search_label search_fs_uuid search_fs_file exfat ext2 ntfs btrfs hfsplus udf

Creating a corresponding grub.cfg file

This configuration covers the basic cases of booting Ubuntu, booting Windows and launching the firmware setup. The last entry allows for loop mounting and booting an ISO image, which might look odd at first because the ESP usually is only a few hundred megabytes large and can't store such big files, but both files also work on FAT formatted USB drives. A multiboot USB drive with several ISOs is just a few edits away. Also you could easily replace ubuntu with fedora to create another menu entry that boots Fedora or any other Linux distribution, just have a look at the contents of your ESP.

set timeout=3
menuentry 'Ubuntu' {
    chainloader /efi/ubuntu/grubx64.efi
}
menuentry 'Windows' {
    chainloader /efi/Microsoft/Boot/bootmgfw.efi
}
menuentry 'Firmware Setup' {
    fwsetup
}
menuentry 'ubuntu-14.04.1-desktop-amd64.iso' {
    set isofile="/efi/boot/ubuntu-14.04.1-desktop-amd64.iso"
    loopback loop $isofile
    linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$isofile noprompt noeject quiet splash
    initrd (loop)/casper/initrd.lz
}

Appendix

What about gummiboot and PreLoader?

I have posted something like that in the past and there is nothing wrong with that as far as I can see. It even works with Secure Boot. Good if it worked for you, but the user experience including downloading, creating and extracting several files manually isn't quite optimal and rather difficult for the average user.

Example output

Example output of running the script from live media:

Possible EFI System Partitions (ESP) found, but none appear to be mounted:
/dev/sda1: LABEL="ESP W8" UUID="8AEF-2F66" TYPE="vfat" 
/dev/sdb1: LABEL="ESP HDD" UUID="CBB5-B769" TYPE="vfat" 
/dev/sdc1: LABEL="ESP EVO" UUID="288D-5954" TYPE="vfat" 
/dev/sdd1: LABEL="SANDISK" UUID="B67A-5BFF" TYPE="vfat" 
Please enter the device name of your ESP (/dev/sd[a-z][1-9]): /dev/sdb1
--- Begin installing grub-efi-amd64 package (could throw some dpkg errors) ---
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  efibootmgr grub-efi-amd64-bin
The following packages will be REMOVED:
  grub-gfxpayload-lists grub-pc
The following NEW packages will be installed:
  efibootmgr grub-efi-amd64 grub-efi-amd64-bin
0 upgraded, 3 newly installed, 2 to remove and 0 not upgraded.
Need to get 0 B/722 kB of archives.
After this operation, 2,399 kB of additional disk space will be used.
Preconfiguring packages ...
(Reading database ... 169555 files and directories currently installed.)
Removing grub-gfxpayload-lists (0.6) ...
Removing grub-pc (2.02~beta2-9ubuntu1) ...
Processing triggers for man-db (2.6.7.1-1) ...
Selecting previously unselected package efibootmgr.
(Reading database ... 169536 files and directories currently installed.)
Preparing to unpack .../efibootmgr_0.5.4-7ubuntu1_amd64.deb ...
Unpacking efibootmgr (0.5.4-7ubuntu1) ...
Selecting previously unselected package grub-efi-amd64-bin.
Preparing to unpack .../grub-efi-amd64-bin_2.02~beta2-9ubuntu1_amd64.deb ...
Unpacking grub-efi-amd64-bin (2.02~beta2-9ubuntu1) ...
Selecting previously unselected package grub-efi-amd64.
Preparing to unpack .../grub-efi-amd64_2.02~beta2-9ubuntu1_amd64.deb ...
Unpacking grub-efi-amd64 (2.02~beta2-9ubuntu1) ...
Processing triggers for man-db (2.6.7.1-1) ...
Setting up efibootmgr (0.5.4-7ubuntu1) ...
Setting up grub-efi-amd64-bin (2.02~beta2-9ubuntu1) ...
Setting up grub-efi-amd64 (2.02~beta2-9ubuntu1) ...
Installing for x86_64-efi platform.
grub-install: error: failed to get canonical path of `/cow'.
dpkg: error processing package grub-efi-amd64 (--configure):
 subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
 grub-efi-amd64
E: Sub-process /usr/bin/dpkg returned an error code (1)
--- End of installing grub-efi-amd64 ---
--- Installing GRUB EFI image and configuration to ESP ---
‘/boot/efi/EFI/boot/bootx64.efi’ -> ‘/boot/efi/EFI/boot/bootx64_uefi-bootfix-backup-2014-11-13_22-39-42.efi’
‘/home/ubuntu/uefi-bootfix/bootx64.efi’ -> ‘/boot/efi/EFI/boot/bootx64.efi’
‘/home/ubuntu/uefi-bootfix/grub.cfg’ -> ‘/boot/efi/EFI/boot/grub.cfg’
--- Done. ---

Solution 2

The output of efibootmgr -v shows that /efi/ubuntu/shimx64.efi has been registered as ubuntu. (These new boot entries are usually added with the highest priority.)

An output of efibootmgr would have help determined if the order was correct.

So from my understanding, it is a matter of changing the boot order so that the entry for grub is the default. I had that issue too.

As you can't boot into ubuntu to solve this or do that in the UEFI/BIOS, you can boot a LiveCD of Ubuntu, and drop into a terminal or a console

You open a teminal and run

# sudo -i
# apt-get install efibootmgr
# efibootmgr
BootCurrent: 0003
Timeout: 0 seconds
BootOrder: 0003,0002,0004,2001
Boot0000* UEFI Onboard LAN IPv6
Boot0001* UEFI Onboard LAN IPv4
Boot0002* ubuntu
Boot0003* Windows Boot Manager
Boot0004* Ubuntu
Boot2001* EFI USB Device

and you change the order of the boot entries

# efibootmgr -o 0002,0003,0004,2001

and run again efibootmgr to check the change is effective. it should change the bootnext value too else you can run

# efibootmgr -n 0002
Share:
9,257

Related videos on Youtube

Csabi Vidó
Author by

Csabi Vidó

This is my AskUbuntu profile and most of my stuff here on StackExchange is tech-oriented. However I do have other hobbies and interests, you may find more about these in my other profiles on the network. I'm lwbt on Reddit and Telegram. I started with Ubuntu and Linux somewhere between 2006 and 2007. With the release of 08.04 I completely migrated away from Windows to Ubuntu and while this has been a few years ago I still consider myself fairly new to this topic and I know I can still discover something new and exciting everyday. The following listing is not to brag about hardware, I'm rather trying to reproduce issues and share experience. Custom built desktop computers with Intel HD graphics (dualscreen setup), Lenovo T530 & T560 (touch) without discrete graphics (also run Windows 10), Chromebooks Lenovo N22 & ASUS Flip C302 (with GalliumOS) Behringer FCA610 USB (PulseAudio multichannel configuration), JDS Labs C5D & The Element, Bluetooth dongles and BT audio speakers and headphones Wacom Intuos 4 PTK-540WL HP 3005pr Port Replicator (works with proprietary DisplayLink driver) Aten CS1794 HDMI KVMP Switch Logitech TK820 and some unifying receiver mice …and some APC UPS

Updated on September 18, 2022

Comments

  • Csabi Vidó
    Csabi Vidó almost 2 years

    An answer posted here should:

    • Avoid to require the user to download and install additional packages or PPAs.
    • Be as quick and simple as possbile. (I tried boot-repair and it didn't qualify.)
    • Probably provide a script for users who don't have much experience with the terminal.

    Similar issues like these have been posted several times to the site:

    • A recent release of Ubuntu has been successfully installed on a UEFI-capable machine that came with a preinstalled copy of Windows 8 or later.
      • The output of efibootmgr -v shows that /efi/ubuntu/shimx64.efi has been registered as ubuntu. (These new boot entries are usually added with the highest priority. See also Change boot order using efibootmgr)
      • After rebooting, no OS selection menu (GRUB) was shown and the machine booted directly to Windows.
    • When accessing the firmware settings menu (formerly called BIOS):
      • There is no indication of how to change the boot order for indivual operating systems or there are no operating systems (like Windows Boot Manager) displayed at all, only devices.
      • The Secure Boot feature is turned off in firmware settings.
    • Ubuntu was installed by booting the live media in UEFI mode, not by running the WUBI-Installer in Windows.
    • The Windows installation itself was not modified, replaced or erased.
      • The drive contains a GPT partition table.
      • Windows Diskmanagement shows that at least the following 3 partitions exist on the disk:
        • EFI System Partition
        • Windows partition
        • an unreadable RAW partition that could be the Ubuntu installation
    • You tried removing the \EFI\BOOT\ directory entirely, before(!) backing it up.

    This usually indicates an issue with the default bootloader or bootprocess being somewhat hardcoded to boot Windows. In most cases this can easily be fixed by replacing \EFI\BOOT\BOOTx64.EFI with another file that also allows for booting other operating systems.

    • psusi
      psusi over 9 years
      Have you tried removing the \EFI\BOOT directory entirely?
    • Csabi Vidó
      Csabi Vidó over 9 years
      @psusi I assume that this should be added to the list of criteria. Regarding myself, I said on LP #1366546 that "I don't have access to such a machine currently."
    • Csabi Vidó
      Csabi Vidó about 6 years
      @karel thanks for the heads up. Back in early 2016 I really wanted to clean up some of my uefi post and then I forgot about it. If there is a way salvage the important parts and remove the rest just let my know, I'd be glad to help.
    • karel
      karel about 6 years
      @LiveWireBT I had to delete my original comment about another question being a duplicate of this question. After checking back on that question I saw that the "possible duplicate" question has been answered and the answer that was accepted is different from its possible duplicate so I retracted my close vote there.