Làm cách nào để khởi động tải kernel bằng trình tải EFI stub (efistub)?


14

Tôi có Ubuntu 14.04 chạy ở chế độ UEFI chỉ là hệ điều hành, không có khởi động kép ở đây. Phiên bản kernel là 3.13.0-24-generic. Có một phân vùng EFI. Trong trường hợp này, phân vùng EFI không ở mặc định /dev/sda1/dev/sda3vì tôi thực sự đã chuyển đổi chế độ BIOS sang chế độ EFI . Tôi đã sử dụng grub-efi-amd64gói, mặc dù thực sự tải menu khởi động GRUB từ menu khởi động chương trình cơ sở UEFI (tải khởi động UEFI \EFI\ubuntu\grubx64.efi).

Tôi muốn bỏ qua bước tải menu khởi động kép đó và khởi động nhanh hơn, trực tiếp từ UEFI vào kernel. Các hạt nhân Ubuntu kể từ ngày 12.10 có tính năng "trình tải sơ khai Kernel EFI" .

Tôi biết tôi cần phải sao chép kernel Ubuntu vào phân vùng EFI (có thể đổi tên) và tạo một mục trong menu khởi động UEFI (ví dụ như sử dụng efibootmgr). Những lệnh thiết bị đầu cuối chính xác là cần thiết để làm điều này?

Câu trả lời:


14

Các lệnh dưới đây là chung hơn cho phiên bản kernel 3.13.0-35.

1. Gắn phân vùng efi và sao chép các tập tin kernel ở đó

$ 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. Thay đổi tên tệp kernel

Rút ngắn tên tệp kernel bằng cách xóa -genericdường như có giới hạn đường dẫn dài 39 ký tự và Đổi tên (các) tệp kernel để kết thúc .efi, điều này đảm bảo khả năng tương thích với hầu hết các hệ thống

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

Việc rút ngắn tên tập tin kernel ở trên là không đủ cho kernel mainlinedpkg đã cài đặt , vì ví dụ không có vẫn dài 40 ký tự./EFI/ubuntu/vmlinuz-3.16.0-031600rc6.efi-generic

3. Thêm mục mới vào menu khởi động EFI

Thay thế 3.13.0-35trong ví dụ này bằng phiên bản kernel cụ thể của bạn

$ 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

Mục menu khởi động mới này sẽ trở thành lựa chọn khởi động mới mặc định của bạn.

Bạn có thể không cần các thông số gỡ rối thêm debug, ignore_loglevel, libata.force=dump_idcrashkernel=384M-:128M. Initrdphải có mặt, nếu không boot bị treo ở "Đã chuyển sang clockource tsc. " vì thiết bị gốc sda1 không thể mở được.


Tôi không biết làm thế nào bạn phát hiện ra điều này nhưng bạn thật tuyệt vời. Có tài liệu nhỏ đáng ngạc nhiên xung quanh tính năng gọn gàng này.
dùng3549648

Trong trường hợp nó không hoạt động đối với bạn, hãy cố gắng đặt các đối số -l-utrong dấu ngoặc kép (hoặc thoát dấu gạch chéo ngược thủ công). Bạn có thể kiểm tra xem đây có phải là sự cố không bằng cách thực thi efibootmgr -vsau khi bạn đã thêm mục nhập mới vào menu khởi động EFI. Ngoài ra, trong trường hợp máy của bạn có nhiều đĩa (giả sử là SSD và ổ cứng) thì bạn sẽ cần chỉ định một ổ đĩa theo -dmặc định /dev/sda(xem man efibootmgr)
Peeyush Kushwaha

5

Theo wiki Debian , điều này có thể được thực hiện trong một vài bước đơn giản sẽ tồn tại trong bản cập nhật kernel .

Lưu ý: điều này giả định rằng bạn có phân vùng EFI được gắn tại /boot/efi.

  1. Tạo /etc/kernel/postinst.d/zz-update-efistubvới các nội dung sau:

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

    Đây là một hook sẽ được chạy trên bản cập nhật kernel để sao chép hình ảnh kernel và initrd mới nhất vào vị trí thích hợp. Sau đó làm cho nó thực thi và chạy nó:

    sudo chmod +x /etc/kernel/postinst.d/zz-update-efistub
    sudo /etc/kernel/postinst.d/zz-update-efistub
    
  2. Thêm mục khởi động:

    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"
    

    Đừng quên thay đổi -d-pđối số tùy thuộc vào vị trí phân vùng hệ thống EFI của bạn. Trong trường hợp của tôi, nó là / dev / sdb1, nhưng điều này có thể khác với bạn. Bạn cũng có thể sẽ phải thay đổi root=giá trị trong cmdline kernel thành phân vùng gốc của bạn.

    (Bạn có thể thay đổi nhãn thành bất cứ điều gì bạn muốn bằng cách thay đổi -Ltham số.)

    Mục khởi động bạn vừa thêm sẽ trở thành mục nhập mặc định. Và nó sẽ không bị hỏng sau khi cập nhật kernel, vì hook sẽ đảm bảo vmlinuzinitrd.imgluôn được cập nhật.


Bất kỳ cách nào để làm cho nó hoạt động với khởi động an toàn kể từ trên máy tính xách tay HP của tôi khi tôi thử điều này, nó sẽ gây ra lỗi khởi động an toàn (tất nhiên tôi cũng có thể vô hiệu hóa khởi động an toàn)
Suici Doga

Có vẻ như bạn sẽ phải sử dụng cryptboot và một số công cụ để ký kernel trước . Đó là một chút rắc rối đặc biệt là nếu bạn không sử dụng Arch (vì không có công cụ sẵn sàng sử dụng), vì vậy tôi chỉ cần vô hiệu hóa khởi động an toàn.
Léo Lam

Điều gì về việc sao chép kernel .sign?
Suici Doga
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.