How to boot load the kernel using EFI stub (efistub) loader?
The commands below are more generic then for kernel version 3.13.0-35 only.
1. Mount the efi partition and copy the kernel files there
$ mount /dev/sda3 /boot/efi
$ mkdir -pv /boot/efi/EFI/ubuntu/
$ cp -uv /boot/vmlinuz-* /boot/initrd.img-* /boot/efi/EFI/ubuntu/ '/boot/vmlinuz-3.13.0-35-generic' -> '/boot/efi/EFI/ubuntu/vmlinuz-3.13.0-35-generic' '/boot/initrd.img-3.13.0-35-generic' -> '/boot/efi/EFI/ubuntu/initrd.img-3.13.0-35-generic'
2. Change the kernel file name
Shorten the kernel file name by removing -generic
because there seems to be a 39 character length path limit and Rename kernel file(s) to end in .efi
, this ensures compatibility with most systems
$ for f in /boot/efi/EFI/ubuntu/vmlinuz-*-generic; do mv -uv -- "$f" "${f//-generic/}.efi"; done '/boot/efi/EFI/ubuntu/vmlinuz-3.13.0-35-generic' -> '/boot/efi/EFI/ubuntu/vmlinuz-3.13.0-35-generic.efi'`
The above name kernel file name shortening is not enough for a dpkg
installed mainline kernel, because for example /EFI/ubuntu/vmlinuz-3.16.0-031600rc6.efi
without -generic
is still 40 characters long.
3. Add new entry to EFI boot menu
Replace 3.13.0-35
in this example with your specific kernel version
$ kv=3.13.0-35;efibootmgr -c -p 3 -L $kv -l \EFI\ubuntu\vmlinuz-$kv.efi -u root=/dev/sda1 initrd=\\EFI\\ubuntu\\initrd.img-$kv-generic ro rootfstype=ext4 debug ignore_loglevel libata.force=dump_id crashkernel=384M-:128M
This new boot menu entry will become your default new boot choice.
You might not need the extra debugging parameters debug
, ignore_loglevel
, libata.force=dump_id
and crashkernel=384M-:128M
. Initrd
must be present, otherwise boot hangs at "Switched to clocksource tsc." because the root device sda1 cannot be opened.
According to the Debian wiki, this can be done in a few simple steps that will survive a kernel update.
Note: this assumes that you have an EFI partition mounted at /boot/efi
.
Create
/etc/kernel/postinst.d/zz-update-efistub
with the following contents:#!/bin/sh cp /vmlinuz /initrd.img /boot/efi/EFI/ubuntu/
This is a hook that will be ran on kernel update to copy the latest kernel image and initrd to the appropriate location. Then make it executable and run it:
sudo chmod +x /etc/kernel/postinst.d/zz-update-efistub sudo /etc/kernel/postinst.d/zz-update-efistub
Add the boot entry:
sudo efibootmgr -c -d /dev/sdb -p 1 -L "Ubuntu (efistub)" -l /EFI/ubuntu/vmlinuz -u "root=/dev/sdb2 rw initrd=/EFI/ubuntu/initrd.img quiet splash"
Don't forget to change the
-d
and-p
arguments depending on where your EFI system partition is. In my case, it is /dev/sdb1, but this is likely to be different for you. You will probably also have to change theroot=
value in the kernel cmdline to your root partition.(You can change the label to anything you want by changing the
-L
parameter.)The boot entry you just added will become the default entry. And it won't break after a kernel update, since the hook will make sure
vmlinuz
andinitrd.img
are always updated.