Gentoo GRUB

GRUB是一个多启动 第二启动加载器 multiboot secondary bootloader ,用于在系统架构的不同文件系统中加载内核。GRUB支持PC BIOS, PC EFI, IEEE 1275(Open Firmware), SPARC 以及 MIPS Lemote Yeeloong。

GRUB也就是 GRUB 2 替代了早期的 GRUB Legancy (GRUB 1),提供了完全独立的代码,带来新的类似shell的语法用于高级脚本。

安装GRUB软件包

make.confGRUB_PLATFORMS 变量控制了 grub-install 安装目标。 amd64 架构包含了可以用于大多数西欧图能够的默认profile。(见下文)

  • 以下配置案例针对 EMI EFIPC 平台(BIOS):

针对 EMI EFIPC 平台的配置 /etc/portage/make.conf
GRUB_PLATFORMS="emu efi-32 efi-64 pc"

我的系统是 在MacBook Pro上安装Gentoo Linux 所以只需要支持EFI,配置 /etc/portage/make.conf 支持 EFI 64位:

MacBook Air/Pro 只需要平台的配置 /etc/portage/make.conf
GRUB_PLATFORMS="efi-64"

USE flags

一些有用的参数:

  • device-mapper 通过 sys-fs/lvm2 支持 device-mapper

  • doc 添加附加文档

  • efiemu 编译安装 efiemu 运行时

  • fonts 编译安装用于gfxterm模块的字体

  • libzfs 支持 sys-fs/zfs

  • mount 编译和安装 grub-mount 工具

  • ...

比较重要的是 device-mapperlibzfs ,后续可以在相应环境中实践

Gentoo emerge

  • emerge 使用 --newuse --deep 以便能够在修改 Gentoo make.conf 配置参数之后重新构建:

emerge 使用 --newuse --deep 参数安装grub
emerge --ask --newuse --deep sys-boot/grub

附件软件

os-prober

os-prober 工具能够帮助检测系统中的其他操作系统,并且在 grub-mkconfig 命令运行时自动生成GRUB配置,对于多启动系统非常方便:

安装 os-prober 帮助检测系统中其他OS
emerge --ask --newuse sys-boot/os-prober

备注

由于安全原因, os-prober 默认禁用。在 /etc/default/grub 配置中添加 GRUB_DISABLE_OS_PROBER=false 来激活

libisoburn

grub-mkrescue 工具需要 dev-libs/libisoburn 支持,如果需要可以安装:

安装 libisoburn 支持 grub-mkrescue 工具
emerge --ask dev-libs/libisoburn

mdadm

对于支持检测RAID设备,则需要安装 sys-fs/mdadm :

安装 sys-fs/mdadm 支持RAID检测
emerge --ask sys-fs/mdadm

安装GRUB Bootloader

  • UEFI with GPT

  • BIOS with MBR

UEFI with GPT

警告

对于早期的64位系统,例如早期MacBooks(Intel Core 2)以及2010年之前的Windows电脑,实际使用的是32位EFI,此时需要激活 efi-32 来作为32位软件运行,修正GRUB平台。

备注

如果UEFI使用了CSM标准(Compatibility Support Module, 兼容支持模块),那么会让UEFI特性就像BIOS。在firemware设置时,用户接口通常被称为 “传统模式" 或 "兼容模式" 。

UEFI with GPT分区

UEFI系统从一个微软便携执行格式(PE32+标准)的 EFI System Partition(ESP) 分区启动执行文件( .efi 文件)。EFI系统分区可以是任意大小。

警告

对于UEFI GPT启动,系统必须使用一个包含FAT文件系统的独立ESP分区。

在EFI系统分区,只有bootloader的 .efi 文件是必须的。不过,通常在 /boot 挂载目录会包含内核,以及 initramfs (如果需要),以及GRUB配置和支持文件。

备注

EFI系统分区通常挂载为 /boot , /boot/efi 或者 /efi 。这样内核,initramfs以及bootloader支持文件可以存储在独立的分区和文件系统,或者存储在根文件系统自身。但是存储在根文件系统,会要求GRUB访问根文件系统来读取相应文件,有时候是非常难以设置和实现的(例如根文件系统是加密系统)。所以,通常我们采用独立分离的分区和独立文件系统挂载。

我在 在MacBook Pro上安装Gentoo Linux 中(Mabook Air)采用了UEFO with GPT方式分区,注意 EFI分区是fat32格式 :

MBA 13存储: 对SATAe磁盘(128G)分区和格式化
# 初始化磁盘分区表
parted /dev/sda mklabel gpt

# 创建第一个sda1分区,用于EFI启动
parted -a optimal /dev/sda mkpart ESP fat32 0% 256MB
parted /dev/sda set 1 esp on

# 系统分区sda2,分配21GB, XFS
parted -a optimal /dev/sda mkpart primary xfs 256MB 21GB
parted /dev/sda name 2 rootfs

# 完成后检查
parted /dev/sda print

# 分区格式化
mkfs.vfat -F 32 -n efi-boot /dev/sda1
mkfs.xfs -f /dev/sda2

分区挂载配置 /etc/fstab 注意分区文件系统是 vfat :

MacBook Air 13" Early 2014 使用UUID配置 /etc/fstab
/dev/disk/by-uuid/eedcd1d3-6550-483b-9cd8-1bedbbeda28b    /    xfs    defaults,noatime    0 1
/dev/disk/by-uuid/084C-D157    /boot    vfat    defaults,noatime    0 2

为EFI安装GRUB

备注

