如何使用EFI存根(efistub)加载程序引导加载内核?


14

我有以UEFI模式运行的Ubuntu 14.04,仅作为操作系统,此处没有双引导。内核版本为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存根加载器”功能。

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

Answers:


14

下面的命令比仅内核版本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安装的主线内核是不够的,因为例如/EFI/ubuntu/vmlinuz-3.16.0-031600rc6.efi-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-:128MInitrd必须存在,否则引导挂起在“ Switched to clocksource tsc。 ”处,因为无法打开根设备sda1。


我不知道你是怎么想的,但你真是太神奇了。令人惊讶的是,几乎没有关于此整洁功能的文档。
2015年

如果它对您不起作用,请尝试将-l和的参数-u放在双引号中(或手动转义反斜杠)。您可以efibootmgr -v在将新条目添加到EFI引导菜单之后执行,以测试这是否是问题。另外,如果您的计算机具有多个磁盘(例如SSD和HDD),那么您需要指定一个磁盘,-d其默认值为/dev/sda(请参见man efibootmgr
Peeyush Kushwaha

5

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

注意:这假定您在处安装了EFI分区/boot/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,但这对您来说可能有所不同。您可能还必须root=将内核cmdline中的值更改为您的根分区。

    (您可以通过更改-L参数将标签更改为所需的任何标签。)

    您刚刚添加的引导条目将成为默认条目。并且在内核更新后它不会中断,因为该钩子可以确保vmlinuz并且initrd.img总是被更新。


任何使它与安全启动一起工作的方法,因为在我的HP笔记本电脑上尝试此操作时,它会给出安全启动错误(当然,我也可以禁用安全启动)
Suici Doga

看来您必须首先使用cryptboot和一些工具来对内核进行签名。尤其是在您不使用Arch的情况下,这有点麻烦(因为没有现成的工具),因此我只禁用安全启动。
莱奥林

如何复制.signed内核?
Suici Doga,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.