Recover UEFI boot after removing all the kernels

So I recently made a mistake while cleaning old kernel files. Put my lesson in short: always think twice while you use rm -rf with some regular expressions...

Anyways, the catastrophic situation I got into was all the kernels been removed and the machine cannot boot into linux any more. So the following is what I did.

Recreate the UEFI boot entry
  1. Get a live usb (or live cd) of your preference. (In my case, OpenSUSE, and btw, the SUSE Studio Imagewriter is a great tool for making your liveusb.)

  2. Boot with the live usb, and log in the rescue mode.

  3. For modern linux distros, the live system usually ships the efibootmgr tool. Use it to rebuild the efi boot entry. In my case, the old efi files are still there, what I need to do is to tell the system where and what are them. To show the current available efi entries:

    $ efibootmgr
    BootCurrent: 0003
    Timeout: 0 seconds
    BootOrder: 0003,0000,2003,2001,2002
    Boot0000* usb
    Boot0001* UEFI Onboard LAN IPv4
    Boot0002* UEFI Onboard LAN IPv6
    Boot0003* Windows Boot Manager
    Boot2001* EFI USB Device
    Boot2002* EFI DVD/CDROM
    Boot2003* EFI Network

    In my original case, the opensuse entry was missing and I want to create it. First, I need to check the OS's official site/forum to find out where its efi files were stored. For example, OpenSUSE stores its efi files at \EFI\opensuse\grubx64.efi.snote that it follows the windows path convention.

    Then I may create an efi entry pointing to this file. For example, I created a new entry named "opensuse" with the following command (my efi partition is /dev/sda1):

    $ efibootmgr -c -d /dev/sda -p 1 -L "opensuse" -l "\EFI\boot\grubx64.efi"
    BootCurrent: 0003
    Timeout: 0 seconds
    BootOrder: 0004,0003,0000,2003,2001,2002
    Boot0000* usb
    Boot0001* UEFI Onboard LAN IPv4
    Boot0002* UEFI Onboard LAN IPv6
    Boot0003* Windows Boot Manager
    Boot0004* opensuse
    Boot2001* EFI USB Device
    Boot2002* EFI DVD/CDROM
    Boot2003* EFI Network
    Boot0006* opensuse_test
    Here, -c means create; -d specifies the disk and -p the partition number of your EFI partition, you can use fdisk -l to find it out; -L specifies the label name of your new entry; -l specifies the loading path of your efi file. And you can see a new entry with number Boot0004 and named opensuse is created.

    If you made some mistake about the new entry and wanna remove it, you can do the following:

    $ efibootmgr -B -b 0004 
    Here, -B indicates you want to delete an entry; -b xxxx gives the hex number of the entry.

Reinstall the kernels
  1. Now my system knows how to boot into OpenSUSE, but it still won't work because I have removed all the kernel files. So the next thing I need to do is to install a workable kernel. Again, use the liveusb stick to boot into the rescue mode. Then find out the partition where my system is in.

    $ fdisk -l
    Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disklabel type: gpt
    Disk identifier: 0FFBB67A-3A2F-4785-B625-63B9FD9AC128
    Device         Start       End   Sectors   Size Type
    /dev/sda1       2048   1026047   1024000   500M EFI System
    /dev/sda2    1026048   1107967     81920    40M unknown
    /dev/sda3    1107968   1370111    262144   128M Microsoft reserved
    /dev/sda4    1370112   2906111   1536000   750M Windows recovery environment
    /dev/sda5    2906112 317474875 314568764   150G Microsoft basic data
    /dev/sda6  958023680 976771119  18747440     9G Windows recovery environment
    /dev/sda7  317474876 321669495   4194620     2G Microsoft basic data
    /dev/sda8  321671168 395071487  73400320    35G Microsoft basic data
    /dev/sda9  395071488 958023679 562952192 268.4G Microsoft basic data
    In my case, /dev/sda8 is my boot partition.

  2. Mount the boot partition.

    $ mount /dev/sda8 /mnt
    $ mount --bind /dev /mnt/dev
    $ mount --bind /sys /mnt/sys
    $ mount --bind /proc /mnt/proc
    $ chroot /mnt

  3. Reinstall the kernels

    zypper in kernel-desktop-3.16.7

  4. Umount the system and reboot

    $ exit
    $ umount /mnt/proc
    $ umount /mnt/sys
    $ umount /mnt/dev
    $ umount /mnt
    If you run into any problems umounting the partition, usually it's because some files on the partition are still in use. Use lsof to find out what are the files in use, then use fuser to find out the pids of programs that are using these files, then kill them and try umount again.

  5. Restart the system and hooray.