Gentoo的 amd64 profile已经设置了 GRUB_PLATFORMS 变量,并且 grub-install 通常可以自己获知是否要为EFI安装GRUB,还是要为BIOS with MBR / BIOS with GPT安装GRUB。所以,通常在 /etc/portage/make.conf 配置 GRUB_PLATFORMS 不是必须的。用户通常在 make.conf 设置这个变量是为了匹配他们主机系统,以便 emerge sys-boot/grub 安装更少的文件。

在安装GRUB之前, EFI系统分区 必须已经挂载。如果在 fstab 中已经配置,该分区就可以挂载到相应挂载点。

grub-install 复制GRUB支持文件到 /boot/grub 目录,GRUB的PE32+执行程序到 \EFI\gentoo 目录,命名为 grubx64.efi (如果ESP挂载到 /efi 目录下,那么完整文件路径就是 /efi/EFI/gentoo/grubx64.efi ;对于我的实践,ESP挂载目录是 /boot 目录,完整文件路径是 /boot/EFI/gentoo/grubx64.efi

然后, grub-install 会调用 efibootmgr 加入一个启动入口(我之前在 在MacBook Pro上安装Gentoo Linux 是直接添加内诶和挂载目录)

备注

要使得 grub-install 能够正确调用 efibootmgr ,必须以读写方式挂载 efivarfs pseudo文件系统,然后再使用 grub-install 命令。如果 pseudo-filesystem 被编译成内核模块,则 efivarfs 内核模块必须加载:

  • 检查 efivarfs 内核模块:

检查 efivarfs 内核模块是否加载
lsmod | grep efivarfs

输出类似:

检查 efivarfs 内核模块输出信息
efivarfs               24576  1
  • 检查 efivarfs pseudo文件系统挂载:

检查 efivarfs pseudo文件系统挂载
mount | grep efivarfs

输出类似:

检查 efivarfs pseudo文件系统挂载输出信息
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)

如果ESP挂载在 /boot/efi 目录,则可以不加任何参数直接运行 grub-install :

直接运行 grub-install
grub-install

不过,正如我在 在MacBook Pro上安装Gentoo Linux 实践,我的EFI系统分区是挂载到 /boot 目录的,所以这里会有一个报错,显示找不到EFI目录:

/efi 挂载目录,直接运行 grub-install 会出现报错
Installing for x86_64-efi platform.
grub-install: error: cannot find EFI directory.

只需要通过 --efi-directory 参数传递EFI系统分区挂载的目录参数就可以,例如我的案例是挂载到 /boot 目录,则执行:

EFI系统分区挂载在 /boot 目录,通过 --efi-directory 参数运行 grub-install
grub-install --efi-directory=/boot

如果一切正常,则输出如下:

EFI系统分区挂载在 /boot 目录,通过 --efi-directory 参数运行 grub-install 输出信息
Installing for x86_64-efi platform.
Installation finished. No error reported.

备注

默认情况下,GRUB安装系统的目标平台。但是如果使用了其他系统平台,例如主机是CSM模式启动,也就是EFI采用了BIOS with GPT模拟,则需要采用参数 --target=x86_64-efi 参数,或者 --target=i386-efi (32位UEFI target)

备注

对于可移动介质(例如U盘),需要使用参数 --removable 。此时安装到 \EFI\BOOT 目录下的ESP文件名是 BOOTX64.efi (如果ESP挂载为 /efi 则完整文件路径名是 /efi/EFI/BOOT/BOOTX64.efi )。注意,这个参数仅建议用于移动介质,或者主机使用了有限制的UEFI firmware不支持任意路径名的情况。

BIOS with MBR

现代主机大都支持和使用UEFI,可能在虚拟机中会遇到使用BIOS的情况,待后续补充

BIOS with GPT

GPT/MBR hybrid partitions 情况比较特殊,以后有机会再补充实践

类似Windows双启动案例,也是等有机会再实践

配置GRUB

grub-mkconfig 脚本会自动生成grub配置:

  • 和早期的 GRUB LegacyLILO 不同,通常不需要手工配置GRUB配置

  • grub-mkconfig 会结合使用 /etc/grub.d/* 目录下配置和 /etc/default/grub 配置文件来生成正确的 /boot/grub/grub.cfg (GRUB自身唯一使用的配置文件)

  • 管理员通常只需要调整 /etc/default/grub 配置

执行配置非常简单:

使用 -o 参数指定 grub-mkconfig 输出的配置文件
grub-mkconfig -o /boot/grub/grub.cfg

输出:

输出信息举例
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.6.13-gentoo-dist
Found initrd image: /boot/initramfs-6.6.13-gentoo-dist.img
Found linux image: /boot/vmlinuz-6.6.10-gentoo-x86_64
Found initrd image: /boot/initramfs-6.6.10-gentoo-x86_64.img
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done

生成的 /boot/grub/grub.cfg 配置案例如下:

Gentoo Linux mkconfig 生成配置片段举例
...
menuentry 'Gentoo GNU/Linux' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-83f0651c-4b4c-4dc9-be5d-99e23e227e8e' {
	load_video
	if [ "x$grub_platform" = xefi ]; then
		set gfxpayload=keep
	fi
	insmod gzio
	insmod part_gpt
	insmod fat
	search --no-floppy --fs-uuid --set=root 67E3-17ED
	echo	'Loading Linux 6.6.21-gentoo-dist ...'
	linux	/vmlinuz-6.6.21-gentoo-dist root=UUID=83f0651c-4b4c-4dc9-be5d-99e23e227e8e ro  
	echo	'Loading initial ramdisk ...'
	initrd	/initramfs-6.6.21-gentoo-dist.img
}
...

参考