如何在 ubuntu 20.04 中用引导加载程序“systemd-boot”替换 grub?

naz*_*ive 8 uefi

ubuntu@ubuntu:~$ lsblk -po NAME,SIZE,TYPE,FSTYPE,PARTLABEL\nNAME          SIZE TYPE FSTYPE   PARTLABEL\n/dev/loop0    1.9G loop squashfs \n/dev/loop1   27.1M loop squashfs \n/dev/loop2     55M loop squashfs \n/dev/loop3  240.8M loop squashfs \n/dev/loop4   62.1M loop squashfs \n/dev/loop5   49.8M loop squashfs \n/dev/sda    465.8G disk          \n\xe2\x94\x9c\xe2\x94\x80/dev/sda1   292M part vfat     CLR_BOOT\n\xe2\x94\x9c\xe2\x94\x80/dev/sda2   512M part swap     CLR_SWAP\n\xe2\x94\x9c\xe2\x94\x80/dev/sda3 108.6G part ext4     CLR_ROOT\n\xe2\x94\x9c\xe2\x94\x80/dev/sda4    16M part          Microsoft reserved partition\n\xe2\x94\x9c\xe2\x94\x80/dev/sda5    79G part ntfs     Basic data partition\n\xe2\x94\x94\xe2\x94\x80/dev/sda6 277.4G part ntfs     Basic data partition\n/dev/sdb     30.2G disk iso9660  \n\xe2\x94\x9c\xe2\x94\x80/dev/sdb1   2.5G part iso9660  \n\xe2\x94\x9c\xe2\x94\x80/dev/sdb2   3.9M part vfat     \n\xe2\x94\x94\xe2\x94\x80/dev/sdb3  27.7G part ext4     \n/dev/sr0     1024M rom           \nubuntu@ubuntu:~$ \n
Run Code Online (Sandbox Code Playgroud)\n

naz*_*ive 6

遵循本指南后:

\n
# Everything in this tutorial should be done as root:\nsudo -i\n\n# Now hop on into the EFI partition root.\ncd /boot/efi\n\n# Configuration files will go here:\nmkdir -p loader/entries\n\n# And kernels will go here:\nmkdir ubuntu\n
Run Code Online (Sandbox Code Playgroud)\n

将以下内容放入/boot/efi/loader/loader.conf(将超时值更改为您满意的值)

\n
default ubuntu\ntimeout 1\neditor 0\n
Run Code Online (Sandbox Code Playgroud)\n

将以下内容放入/etc/kernel/postinst.d/zz-update-systemd-boot\n确保更改 CHANGEME。

\n
#!/bin/bash\n#\n# This is a simple kernel hook to populate the systemd-boot entries\n# whenever kernels are added or removed.\n#\n       \n# The UUID of your disk.\nUUID="CHANGEME"\n\n# The LUKS volume slug you want to use, which will result in the\n# partition being mounted to /dev/mapper/CHANGEME.\nVOLUME="CHANGEME"\n\n# Any rootflags you wish to set.\nROOTFLAGS="CHANGEME"    \n\n# Our kernels.\nKERNELS=()\nFIND="find /boot -maxdepth 1 -name \'vmlinuz-*\' -type f -print0 | sort -rz"\nwhile IFS= read -r -u3 -d $\'\\0\' LINE; do\n    KERNEL=$(basename "${LINE}")\n    KERNELS+=("${KERNEL:8}")\ndone 3< <(eval "${FIND}")\n\n# There has to be at least one kernel.\nif [ ${#KERNELS[@]} -lt 1 ]; then\n    echo -e "\\e[2msystemd-boot\\e[0m \\e[1;31mNo kernels found.\\e[0m"\n    exit 1\nfi\n       \n# Perform a nuclear clean to ensure everything is always in perfect\n# sync.\nrm /boot/efi/loader/entries/*.conf\nrm -rf /boot/efi/ubuntu\nmkdir /boot/efi/ubuntu\n      \n# Copy the latest kernel files to a consistent place so we can keep\n# using the same loader configuration.\nLATEST="${KERNELS[@]:0:1}"\necho -e "\\e[2msystemd-boot\\e[0m \\e[1;32m${LATEST}\\e[0m"\nfor FILE in config initrd.img System.map vmlinuz; do\n    cp "/boot/${FILE}-${LATEST}" "/boot/efi/ubuntu/${FILE}"\n    cat << EOF > /boot/efi/loader/entries/ubuntu.conf\ntitle   Ubuntu GNOME\nlinux   /ubuntu/vmlinuz\ninitrd  /ubuntu/initrd.img\noptions cryptdevice=UUID=${UUID}:${VOLUME} root=/dev/mapper/${VOLUME} ro rootflags=${ROOTFLAGS}\nEOF\ndone\n    \n# Copy any legacy kernels over too, but maintain their version-based\n# names to avoid collisions.\nif [ ${#KERNELS[@]} -gt 1 ]; then\n    LEGACY=("${KERNELS[@]:1}")\n    for VERSION in "${LEGACY[@]}"; do\n        echo -e "\\e[2msystemd-boot\\e[0m \\e[1;32m${VERSION}\\e[0m"\n        for FILE in config initrd.img System.map vmlinuz; do\n            cp "/boot/${FILE}-${VERSION}" "/boot/efi/ubuntu/${FILE}-${VERSION}"\n            cat << EOF > /boot/efi/loader/entries/ubuntu-${VERSION}.conf\ntitle   Ubuntu GNOME ${VERSION}\nlinux   /ubuntu/vmlinuz-${VERSION}\ninitrd  /ubuntu/initrd.img-${VERSION}\noptions cryptdevice=UUID=${UUID}:${VOLUME} root=/dev/mapper/${VOLUME} ro rootflags=${ROOTFLAGS}\nEOF\n        done\n    done\nfi\n\n# Success!\nexit 0\n
Run Code Online (Sandbox Code Playgroud)\n

