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

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

我以 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)。执行此操作需要哪些确切的终端命令?

答案1

以下命令仅适用于内核版本 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_loglevel和。必须存在,否则启动会挂起在libata.force=dump_idcrashkernel=384M-:128MInitrd切换到时钟源 tsc。“因为无法打开根设备sda1。

答案2

根据Debian 维基,只需几个简单的步骤即可完成内核更新后仍可继续使用

注意:这假设您已在 上安装了一个 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=内核命令行中的值更改为根分区。

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

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

相关内容