如何使用EFI stub(efistub)加载器启动加载内核?

我把Ubuntu 14.04作为唯一的操作系统在UEFI模式下运行,这里没有双启动。 内核版本是3.13.0-24-generic。 有一个EFI分区。 在这种情况下,EFI分区不是默认的/dev/sda1而是/dev/sda3因为我确实将BIOS模式转换为EFI模式 。 我使用了grub-efi-amd64软件包,但它实际上从UEFI固件启动菜单(UEFI启动加载\EFI\ubuntu\grubx64.efi )加载了GRUB启动菜单。

我想跳过双启动菜单加载步骤,并直接从UEFI启动到内核中。 自12.10以来的Ubuntu内核具有“内核EFI存根加载器”function。

我知道我确实需要将Ubuntu内核复制到EFI分区(可能是重命名)并在UEFI启动菜单中创建一个条目(例如使用efibootmgr )。 这样做需要哪些确切的终端命令?

以下命令仅对内核版本3.13.0-35更通用。

1.挂载efi分区并将核心文件复制到那里

$ 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.更改内核文件名

通过删除-generic缩短内核文件名,因为似乎有39个字符长度的路径限制并且重命名内核文件以.efi ,这确保了与大多数系统的兼容性

 $ 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'` 

对于dpkg安装的主线内核 ,上面的名称内核文件名称缩短是不够的,因为例如没有-generic仍然是40个字符长。

3.向EFI启动菜单添加新条目

将此示例中的3.13.0-35替换为您的特定内核版本

$ 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

这个新的启动菜单项将成为您的默认新启动选项。

您可能不需要额外的调试参数debugignore_loglevellibata.force=dump_idcrashkernel=384M-:128M 必须存在Initrd ,否则引导挂起“ Switched to clocksource tsc。 ”因为根设备sda1无法打开。

根据Debian wiki ,这可以通过几个简单的步骤完成,这些步骤将在内核更新后继续存在

注意:这假设您在/boot/efi上安装了EFI分区。

  1. 使用以下内容创建/etc/kernel/postinst.d/zz-update-efistub

     #!/bin/sh cp /vmlinuz /initrd.img /boot/efi/EFI/ubuntu/ 

    这是一个将在内核更新上运行的钩子,用于将最新的内核映像和initrd复制到适当的位置。 然后使其可执行并运行它:

     sudo chmod +x /etc/kernel/postinst.d/zz-update-efistub sudo /etc/kernel/postinst.d/zz-update-efistub 
  2. 添加启动项:

     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" 

    不要忘记根据EFI系统分区的位置更改-d-p参数。 就我而言,它是/ dev / sdb1,但这对你来说可能有所不同。 您可能还需要将内核cmdline中的root=值更改为根分区。

    (您可以通过更改-L参数将标签更改为您想要的任何内容。)

    您刚添加的启动条目将成为默认条目。 并且在内核更新后它不会中断,因为钩子将确保vmlinuzinitrd.img始终更新。