如果您的设置很简单,您可以不使用任何 ROOTFLAGS 和 VOLUME,并且脚本中的相应行可能如下所示:options root=UUID=${UUID} ro

\n

注意权限:

\n
chown root: /etc/kernel/postinst.d/zz-update-systemd-boot\nchmod 0755 /etc/kernel/postinst.d/zz-update-systemd-boot\ncd /etc/kernel/postrm.d/ && ln -s ../postinst.d/zz-update-systemd-boot zz-update-systemd-boot\n[ -d "/etc/initramfs/post-update.d" ] || mkdir -p /etc/initramfs/post-update.d\ncd /etc/initramfs/post-update.d/ && ln -s ../../kernel/postinst.d/zz-update-systemd-boot zz-update-systemd-boot\n
Run Code Online (Sandbox Code Playgroud)\n

然后你/boot/efi/loader/entries/ubuntu.conf应该看起来像这样(显然,你需要更改 UUID):

\n
title   Ubuntu GNOME\nlinux   /ubuntu/vmlinuz\ninitrd  /ubuntu/initrd.img\noptions root=UUID=81c4bc1c-1a7e-4822-acae-220bbe572240 ro\n
Run Code Online (Sandbox Code Playgroud)\n

查看 UUID

\n
ubuntu@ubuntu:~$ lsblk -f\n名称 FSTYPE 标签 UUID FSAVAIL FSUSE% MOUNTPOINT\nloop0 squashfs 0 100% /rofs\nloop1 squashfs 0 100% /snap/snapd/7264\nloop2 squashfs 0 100% /snap/core18/1705 \nloop3 壁球 0 100% /snap/gnome-3-34-1804/24\nloop4 壁球 0 100% /snap/gtk-common-themes/1\nloop5 壁球 0 100% /snap/snap-store/433\nsda \n\xe2\x94\x9c\xe2\x94\x80sda1 vfat 1A74-A270 113.2M 61% /media/ubuntu/1A74-A270\n\xe2\x94\x9c\xe2\x94\x80sda2 交换 10842320-1286-413f -bf08-3e0ca76bcf2f [交换]\n\xe2\x94\x9c\xe2\x94\x80sda3 ext4 81c4bc1c-1a7e-4822-acae-220bbe572240 87.6G 13% /media/ubuntu/81c4bc1c-1a\n\xe2\x94\ x9c\xe2\x94\x80sda4\n\xe2\x94\x9c\xe2\x94\x80sda5 ntfs 80D47B63D47B59FC\n\xe2\x94\x94\xe2\x94\x80sda6 ntfs router_data 4416017316016770 \nsdb 是o9660 Ubuntu 20.04 LTS amd64 2020-04 -23-07-51-42-00 \n\xe2\x94\x9c\xe2\x94\x80sdb1 iso9660 Ubuntu 20.04 LTS amd64 2020-04-23-07-51-42-00 0 100% /cdrom\n\ xe2\x94\x9c\xe2\x94\x80sdb2 vfat 1AC3-20ED \n\xe2\x94\x94\xe2\x94\x80sdb3 ext4 writable b8474e17-164a-4fb3-94ff-d4e68f2e1548 25.7G 0% /var/crash\nsr0
\n

查找当前的内核并重新安装它以触发您刚刚创建的挂钩:sudo apt install --reinstall linux-image-5.13.0-22-generic

\n

实际安装 systemd-boot\n对于大多数人来说,安装由一个命令组成:

\n

同样,这应该转到 EFI 分区:

\n
bootctl install --path=/boot/efi\n
Run Code Online (Sandbox Code Playgroud)\n

要验证系统 \xe2\x80\x94 上安装的引导加载程序及其顺序 \xe2\x80\x94,请运行:

\n
efibootmgr\n\nreboot\n
Run Code Online (Sandbox Code Playgroud)\n

一旦一切正常,您就可以删除系统中 grub 的存在

\n
# Purge the packages.\napt-get purge grub*\n\n# Purge any obsolete dependencies.\napt-get autoremove --purge\n
Run Code Online (Sandbox Code Playgroud)\n