GRUB (简体中文)
GRUB , 是下一代 GRand Unified Bootloader, 请不要和 GRUB Legacy 混淆了。它来自下一代 GRUB 研究项目 PUPA,代码全部重写,实现了模块化和增强了移植性。[1].
Contents
前言
简单的说,Boot Loader是电脑启动时运行的第一个程序,它负责装载内核并将控制权转交。内核再初始化操作系统的其它部分。官方所称的 GRUB 是软件的第二版,即 GRUB2,请参考[2].
GRUB 不支持F2FS格式的根目录,所以你需要为/boot
分区单独设置一个支持的文件系统.
BIOS 系统
GUID分区表(GPT)特殊操作
BIOS/GPT配置中,必须使用 BIOS 启动分区。GRUB将core.img
嵌入到这个分区。
安装 GRUB 前,在一个没有文件系统的磁盘上,用 fdisk
或 gdisk
创建一个 +1M
分区,设置为 BIOS boot
类型,在 fdisk
中的类型号是 4
, 在 gdisk
中的类型是 ef02
,在 parted
中是 bios_grub
。此分区可以在磁盘前 2TB 的任何位置。分区建立好后,按下面的命令安装启动管理器。
GPT 后面的空间也可以用作 BIOS 启动分区,但是这会违反 GPT 对齐规范。因为这个分区不会经常访问,所以性能的影响很小。只不过有些分区工具会发出警告。在 fdisk
或 gdisk
中创建一个新分区,从 34 扇区开始,一直到 2047,然后设置类型。为了让其它分区对齐,可以最后再创建此分区。
主引导记录(MBR)特殊操作
一般来说,如果使用兼容 DOS 的分区对齐模式, MBR 512 byte 结束位置和第一个分区之间都有 31KB 的空闲空间。不过,为了提供足够的空间嵌入GRUB的core.img
文件,建议将这个空间设置为 1 到 2 Mib(FS#24103). 建议使用支持 1 MiB分区对齐的分区软件来分区, 因为这样也能满足非512B扇区磁盘分区的需求.
安装
安装 软件包 grub. 如果之前安装过 grub-legacyAUR,安装完成后它会代替grub-legacyAUR.
# grub-install --target=i386-pc /dev/sdx
-
--target=i386-pc
指示grub-install
是为使用BIOS的系统安装. 推荐一直标明这点以防混淆. -
/dev/sdx
是已经完成分区的磁盘,grub 将安装到它上面。
命令会
- 将
grub
安装到 MBR 的启动代码区域 - 填充
/boot/grub
文件夹 - 生成
/boot/grub/i386-pc/core.img
- 如果是 MBR 分区的磁盘,将其嵌入 MBR 后面的 31KB 空间
- 如果是 GPT 分区的磁盘,将其嵌入 BIOS 启动分区中
然后必须生成主配置文件。
详情请参考 grub-install(8) 和 [3]。
如果 /boot
使用 LVM,可以将 GRUB 安装在多个物理磁盘上.
UEFI 系统
检查你是否使用GPT且有ESP分区
要使用 EFI 在某个磁盘上进行启动,就需要使用EFI系统分区(ESP). GPT 倒不是必须的,不过我们还是高度建议使用 GPT,并且这也是本文当前唯一支持的方法.如果你在一个支持 EFI,并且已经有操作系统(Win8/Win10)的电脑上安装 Arch,系统上已经有了ESP.可以通过parted
来列出启动磁盘上的分区表以检查其是否支持GPT和ESP(假设这个启动磁盘是/dev/sda)
# parted /dev/sda print
如果使用 GPT,那么会出现"分区表:GPT".如果使用 EFI,那么会有一个文件系统为vfat的小分区(一般小于512MiB)并且被标志为启动分区.在这个小分区上,应该有一个名为EFI的文件夹.如果这些条件都满足,那么这就是ESP了.注意分区序号,因为之后安装 GRUB 时你需要先挂载这个分区。请将下文中的 esp
替换为对应的分区号。
如果还没有ESP,请参考 EFI System Partition 进行创建。
安装
本节假设您正在 x86_64 上安装 GRUB 系统(x86_64-EFI)。对于 i686 系统,将 x86_64-efi
替换为 i386-efi
。
请确保您在 bash shell 中。
安装 软件包 grub 和 efibootmgr。"GRUB"是引导程序, efibootmgr 创建 GRUB 安装脚本使用的 .efi
启动项。
接下来的步骤安装 GRUB UEFI 程序到 esp/EFI/grub
中, 安装其模块到/boot/grub/x86_64-efi
, 然后将可以启动的 grubx64.efi
到 esp/EFI/grub
.
首先,告诉 GRUB 使用 UEFI,设置启动目录,并设置引导程序ID。挂载 ESP 分区,例如挂载到 /boot
或 /boot/efi
。将下面命令中的 esp_mount
修改为挂载点(通常为 /boot
)
# grub-install --target=x86_64-efi --efi-directory=esp_mount --bootloader-id=grub
--bootloader-id
是启动项中用来识别 GRUB EFI 的标记,请用容易判断的信息。安装程序会在 esp/EFI/
的相同目录创建相同名称的目录用来存放 EFI 二进制启动加载器。
上述安装完成后 GRUB 的主目录将位于 /boot/grub/
。
生成主配置文件
安装后,需要生成置文件 grub.cfg
。配置文件的生成过程受到 /etc/default/grub
和 /etc/grub.d/
下脚本的影响。
如果没有额外配置,自动生成程序会侦测 root 目录。所以请确保系统已经启动或 chroot 进入。
/etc/default/grub
或 /etc/grub.d/
中的配置文件变更后,需要重新生成 grub.cfg
。使用下面命令生成 grub.cfg
:
# grub-mkconfig -o /boot/grub/grub.cfg
默认生成脚本自动为 Arch Linux 创建菜单项,其它系统的配置参考配置段落。
安装 软件包 os-prober 并 挂载 包含其它系统的磁盘,grub-mkconfig 会自动搜索已经安装的其它系统并添加到启动菜单。
默认文件路径是/boot/grub/grub.cfg
, 而不是/boot/grub/i386-pc/grub.cfg
.grub 软件包提供了示例 /boot/grub/grub.cfg
文件,请确保需要的修改都保存在此文件中。
如果是在 chroot 或 systemd-nspawn 容器中执行 grub-mkconfig,可能会报 grub-probe 无法获取 "canonical path of /dev/sdaX" 错误,请尝试使用 arch-chroot。参考 BBS post.
配置
本部分介绍了 /etc/default/grub
文件的配置,更多信息请参考 GRUB/Tips and tricks.
每次修改 /etc/default/grub
后,都需要重新#生成主配置文件.
额外的参数
在 /etc/default/grub
中设置 GRUB_CMDLINE_LINUX
和 GRUB_CMDLINE_LINUX_DEFAULT
变量可以向 Linux 镜像传递额外的参数. 生成普通启动项时,这两个参数的值会合并在一起加入, 对于recovery启动项, 则添加 GRUB_CMDLINE_LINUX
参数的值.
没有必要两者都使用,如果要系统支持休眠后恢复,可以使用GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sdaX quiet"
(sdaX
是交换分区).生成 recovery 启动项时,不会加入 resume 和 quiet 参数; 而其他的普通启动项会包含它们.
grub-mkconfig 默认使用根文件系统的 UUID 要禁用此设置,取消 GRUB_DISABLE_LINUX_UUID=true
前的注释.
你也可以使用GRUB_CMDLINE_LINUX="resume=UUID=uuid-of-swap-partition"
要生成 GRUB recovery启动项,需要在 /etc/default/grub
中将 #GRUB_DISABLE_RECOVERY=true
注释掉.
更多信息请参考Kernel parameters.
多系统启动
使用 /etc/grub.d/40_custom 和 grub-mkconfig 自动生成
添加其他启动项的最好方法是编辑 /etc/grub.d/40_custom
或 /boot/grub/custom.cfg
. 运行grub-mkconfig
后,这些文件中的启动项会被自动添加到 /boot/grub/custom.cfg
中.
更新了这些文件后,运行下面命令更新grub.cfg
:
# grub-mkconfig -o /boot/grub/grub.cfg
在UEFI-GPT模式下,运行:
# grub-mkconfig -o /boot/efi/EFI/GRUB/grub.cfg
一个典型 /etc/grub.d/40_custom
示例文件类似于下面。每个 menuentry
的结构都应该和下面的类似.请注意 UEFI 分区/dev/sda2
被命名为hd0,gpt2
和 ahci0,gpt2
(请参考here获取更多信息)
/etc/grub.d/40_custom
#!/bin/sh exec tail -n +3 $0 # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. menuentry "Microsoft Windows 8.1" { echo "Loading Microsoft Windows 8.1..." insmod part_gpt insmod fat insmod search_fs_uuid insmod chain search --fs-uuid --no-floppy --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 763A-9CB6 chainloader /EFI/Microsoft/Boot/bootmgfw.efi } menuentry "Microsoft Control Center" { echo "Loading Microsoft Control Center..." insmod part_gpt insmod fat insmod search_fs_uuid insmod chain search --fs-uuid --no-floppy --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 763A-9CB6 chainloader /EFI/HP/boot/bootmgfw.efi } menuentry "System shutdown" { echo "System shutting down..." halt } menuentry "System restart" { echo "System rebooting..." reboot }
GNU/Linux 启动项
假设另一个发行版位于sda2
:
menuentry "Other Linux" { set root=(hd0,2) linux /boot/vmlinuz (add other options here as required) initrd /boot/initrd.img (if the other kernel uses/needs one) }
或者让 grub 根据 UUID 或 label 查找启动项:
menuentry "Other Linux" { # assuming that UUID is 763A-9CB6 search --set=root --fs-uuid 763A-9CB6 # search by label OTHER_LINUX (make sure that partition label is unambiguous) #search --set=root --label OTHER_LINUX linux /boot/vmlinuz (add other options here as required, for example: root=UUID=763A-9CB6) initrd /boot/initrd.img (if the other kernel uses/needs one) }
FreeBSD 启动项
要求 FreeBSD 安装在单独的 UFS(v2) 分区上,假设在分区表里面 FreeBSD 分区是 sda4
:
直接加载内核
menuentry 'FreeBSD' { insmod ufs2 set root='hd0,gpt4,bsd1' ## or 'hd0,msdos4,bsd1', if using an IBM-PC (MS-DOS) style partition table kfreebsd /boot/kernel/kernel kfreebsd_loadenv /boot/device.hints set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada0s4a set kFreeBSD.vfs.root.mountfrom.options=rw }
Chainloading 嵌入的启动项
menuentry 'FreeBSD' { insmod ufs2 set root='hd0,gpt4,bsd1' chainloader +1 }
运行传统的 BSD 第二阶段 loader
menuentry 'FreeBSD' { insmod ufs2 set root='(hd0,4)' kfreebsd /boot/loader }
UEFI-GPT 模式下安装的Windows的启动项
if [ "${grub_platform}" == "efi" ]; then menuentry "Microsoft Windows Vista/7/8/8.1 UEFI-GPT" { insmod part_gpt insmod fat insmod search_fs_uuid insmod chain search --fs-uuid --set=root $hints_string $fs_uuid chainloader /EFI/Microsoft/Boot/bootmgfw.efi } fi
$hints_string
和 $uuid
可以通过以下命令获取。$uuid
:
# grub-probe --target=fs_uuid $esp/EFI/Microsoft/Boot/bootmgfw.efi 1ce5-7f28
$hints_string
:
# grub-probe --target=hints_string $esp/EFI/Microsoft/Boot/bootmgfw.efi
--hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1
这两个命令都是假设ESP挂载在$esp
上.当然,Windows的EFI文件路径可能有变,因为这就是Windows....
"Shutdown" 启动项
menuentry "System shutdown" { echo "System shutting down..." halt }
"Restart" 启动项
menuentry "System restart" { echo "System rebooting..." reboot }
在BIOS-MBR模式下安装的Microsoft Windows
bootmgr
启动,现在不再需要链式加载分区启动扇区了bootmgr
位于系统分区(system partition),而不是Windows系统所在的分区(比如C盘).在uuid-卷名列表中,系统分区是那个名为LABEL="SYSTEM RESERVED"
或 LABEL="SYSTEM"
的项,而且这个分区一般只有100到200MB大(和Arch的启动分区差不多).请参考Wikipedia:System partition and boot partition本节假设你的Windows分区是/dev/sda1
.首先,找到Windows系统分区的UUID(Windows's SYSTEM PARTITION,bootmgr存放其上
).如果Windows bootmgr
的位置是/media/SYSTEM_RESERVED/bootmgr
,对于 Windows Vista/7/8,执行:
# grub-probe --target=fs_uuid /media/SYSTEM_RESERVED/bootmgr 69B235F6749E84CE
# grub-probe --target=hints_string /media/SYSTEM_RESERVED/bootmgr --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1
NTLDR
替代bootmgr
. 注意,可能NTLDR
不是在名为"SYSTEM_RESERVED"的分区上,请在XP系统所在的分区上寻找 NTLDR
接着,将下面的代码添加到/etc/grub.d/40_custom
或者/boot/grub/custom.cfg
中.然后,使用grub-mkconfig
重新生成grub.cfg
,这样就能在BIOS-MBR配置下使用GRUB2引导启动Windows系统了:
对于 Windows Vista/7/8
if [ "${grub_platform}" == "pc" ]; then menuentry "Microsoft Windows Vista/7/8 BIOS-MBR" { insmod part_msdos insmod ntfs insmod search_fs_uuid insmod ntldr search --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 69B235F6749E84CE ntldr /bootmgr } fi
对于Windows XP
if [ "${grub_platform}" == "pc" ]; then menuentry "Microsoft Windows XP" { insmod part_msdos insmod ntfs insmod search_fs_uuid insmod ntldr search --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 69B235F6749E84CE ntldr /ntldr } fi
\boot\bcd
报错(错误代码为0xc000000f
).可以通过Wondows Recovery Console来修复这个错误:
x:\> "bootrec.exe /fixboot" x:\> "bootrec.exe /RebuildBcd".
不要使用bootrec.exe /Fixmbr
,因为那会将GRUB清除掉
/etc/grub.d/40_custom
可以做为创建/etc/grub.d/nn_custom
的模板.nn
定义了脚本执行的优先级.脚本执行的顺序又决定了grub引导启动目录的内容.
nn
应该比06大,这样才能确保必要的脚本被优先执行通过EasyBCD NeoGRUB 和Windows共存
现在EasyBCD的NeoGRUB还不能识别GRUB的目录格式,在 C:\NST\menu.lst
中添加如下行以链式加载到GRUB:
default 0 timeout 1
title Chainload into GRUB v2 root (hd0,7) kernel /boot/grub/i386-pc/core.img
最后,使用grub-mkconfig
重建grub.cfg
其他选项
LVM
如果使用LVM做为启动设备,那么在启动项里添加:
insmod lvm
然后在启动项里指定root:
set root=lvm/lvm_group_name-lvm_logical_boot_partition_name
示例如下:
# (0) Arch Linux menuentry "Arch Linux" { insmod lvm set root=lvm/VolumeGroup-lv_boot # you can only set following two lines linux /vmlinuz-linux root=/dev/mapper/VolumeGroup-root ro initrd /initramfs-linux.img }
阵列
通过添加insmod mdraid
,GRUB能够很方便的处理磁盘阵列.比如/dev/md0
:
set root=(md0)
阵列上的分区(比如/dev/md0p1
)则为:
set root=(md0,1)
如果启动分区在raid1上,想要安装grub,只需要在两个磁盘上分别运行grub-install即可:
grub-install --target=i386-pc --recheck --debug /dev/sda && grub-install --target=i386-pc --recheck --debug /dev/sdb
这时/dev/sda和/dev/sdb就都有了raid1的启动文件夹/boot了
root加密
将cryptdevice=/dev/yourdevice:label
添加到/etc/default/grub
中的GRUB_CMDLINE_LINUX
配置项,可以让GRUB传递参数给内核,让内核对root加密:
/boot/grub/menu.lst.pacsave
以获取正确的device/label. 在kernel /vmlinuz-linux
后去找label.将root映射到/dev/mapper/root
:
GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda2:root"
当然,需要在rootfs上禁用UUID:
GRUB_DISABLE_LINUX_UUID=true
Regenerate the configuration.
在GRUB中直接从ISO启动
编辑/etc/grub.d/40_custom
或 /boot/grub/custom.cfg
,给目标ISO添加一个启动项.然后使用grub-mkconfig -o /boot/grub/grub.cfg
更新配置档
Arch ISO
hd0,6
分区上的/archives
文件夹里(hd1,$partition)
and either /dev/sdbY
for the img_dev
parameter or a persistent name, e.g. img_dev=/dev/disk/by-label/CORSAIR
.(hd1,$partition)
或/dev/sdbY
作为img_dev
参数的值,或者使用持久块设备命名法命名的设备,比如img_dev=/dev/disk/by-label/CORSAIR
.x86_64
menuentry "Archlinux-2013.05.01-dual.iso" --class iso { set isofile="/archives/archlinux-2013.05.01-dual.iso" set partition="6" loopback loop (hd0,$partition)/$isofile linux (loop)/arch/boot/x86_64/vmlinuz archisolabel=ARCH_201305 img_dev=/dev/sda$partition img_loop=$isofile earlymodules=loop initrd (loop)/arch/boot/x86_64/archiso.img }
i686
menuentry "Archlinux-2013.05.01-dual.iso" --class iso { set isofile="/archives/archlinux-2013.05.01-dual.iso" set partition="6" loopback loop (hd0,$partition)/$isofile linux (loop)/arch/boot/i686/vmlinuz archisolabel=ARCH_201305 img_dev=/dev/sda$partition img_loop=$isofile earlymodules=loop initrd (loop)/arch/boot/i686/archiso.img }
Ubuntu ISO
hd0,6
分区上的/archives
文件夹里. 用户需要根据自己系统的实际情况调整.menuentry "ubuntu-13.04-desktop-amd64.iso" { set isofile="/archives/ubuntu-13.04-desktop-amd64.iso" loopback loop (hd0,6)/$isofile linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash -- initrd (loop)/casper/initrd.lz }
menuentry "ubuntu-12.04-desktop-amd64.iso" { set isofile="/archives/ubuntu-12.04-desktop-amd64.iso" loopback loop (hd0,6)/$isofile linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash -- initrd (loop)/casper/initrd.lz }
Other ISOs
可从这里获取其他ISO的配置.
使用GRUB命令行
MBR太小,所以不足以存储所有的GRUB模组.MBR里面只有启动目录配置和一些很基本的命令.GRUB的主要功能通过/boot/grub
里的模组实现,而且可以按需加载.出现错误时,GRUB可能不能引导启动(比如,磁盘分区发生了变化).这时候,一般会出现命令行界面.
GRUB不止提供一个shell.如果GRUB不能读取到启动目录配置,但是能找到磁盘,你很可能需要进入"normal" shell:
sh:grub>
如果有更严重的问题(比如,GRUB找不到必须的文件了),你就可能需要进入"rescue" shell:
grub rescue>
"rescue" shell是"normal" shell的一个子集,其支持的功能更少.如果不幸进入了"rescue" shell里,首先记载"normal"模组,然后启动"normal" shell:
grub rescue> set prefix=(hdX,Y)/boot/grub grub rescue> insmod (hdX,Y)/boot/grub/i386-pc/normal.mod rescue:grub> normal
分页支持
GRUB支持对长输出进行分页(比如运行help
的输出).不过只有normal shell支持分页,而rescue shell不支持.开启分页支持的方法如下:
sh:grub> set pager=1
使用命令行引导操作系统
grub>
可以使用GRUB命令行引导操作系统,一个典型的应用场景是通过chainloading来引导另一个Windows或Linux
ChainLoading的意思是用当前的bootloader去载入另一个bootloader,所以叫做链式加载.这个bootloader可能位于MBR,也可能在另一个分区的引导扇区上.
链式加载一个分区
set root=(hdX,Y) chainloader +1 boot
X=0,1,2... Y=1,2,3...
比如链式加载一个位于首磁盘,首分区上的Windows:
set root=(hd0,1) chainloader +1 boot
也可以使用GRUB链式加载另一个分区引导扇区上的GRUB.
链式加载磁盘
set root=hdX chainloader +1 boot
正常载入
请参考#使用应急命令行
parttool
如果你安装了Windows 9x系列操作系统,而它们隐藏了磁盘(比如C盘),GRUB能够使用parttool来设置是否隐藏.比如,想从三个Windows 9x系统的第三个启动,可以这样:
parttool hd0,1 hidden+ boot- parttool hd0,2 hidden+ boot- parttool hd0,3 hidden- boot+ set root=hd0,3 chainloader +1 boot
使用应急命令行
请先阅读#使用GRUB命令行.如果无法进入命令行,请尝试使用Live CD或者其他rescue磁盘引导,然后修正错误.不过有些时候我们手上没有此类rescue磁盘,这时,应急命令行(rescue console)就可以派上用场了.
GRUB应急命令行里可用的命令有insmod
, ls
, set
, unset
.可以使用set/unset修改变量,使用insmod来载入模组.
首先,用户必须知道启动分区(/boot
所在位置然后设置:
grub rescue> set prefix=(hdX,Y)/boot/grub
通过加载linux
模组来扩展命令行的功能:
grub rescue> insmod (hdX,Y)/boot/grub/linux.mod
set prefix=(hdX,Y)/grub
然后insmod (hdX,Y)/grub/linux.mod
)这个模组会启动对我们熟悉的linux
和 initrd
命令的支持 (请参考#配置).
比如:
set root=(hd0,5) linux /boot/vmlinuz-linux root=/dev/sda5 initrd /boot/initramfs-linux.img boot
如果/boot在单独分区上:
set root=(hd0,5) linux /vmlinuz-linux root=/dev/sda6 initrd /initramfs-linux.img boot
成功启动Arch后,用户可以修正配置的错误或者重新安装GRUB.
异常处理
Intel BIOS不能引导GPT
一些Intel的BIOS要求至少要一个可启动的分区(MBR方案下的),导致GPT方案下的分区GRUB无法启动.
可以通过fdisk来将一个GPT分区标志为'boot'((最好就设在你为GRUB创建的那个1007KiB分区上)),这样就可以绕过这个问题了:
1.对目标磁盘(比如/dev/sda)运行fdisk 2.按a
键,然后选择想要设置'boot'标志的分区 3.最后按w
键,将变更写入磁盘
请参考 http://www.rodsbooks.com/gdisk/bios.html
启用调试信息
在grub.cfg
里添加:
set pager=1 set debug=all
"No suitable mode found" error
启动时可能出现如下提示信息:
error: no suitable mode found Booting however
然后你需要以合适的视频模式(gfxmode
)启动 GRUB 图形化终端(gfxterm
).视频模式由GRUB通过'gfxpayload'变量传递给linux内核.在UEFI系统下,如果没有初始化视频模式的值,终端上就不会显示内核启动消息(至少直到KMS开始运行)
将/usr/share/grub/unicode.pf2
复制到 ${GRUB_PREFIX_DIR}(/boot/grub/
.如果GRUB UEFI安装时设定了--boot-directory=$esp/EFI
,那么复制的目的文件夹是$esp/EFI/grub/
:
# cp /usr/share/grub/unicode.pf2 ${GRUB_PREFIX_DIR}
如果/usr/share/grub/unicode.pf2
不存在, 安装bdf-unifont, 创建 unifont.pf2
文件然后将其复制到 ${GRUB_PREFIX_DIR}
:
# grub-mkfont -o unicode.pf2 /usr/share/fonts/misc/unifont.bdf
然后,在grub.cfg
文件中添加如下行:
(会给linux内核传递合适的视频模式,否则你只会得到一个黑屏,虽然系统还是会启动成功)
BIOS 系统:
insmod vbe
UEFI 系统:
insmod efi_gop insmod efi_uga
在这些行后添加(BIOS&&UEFI):
insmod font
if loadfont ${prefix}/fonts/unicode.pf2 then insmod gfxterm set gfxmode=auto set gfxpayload=keep terminal_output gfxterm fi
如果要gfxterm(图形化终端)工作正常,${GRUB_PREFIX_DIR}
文件夹里面应该要有unicode.pf2
.
出现"msdos-style"错误消息
以下错误可能出现在你将GRUB安装到VMware上时.请阅读相关链接.这种情况是因为首分区直接从MBR后开始(即第64个扇区),而不是和正常的那样有1到2M post-MBR gap.请参阅#MBR专用指令[broken link: invalid section]
grub-setup: warn: This msdos-style partition label has no post-MBR gap; embedding will not be possible! grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and its use is discouraged. grub-setup: error: If you really want blocklists, use --force.
GRUB UEFI 启动到了rescue shell下
如果GRUB直接就启动到了rescue shell下,而且没报错,这可能是因为grub.cfg
丢失或者位置不对.如果GRUB UEFI 安装时设定了--boot-directory
参数,而grub.cfg
文件丢失,会出现这个问题.如果启动分区的分区号发生了变化(这个分区号会被直接编码到grubx64.efi
文件中),也会出现这个问题.
GRUB UEFI 无法被载入
下面是一个EFI启动项信息示例:
# efibootmgr -v
BootCurrent: 0000 Timeout: 3 seconds BootOrder: 0000,0001,0002 Boot0000* Grub HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\efi\grub\grub.efi) Boot0001* Shell HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\EfiShell.efi) Boot0002* Festplatte BIOS(2,0,00)P0: SAMSUNG HD204UI
如果启动后,屏幕直接变黑,几秒后就跳到了下一个启动项,根据相关链接的说法是,将GRUB移动到root分区上可能会解决这个问题.必须先删除启动项,然后重建,变化如下:
Boot0000* Grub HD(1,800,32000,23532fbb-1bfa-4e46-851a-b494bfe9478c)File(\grub.efi)
"Invalid signature"错误
如果在启动Windows时出现了"invalid signature"错误(比如在重新分区或者添加了新硬盘后),删除GRUB的磁盘mapping,然后重建:
# mv /boot/grub/device.map /boot/grub/device.map-old # grub-mkconfig -o /boot/grub/grub.cfg
grub-mkconfig
此时就应该生成了新的启动项了,包括Windows.确认能启动成功后,再将备份文件/boot/grub/device.map-old
删除.
引导过程卡死
如果在GRUB载入内核并初始化ramdisk后引导过程卡死了,请尝试移除add_efi_memmap
这个内核参数
回滚到 GRUB Legacy
- 将GRUB2相关文件改名以为备份:
# mv /boot/grub /boot/grub.nonfunctional
- 将GRUB Legacy 移回
/boot
:
# cp -af /boot/grub-legacy /boot/grub
- 恢复备份的MBR
# dd if=/path/to/backup/first-sectors of=/dev/sdX bs=512 count=1
安全的方法是只恢复MBR中的启动代码:
# dd if=/path/to/backup/mbr-boot-code of=/dev/sdX bs=446 count=1
其他系统不能自动发现Arch Linux
有人发现有些发行版不能使用os-prober
自动发现Arch Linux.据称先使用/etc/lsb-release
可能会解决这个问题.相关文件和工具可以在 官方仓库的lsb-release包中找到.
未找到 Windows 8/10
Windows 8/10 如果启用了 "Hiberboot", "Hybrid Boot" 或 "Fast Boot",可能会导致 Windows 分区无法被挂载。所以 grub-mkconfig
无法找到安装的 Windows。可以先禁用混合启动,将其添加到 GRUB 菜单。
参阅
- 官方GRUB说明 - https://www.gnu.org/software/grub/manual/grub.html
- Ubuntu GRUB Wiki - https://help.ubuntu.com/community/Grub2
- 在UEFI系统上编译GRUB步骤描述- https://help.ubuntu.com/community/UEFIBooting
- 维基百科BIOS启动分区
- 配置GRUB的完整说明 - http://members.iinet.net/~herman546/p20/GRUB2%20Configuration%20File%20Commands.html