I would like to share the line of action i use to investigate and (hopefully) repair broken UEFI boot scenarios (It may even serve to manually install GRUB2 for UEFI boot).
Please be aware:
- I use openSUSE 42.3 on UEFI-based machines with GRUB2 as bootloader.
- “secureboot” is always disabled.
- The UEFI is set to boot in UEFI-mode (no “Compatibility Support Mode (CSM)” aka “Legacy mode” or “MBR mode”).
- All disks have a GPT partition scheme and ext4 as file system.
- RAID or LVM are not used.
- There are no separat boot partition or any encrypted system/swap partition(s).
If your setup is different the following might probably be of no use to you.
The UEFI specification offers some freedom to vendors on how to implement an UEFI (and there even might be faulty UEFI implementations). So some UEFI specific stuff mentioned below may not work with your UEFI (it might be worth to check your motherboard vendors website for the latest UEFI version).
Before you start:
Your system may become completely unusable if you follow the guidelines below! Make sure you have a working and up to date backup of all your data.
When your system does not boot any more the openSUSE-Installation-media (DVD/USB stick) can be used to repair the broken boot scenario:
- Make sure your UEFI is set up to boot in UEFI-mode.
- Make sure “secureboot” and “FastBoot” are disabled in your UEFI.
- Boot the openSUSE installation media [01] (DVD/USB stick).
Make sure it really started in UEFI mode; i.e at the bottom of the very first screen there is NO options menu (F1, F2, …) displayed. If there is an options menu the media booted in CSM (legacy mode / MBR mode). - Select “More …” and then “Rescue system”. This will give you a working command-line-only system.
- Log in as “root” (no password needed).
- It’s high time to make sure you have a backup of your data.
# od -An -t u1 /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data
0
#
This will check the “secureboot”-status of your UEFI. If the result is not equal “0” then you still need to disable “secureboot” in your UEFI (or your UEFI returns invalid values). In case the command fails completely make sure you booted in UEFI-mode.
- The UEFI spec allows for more than one UEFI system partition. If you plan to (re)install GRUB2 you can use any EFI system partition available on your system (as long as it has enough free space to hold the openSUSE GRUB2 bootloader files) or - if you have some spare disk space available (min. 128 MB; better 500 MB) - you may even create a new EFI system partition (Type 0xEF00; file system FAT32).
# blkid | grep EFI
Will help you to find the EFI system partition(s) available on your system. If you want to use a specific one (e.g. the one that was used in a once working boot scenario) and are not sure about which it is you can inspect each in order to determine which is the one you are looking for.
- Mount the EFI system partitions one by one. Use “blkid” to get the proper value(s) for “sdxz”.
# mount /dev/sdxz /mnt
If you already had a working boot scenario you can now look for a file “/mnt/efi/opensuse/grubx64.efi”. If you can’t find that file check the other EFI system partitions. If there aren’t any other EFI system partitions you need to reinstall GRUB2 as described later on.
- “grubx64.efi” is the booatloader which needs to know where to find the system it is supposed to boot. This knowledge will either be build into “grubx64.efi” when it gets installed or there is a file “/mnt/efi/opensuse/grub.cfg”.
# cat /mnt/efi/opensuse/grub.cfg
search --fs-uuid --set=root a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6
set prefix=(${root})/boot/grub2
configfile $prefix/grub.cfg
Make sure that “a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6” fits the UUID of the partition which hosts the root file system of the system you want to boot. Use “blkid” to get the UUID of your openSUSE root file system partition.
If “grubx64.efi” was build to boot from a partition that no longer exists (or you just don’t want to boot from any longer) then you need to reinstall GRUB2 as described later on.
# umount /mnt
Finaly unmount the EFI system partition you inspected.
- Setup a changeroot environment.
# mount /dev/sdxy /mnt
Mounts your openSUSE root file system partition. Use “blkid” to get the proper value for “sdxy”.
# mount /dev/sdxz /mnt/boot/efi
Mounts your EFI system partition. Use “blkid” to get the proper value for “sdxz”.
# mount -o bind /dev /mnt/dev
# mount -o bind /run /mnt/run
# mount -o bind /sys /mnt/sys
# mount -o bind /proc /mnt/proc
# chroot /mnt
Completes and starts the changeroot environment. From here on all actions take place in the already installed openSUSE system.
# zypper se -si grub2
Check that GRUB2 is installed (that should be the case if there once was a working boot scenario). If no grub2-packages are listed GRUB2 needs to be installed (a working internet connection is needed for this!)
# zypper in grub2
# zypper up grub2
If GRUB2 is already installed this makes sure you have the latest version of the grub2-packages (a working internet connection is needed for this!)
- Check the GRUB2 configuration file
# cat /etc/default/grub | grep "GRUB_USE_LINUXEFI"
GRUB_USE_LINUXEFI="true"
# cat /etc/default/grub | grep "GRUB_DISABLE_OS_PROBER"
GRUB_DISABLE_OS_PROBER="false"
If you do not see the results shown above use an editor (e.g. vi) to change the file “/etc/default/grub”
You may also want to check the “GRUB_CMDLINE_LINUX_DEFAULT=” and “GRUB_CMDLINE_LINUX=” settings in that file. If there is something like “resume=/dev/disk/by-uuid/a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6” make sure that “/dev/disk/by-uuid/a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6” really exists and is the partition you want to use for resume.
# cat /etc/fstab | grep boot
UUID=1234-ABCD /boot/efi vfat umask=0002,utf8=true 0 0
Make sure that “1234-ABCD” fits the UUID of the EFI system partition you want to use. If there is no entry with “/boot/efi” the EFI system partition will not be mounted at system startup so you need to add an entry for the EFI system partition to “/etc/fstab”.
# efibootmgr -v
BootCurrent: 0003
Timeout: 2 seconds
BootOrder: 0003,0005,0001,0000
Boot0000* Win...
Boot0003* opensuse HD(5,GPT,a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6,0xacbe800,0x200000)/File(\EFI\OPENSUSE\GRUBX64.EFI)..BO
Boot0005* Ubu...
This will check the UEFIs NVRAM. If there is no entry (Bootnnnn) for opensuse you need to create one (replace “sdx” with the device that carries the EFI system partition you want to use; in “–part n” replace “n” with the number of this EFI system partition)
# efibootmgr --create --disk /dev/sdx --part n --label "openSUSE" --loader \\EFI\\opensuse\\grubx64.efi
# blkid
will help you to find the correct value for “/dev/sdx” and
# gdisk -l /dev/sdx
will help you to determine “n”
# efibootmgr -b 0004 -B
Changes the bootsequence stored in the UEFIs NVRAM (e.g. make entry “Boot0004” to be the first one in the “BootOrder”)
- If you could not fix the problem so far you can reinstall GRUB2
# grub2-install --target=x86_64-efi
and create a new GRUB2 boot menu
# grub2-mkconfig -o /boot/grub2/grub.cfg
- Leave the changeroot environment
# exit
- Reboot your system
# init 6
Hopefully your system will boot again.
Last but not least a few things worth knowing about UEFI:
- EFI firmware contains knowledge about the partition structure of various devices and can understand legacy MBR, GPT, and “El Torito”. An EFI system partition supports backward compatibility with legacy systems.
- The file system (for EFI system partitions) supported by EFI is based on the FAT file system and includes support for long file names. The EFI firmware must support the FAT32, FAT16, and FAT12 variants of the EFI file system. EFI encompasses the use of FAT32 for a EFI system partition and FAT12 or FAT16 for removable media.
- FAT defines that all files in a directory must have a unique name and unique is defined as a case insensitive match.
- An EFI system partition that is present on a hard disk must contain in the root directory a directory named EFI. All OS loaders and applications will be stored in subdirectories below EFI. The choice of the subdirectory name is up to the vendor, but all vendors must pick names that do not collide with any other vendor’s subdirectory name. This applies to system manufacturers, operating system vendors, BIOS vendors, and third party tool vendors, or any other vendor that wishes to install files on an EFI system partition. There must also only be one executable EFI image for each supported processor architecture in each vendor subdirectory. If more than one executable EFI image is present, then the boot behavior for the system will not be deterministic. There may also be an optional vendor subdirectory called BOOT. This directory contains EFI images that aide in recovery if the boot selections for the software installed on the EFI system partition are ever lost.
- The UEFI boot sequence looks like this:
The boot order list (shown as “BootOrder” by “efibootmgr -v”) is read from the UEFI NVRAM. It holds a list of NVRAM variables (shown as “Boot0000” to “BootFFFF” by “efibootmgr -v”) that contain information about what is to be booted. Modifications to this variable are only guaranteed to take effect after the next platform reset.
Each NVRAM variable (“Boot0000” to “BootFFFF”) contains a pointer to the hardware device and to a file on that hardware device that contains the UEFI image to be loaded. Also it defines a name for the boot option that can be displayed to a user. Furthermore the variable might contain paths to the OS partition and directory along with other configuration specific directories. The UEFI will try to boot the “Bootnnnn” entries in the order given by “BootOrder” until a “Bootnnnn” can be booted successfully. If no “Bootnnnn” could be booted successfully (or no “Bootnnnn” was defined) then the UEFI will try to boot /EFI/BOOT/BOOT.efi".
Some helpful links:
[01] openSUSE install media
http://download.opensuse.org/distribution/openSUSE-current/iso/
[02] GRUB2 Manual
https://www.gnu.org/software/grub/manual/grub/
[03] UEFI specification
http://www.uefi.org/specifications
Regards
susejunky