介绍
GRUB 2 是 GNU GRUB (GRand Unified Bootloader) 的最新版本。bootloader(引导程序) 是计算机开机时第一个运行的软件程序。它负责加载操作系统内核并把控制权交给操作系统内核(Fedora 下就是 Linux 了)。反过来,内核初始化操作系统的其余部分。
GRUB 2 已经取代了之前的 GRUB (即,0.9x 版本),使 GRUB 成为了 GRUB Legacy 。
从 Fedora 16 开始,GRUB 2 就是 x86 BIOS 系统下默认的引导程序了。对于 BIOS 系统的升级也是默认安装 GRUB 2,但是您完全可以选择跳过配置引导程序。
使用 Grubby 管理内核引导参数
Grubby 可用于更新引导相关的配置文件,我们推荐你使用它更新内核引导参数和设定默认内核。
下面我们简单介绍 grubby
的用法:
- 为单个引导项添加一个内核参数:
# grubby --args=<NEW_PARAMETER> --update-kernel=/boot/vmlinuz-5.11.14-300.fc34.x86_64
- 为单个引导项添加多个内核参数:
# grubby --args="<NEW_PARAMETER1> <NEW_PARAMETER2 <NEW_PARAMETER_n>" --update-kernel=/boot/vmlinuz-5.11.14-300.fc34.x86_64
- 为所有引导项添加内核参数:
# grubby --args=<NEW_PARAMETER> --update-kernel=ALL
- 从当前和以后的所有引导项中删除内核参数:
# grubby --remove-args=<PARAMETER_TO_REMOVE> --update-kernel=ALL
- 设置默认内核:
# grubby --set-default=/boot/vmlinuz-5.11.12-300.fc34.x86_64
更新 GRUB 2 主配置文件
/boot/grub2/grub.cfg
是默认的 GRUB 配置文件。通常来说你不需要去改动这个静态文件,除非你对磁盘进行了更换或并行安装了其他系统。
探测使用中的固件
执行下面的命令:
- 在 UEFI 系统:
# ls -ld /sys/firmware/efi
- 在 BIOS 系统:
# ls -lrt /etc/grub2.cfg
输出的结果即为你使用的固件。
grub2-mkconfig -o /boot/grub2/grub.cfg
将探测其他的操作系统并更新引导选单,这是通过 os-prober
实现的。
修复 GRUB 2
如果你的系统无法引导,尝试进入恢复模式以对引导进行修复,详见 Fedora Docs 的相关文章。
然后,执行下面的命令挂载根分区:
# chroot /mnt/sysimage
重新安装 GRUB 2
GRUB 2 软件包包含了安装引导器和生成 grub.cfg
配置文件的相关脚本。
grub2-install
会在 MBR 安装引导器,引导器的相关文件会储存在 /boot/
目录。
要重装 GRUB 2:
- 了解系统正在使用的固件有那些。 请阅读本章节 了解详情。
- 在 UEFI 系统:
# dnf reinstall shim-* grub-efi-*
- 在 BIOS 系统:
- 查看
/boot/
目录位于哪个分区上:
- 查看
# mount | grep "/boot " /dev/sda4 on /boot type ext4 (rw,relatime,seclabel)
就如上面的例子,目录位于 /dev/sda4
.
- 重新安装引导器:
# grub2-install /dev/sda Installing for i386-pc platform. Installation finished. No error reported.
Appendix
Enabling serial console in GRUB 2
To enable serial console for usage on virtual environments you need to run the following command:
# grubby --args="systemd.journald.forward_to_console=1 console=ttyS0,38400 console=tty1" --update-kernel=/boot/vmlinuz-5.11.16-300.fc34.x86_64 # grubby --set-default=/boot/vmlinuz-5.11.16-300.fc34.x86_64
The first command specifies the baud rate, console forwarding for systemd
, what console to use (tty1
) and on what kernel such changes should be applied. The second command ensures the specified kernel is going to be loaded by default on next reboot.
For instructions on how to enable serial consol in GRUB 2 for baremetal machines, see Using GRUB via a serial line.
In UEFI boot environment, use efi0
instead of --unit=0
. If it does not work, check that your serial port is visible in your UEFI environment, e.g. by running devtree
or dh -p SerialIO
in EFI Shell. See Grub2 UEFI boot and serial console output for more information.
Fixing a damaged GRUB 2 configuration file using a plaintext stub file
On Fedora 34 and later, you can repair a malfunctioning grub.cfg
configuration file by creating a stub file with the following content.
- Discover the Universally Unique Identifier (UUID) for the
/boot/
mount point:
# lsblk --fs NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT sr0 iso9660 Joliet Extension Fedora-WS-Live-34-1-2 2021-04-23-11-17-40-00 0 100% /run/media/jdoe/Fedora-WS-Live-34-1-2 zram0 [SWAP] vda ├─vda1 ext4 1.0 dc29837b-22dc-4469-be85-fc9acf3009fd 699.8M 21% /boot └─vda2 btrfs fedora_localhost-live c58f3698-5587-40f2-b920-64d46c43161d 23.7G 14% /home
The UUID of /boot/
is dc29837b-22dc-4469-be85-fc9acf3009fd
.
- Create a custom grub.cfg file with the following content:
search --no-floppy --fs-uuid --set=dev dc29837b-22dc-4469-be85-fc9acf3009fd set prefix=($dev)/grub2 export $prefix configfile $prefix/grub.cfg
At the end of first line (--set=dev
), there is the UUID value of the /boot/
mount point.
The above example assumes default partitioning, where a separate ext4 file system is mounted at /boot/
. In case of other configurations, you need to insert /boot/
into line 2. For example:
... set prefix=($dev)/boot/grub2 ...
- Move or copy the custom grub.cfg file you created in the previous step to /boot/efi/EFI/fedora/grub.cfg
Setting default entry
Due to grub2-mkconfig
(and os-prober) we cannot predict the order of the entries in /boot/grub2/grub.cfg
, so we set the default by name/title instead.
Open /etc/default/grub
and ensure this line exists:
GRUB_DEFAULT=saved
and ensure this line not exists:
GRUB_SAVEDEFAULT=true
or ensure this line exists:
GRUB_SAVEDEFAULT=false
Apply the change to grub.cfg
by running:
grub2-mkconfig -o /boot/grub2/grub.cfg
Now list all possible menu entries
grep -P "submenu|^menuentry" /boot/grub2/grub.cfg | cut -d "'" -f2
Now set the desired default menu entry
grub2-set-default "<submenu title><menu entry title>"
Verify the default menu entry
grub2-editenv list
If you understand the risks involved and still want to directly modify /boot/grub2/grub.cfg, here's how you can do it:
Edit /boot/grub2/grub.cfg, and change the line
set default="0"
to
set default="5"
深入阅读
http://www.gnu.org/software/grub/manual/grub.html
http://fedoraproject.org/wiki/Features/Grub2
http://fedoraproject.org/wiki/Anaconda/Features/Grub2Migration