GRUB Legacy
GRUB Legacy 是由 multiboot 引导加载程序,曾由 GNU 项目维护。它源自 GRUB,即 **GR**and **U**nified **B**ootloader,最初由 Erich Stefan Boleyn 设计和实现。
简而言之,引导加载程序是计算机启动时运行的第一个软件程序。它负责加载 Linux 内核并将其控制权移交给 Linux 内核。内核随后初始化操作系统的其余部分。
支持的文件系统
GRUB Legacy 捆绑了对多种文件系统的原生支持,特别是 FAT32、ext2、ReiserFS 或 XFS (仅限 v4)。
/boot,除非禁用不兼容的功能。通常可以通过使用一个独立的 /boot 分区来解决此问题,该分区使用通用支持的文件系统,例如 FAT32。安装
GRUB Legacy 可以通过 grub-legacyAUR 包进行安装。
此外,GRUB 必须安装到驱动器或分区的引导扇区才能充当引导加载程序。这将在#引导加载程序安装中介绍。
配置
配置文件位于 /boot/grub/menu.lst。编辑此文件以满足您的需求。
timeout #-- 在自动加载default操作系统之前等待的秒数。default #-- 当timeout过期时选择的默认启动项。
一个示例配置(其中 /boot 位于一个单独的分区上)随包提供。
查找 GRUB 的根目录
GRUB 必须知道其文件在系统中的位置,因为可能存在多个实例(例如,在多引导环境中)。GRUB 文件始终位于 /boot 下,而 /boot 可能位于一个专用的分区上。
- 硬盘被定义为 (hdX);这也指任何 USB 存储设备。
- 设备和分区编号从零开始。例如,BIOS 中识别的第一个硬盘将被定义为 (hd0)。第二个设备将被命名为 (hd1)。这也适用于分区。因此,第一个硬盘上的第二个分区将被定义为 (hd0,1)。
如果您不确定 /boot 的位置,请使用 GRUB shell 的 find 命令来定位 GRUB 文件。通过以下方式以 root 身份进入 GRUB shell:
# grub
以下示例适用于 *没有* 独立 /boot 分区的系统,其中 /boot 仅是 / 下的一个目录。
grub> find /boot/grub/stage1
以下示例适用于 *有* 独立 /boot 分区的系统。
grub> find /grub/stage1
GRUB 将找到文件,并输出 stage1 文件的位置。例如:
grub> find /grub/stage1
(hd0,0)
此值应输入到您的配置文件中的 root 行。键入 quit 退出 shell。
与 Windows 双系统启动
将以下内容添加到您的 /boot/grub/menu.lst 文件末尾(假设您的 Windows 分区位于第一个驱动器的第一个分区上)。
/boot/grub/menu.lst
title Windows rootnoverify (hd0,0) makeactive chainloader +1
- 如果您尝试与 Windows 7 双系统启动,则应注释掉
makeactive行。 - Windows 2000 及更高版本 *不需要* 位于第一个分区即可启动(与普遍认为的相反)。如果 Windows 分区发生更改(例如,如果您在 Windows 分区之前添加了一个分区),则需要编辑 Windows 的
boot.ini文件以反映更改(有关如何操作的详细信息,请参阅本文)。
如果 Windows 位于另一块硬盘上,则必须使用 map 命令。这将使您的 Windows 安装认为它实际上位于第一个驱动器上。假设您的 Windows 分区位于第二个驱动器的第一个分区上。
/boot/grub/menu.lst
title Windows map (hd0) (hd1) map (hd1) (hd0) rootnoverify (hd1,0) makeactive chainloader +1
与 GNU/Linux 双系统启动
这可以通过与 Arch Linux 安装定义相同的方式完成。例如:
/boot/grub/menu.lst
title Other Linux root (hd0,2) kernel /path/to/kernel root=/dev/sda3 ro initrd /path/to/initramfs
/boot/grub/menu.lst 以匹配引导选项,或参阅#chainloader 和 configfile(推荐)。chainloader 和 configfile
为了便于系统维护,应使用 chainloader 或 configfile 命令来引导另一个提供 "automagic" GRUB 配置机制的 Linux 发行版(例如 Debian、Ubuntu、openSUSE)。这允许发行版自行管理其 menu.lst 和引导选项。
chainloader命令将加载另一个引导加载程序(而不是内核映像);如果另一个引导加载程序安装在分区的引导扇区中(例如 GRUB),则非常有用。这允许将 GRUB 的 "main" 实例安装到 MBR,并将发行版特定的 GRUB 实例安装到每个分区引导记录 (PBR) 中。
configfile命令将指示当前运行的 GRUB 实例加载指定的配置文件。这可以在不安装单独的 GRUB 的情况下用于加载另一个发行版的menu.lst。这种方法的缺点是其他menu.lst可能与已安装的 GRUB 版本不兼容;一些发行版会深度修改其 GRUB 版本。
例如,GRUB 将安装到 MBR,而另一个引导加载程序(无论是 GRUB 还是 LILO)已安装到 (hd0,2) 的引导扇区。
--------------------------------------------- | | | | % | | M | | | B % | | B | (hd0,0) | (hd0,1) | L % (hd0,2) | | R | | | % | | | | | % | --------------------------------------------- | ^ | chainloading | -----------------------------
您可以简单地在 menu.lst 中包含:
title Other Linux root (hd0,2) chainloader +1
或者,如果 (hd0,2) 上的引导加载程序是 GRUB:
title Other Linux root (hd0,2) configfile /boot/grub/menu.lst
chainloader 命令还可以用于加载第二个驱动器的 MBR。
title Other drive rootnoverify (hd1) chainloader +1
与 GNU/Linux 双系统启动 (GRUB2)
如果另一个 Linux 发行版使用 GRUB2(例如 Ubuntu 9.10+),并且您已将其引导加载程序安装到其根分区,您可以向您的 /boot/grub/menu.lst 添加类似以下的条目:
/boot/grub/menu.lst
# other Linux using GRUB2 title Ubuntu root (hd0,2) kernel /boot/grub/core.img
在启动时选择此条目将加载另一个发行版的 GRUB2 菜单,假设该发行版安装在 /dev/sda3 上。
引导加载程序安装
手动恢复 GRUB 库
*stage* 文件应该位于 /boot/grub 中,如果引导加载程序未在系统安装期间安装,或者分区/文件系统已损坏、意外删除等,则可能不是这样。
像这样手动复制 GRUB 库:
# cp -a /usr/lib/grub/i386-pc/* /boot/grub
关于引导加载程序安装的一般说明
GRUB 可以从一个单独的介质(例如 LiveCD)安装,或直接从一个正在运行的 Arch 系统安装。GRUB *很少*需要重新安装,并且在以下情况下*不需要*安装:
- 配置文件已更新。
grub-legacyAUR 包已更新。
在以下情况下*需要*安装:
- 尚未安装引导加载程序。
- 另一个操作系统覆盖了 Linux 引导加载程序。
- 引导加载程序由于未知原因失败。
在继续之前,请注意几点:
- 在继续之前,请确保您的 GRUB 配置正确(
/boot/grub/menu.lst)。请参阅 查找 GRUB 的根目录 以确保您的设备定义正确。 - GRUB 必须安装到 MBR(硬盘的第一个扇区),或大多数 BIOS 识别的第一个存储设备的第一分区。为了让各个发行版能够管理自己的 GRUB 菜单,可以使用多个 GRUB 实例,请参阅 #chainloader 和 configfile。
- 在某些情况下(例如 RAID 配置,或如果您忘记/破坏了 GRUB 安装),可能需要从一个
chroot环境中安装 GRUB(即通过独立介质从已安装的环境进行)。您需要从 LiveCD 或另一个 Linux 安装中 更改根目录来执行此操作。
首先,进入 GRUB shell:
# grub
使用 root 命令和 find 命令的输出(请参阅 #查找 GRUB 的根目录)来指示 GRUB 哪个分区包含 stage1(因此,也包含 /boot)。
grub> root (hd1,0)
Tab,您将看到可用的存储设备,这也可以对分区进行。制表符补全在 GRUB 启动菜单中也有效。如果您的配置文件有错误,您可以在启动菜单中编辑它,并使用制表符补全来帮助查找设备和分区。请参阅 #编辑 GRUB 启动菜单项。安装到 MBR
以下示例将 GRUB 安装到第一个驱动器的 MBR。
grub> setup (hd0)
安装到分区
以下示例将 GRUB 安装到第一个驱动器的第一个分区。
grub> setup (hd0,0)
运行 setup 后,键入 quit 退出 shell。如果您进行了 chroot,请 退出 chroot 并卸载分区。现在重新启动进行测试。
备用方法 (grub-install)
使用 grub-install 命令后跟安装引导加载程序的位置。例如,将 GRUB 安装到第一个驱动器的 MBR:
# grub-install /dev/sda
GRUB 将指示是否成功安装。如果未成功,您将需要使用 GRUB shell 方法。
技巧与提示
帧缓冲分辨率
可以在 menu.lst 中使用给定的分辨率,但您可能希望以其全原生分辨率使用 LCD 宽屏。以下是您可以实现这一目标的方法:
在 Wikipedia 上,有一个扩展帧缓冲分辨率的列表(即超出 VBE 标准的分辨率)。
如果所需分辨率在使用从表中获取的代码后不起作用,通常是因为显卡制造商可以自由选择任何他们希望的数字,因为这不属于 VBE 3 标准。这些代码可能因显卡而异(甚至可能来自同一制造商)。
与其使用该表,不如使用下面提到的工具之一来获取正确的代码:
GRUB 识别的值
这是仅使用 GRUB 本身查找分辨率代码的简单方法。
在内核行上,指定内核应询问您使用哪种模式。
kernel /vmlinuz-linux root=/dev/sda1 ro vga=ask
现在重新启动。GRUB 将显示一组合适的代码供您使用,并提供扫描更多代码的选项。
您可以选择要使用的代码(不要忘记它,下一步需要它)并使用它进行引导。
现在,将内核行中的 ask 替换为您选择的正确代码。
例如,对于 [369] 1680x1050x32 的内核行将是:
kernel /vmlinuz-linux root=/dev/sda1 ro vga=0x369
hwinfo
- 安装 hwinfo 包。
- 以 root 身份运行
hwinfo --framebuffer。 - 选择与所需分辨率对应的代码。
- 在
menu.lst的vga=内核选项中使用带 0x 前缀的 6 位数代码。或者将其转换为十进制以避免使用 0x 前缀。
hwinfo 的示例输出
Mode 0x0364: 1440x900 (+1440), 8 bits Mode 0x0365: 1440x900 (+5760), 24 bits
以及内核行
kernel /vmlinuz-linux root=/dev/sda1 ro vga=0x0365
命名分区
按标签
如果您不时地更改(或计划更改)分区大小,您可能需要考虑按标签定义您的驱动器/分区。您可以通过以下方式为 ext2、ext3、ext4 分区添加标签:
e2label /dev/drive|partition label
标签名称最多可以为 16 个字符,但 GRUB 无法识别空格。然后,在您的 menu.lst 中定义它:
kernel /boot/vmlinuz-linux root=/dev/disk/by-label/Arch_Linux ro
按 UUID
可以使用 blkid 或 ls -l /dev/disk/by-uuid 发现分区的 UUID(Universally Unique IDentifier)。在 menu.lst 中使用以下任一方式定义:
kernel /boot/vmlinuz-linux root=/dev/disk/by-uuid/uuid_number
或者
kernel /boot/vmlinuz-linux root=UUID=uuid_number
以 root 身份启动 (单用户模式)
在引导加载程序处,选择一个条目并编辑它(按 e 键)。将以下参数附加到内核选项:
[...] single init=/bin/bash
这将以单用户模式(init 1)启动,即您将进入 root 提示符,而不会被要求输入密码。这对于恢复功能(例如重置 root 密码)可能很有用。但是,如果您没有设置任何#密码保护,这将是一个巨大的安全漏洞。
密码保护
您可以在 GRUB 配置文件中为要保护的操作系统启用密码保护。如果您希望获得额外的安全性,并且 BIOS 缺少此类功能,则可能需要引导加载程序密码保护。
首先,选择一个您能记住的密码,然后加密它:
# grub-md5-crypt
Password: Retype password: $1$ZOGor$GABXUQ/hnzns/d5JYqqjw
然后,将您的密码添加到 /boot/grub/menu.lst 文件开头(密码必须位于配置文件开头,GRUB 才能识别它)。
# general configuration timeout 5 default 0 color light-blue/black light-cyan/blue password --md5 $1$ZOGor$GABXUQ/hnzns/d5JYqqjw
然后,对于您希望保护的每个操作系统,添加 lock 命令:
# (0) Arch Linux title Arch Linux lock root (hd0,1) kernel /boot/vmlinuz-linux root=/dev/disk/by-label/Arch_Linux ro initrd /boot/initramfs-linux.img
您始终可以通过在主板上设置相应的跳线来重置 BIOS 设置(请参阅您的主板手册,因为这因型号而异)。因此,万一其他人可以访问硬件,基本上无法阻止引导破解。
以命名的引导项重启
如果您发现您经常需要切换到其他非默认操作系统(例如 Windows),但又不得不重新启动并等待 GRUB 菜单出现,这会很麻烦。GRUB 提供了一种在重启时记录您选择的操作系统而不是等待菜单出现的方法,通过指定一个临时的新默认项,该默认项将在使用后重置。
假设有一个简单的 menu.lst 设置如下:
/boot/grub/menu.lst
# general configuration: timeout 10 default 0 color light-blue/black light-cyan/blue # (0) Arch title Arch Linux root (hd0,1) kernel /boot/vmlinuz-linux root=/dev/disk/by-label/ARCH ro initrd /boot/initramfs-linux.img # (1) Windows title Windows XP rootnoverify (hd0,0) makeactive chainloader +1
Arch 是默认项(0)。我们想重启到 Windows。将 default 0 更改为 default saved -- 这将在每次使用 savedefault 0 命令时将当前默认项记录在 GRUB 目录中的 default 文件中。现在,在 Windows 条目底部添加 savedefault 0 行。每次引导 Windows 时,它都会将默认值重置为 Arch,从而使将默认值更改为 Windows 成为临时性的。
现在需要的是一种手动轻松更改默认值的方法。这可以通过 grub-set-default 命令来实现。因此,要重启到 Windows,请输入以下命令:
# grub-set-default 1
然后重启。
为了方便使用,您可能希望设置 sudo 并将 /sbin/grub-set-default 添加到用户无需密码即可执行的命令列表中。
LILO 和 GRUB 的交互
如果您的系统上安装了 LILO 包,请卸载它。因为某些任务(例如使用 make all 进行内核编译)会调用 LILO,然后 LILO 将安装在 GRUB 之上。LILO 可能已包含在您的基础系统中,具体取决于您的安装介质版本以及您在软件包选择阶段是否选中/取消选中它。
GRUB 启动盘
首先,格式化一张软盘:
# fdformat /dev/fd0 # mke2fs /dev/fd0
现在挂载磁盘:
# mount -t ext2 /dev/fd0 /mnt/fl
将 GRUB 安装到磁盘:
# grub-install --root-directory=/mnt/fl '(fd0)'
将您的 menu.lst 文件复制到磁盘:
# cp /boot/grub/menu.lst /mnt/fl/boot/grub/menu.lst
现在卸载您的软盘:
# umount /mnt/fl
现在,您应该能够插入磁盘并重新启动计算机,它应该会引导到 GRUB。当然,请确保在 BIOS 的启动顺序中将软盘驱动器设置为比硬盘更高的优先级。
另请参阅:Super GRUB Disk。
隐藏 GRUB 菜单
可以使用 hiddenmenu 选项来默认隐藏菜单。这样就不会显示菜单,并且在超时后将自动选择默认选项。但是,您仍然可以按 Esc 键来显示菜单。要使用它,只需将其添加到您的 /boot/grub/menu.lst 文件中:
hiddenmenu
故障排除
GRUB 错误 17
首先要检查的是拔掉所有外部驱动器。这似乎显而易见,但有时我们会感到疲惫;)
如果您的分区表被弄乱了,"GRUB error 17" 这样的不愉快消息可能是您下次重新启动时唯一看到的东西。分区表可能被弄乱的原因有很多。通常,使用 GParted 操作分区的用户——特别是逻辑驱动器——可能会导致分区的顺序发生变化。例如,您删除了 /dev/sda6 并调整了 /dev/sda7 的大小,最后重新创建了原来的 /dev/sda6,但现在它出现在列表的底部,例如 /dev/sda9。尽管分区的物理顺序/逻辑驱动器的顺序没有改变,但它们被识别的顺序却改变了。
修复分区表很容易。从您的 Arch CD/DVD/USB 启动,以 root 身份登录并修复分区表:
# fdisk /dev/sda
进入磁盘后,键入 e[x]tra/expert 模式,[f]ix 分区顺序,然后 [w]rite 表并退出。
您可以通过发出 fdisk -l 来验证分区表是否已修复。现在您只需要修复 GRUB。请参阅 #引导加载程序安装。
基本上,您需要告诉 GRUB /boot 的正确位置,然后将 GRUB 重新写入磁盘上的 MBR。
例如:
# grub
grub> root (hd0,6) grub> setup (hd0) grub> quit
有关此部分更深入的摘要,请参阅 [1]。
/boot/grub/stage1 读取不正确
如果您在尝试设置 GRUB 时看到此错误消息,并且您没有使用新的分区表,那么检查它值得。
# fdisk -l /dev/sda
这将显示 /dev/sda 的分区表。请在此处检查您的分区的 "Id" 值是否正确。"System" 列将显示 "Id" 值的描述。
例如,如果您的引导分区被标记为 "HPFS/NTFS",那么您必须将其更改为 "Linux"。为此,请进入 fdisk:
# fdisk /dev/sda
使用 t 更改分区的系统 ID,选择您的分区号,然后输入新的系统 ID(Linux = 83)。您也可以通过键入 L 而不是系统 ID 来列出所有可用的系统 ID。
如果您更改了分区的系统 ID,您应该 [v]erify 您的分区表,然后 [w]rite 它。
现在再次尝试设置 GRUB。
另请参阅报告此问题的 论坛帖子。
意外安装到 Windows 分区
如果您意外地将 GRUB 安装到 Windows 分区,GRUB 会将一些信息写入分区的引导扇区,从而擦除对 Windows 引导加载程序的引用。(这对于 NTLDR(Windows XP 及更早版本的引导加载程序)是正确的,对于更高版本不确定)。
要解决此问题,您需要使用 Windows 发行版的 Windows 恢复控制台。由于许多计算机制造商不随产品附带此功能(许多选择使用恢复分区),Microsoft 已提供下载。如果您使用 XP,请查看此页面以将软盘转换为恢复 CD。引导恢复 CD(或启用 Windows 恢复模式)并运行 fixboot 来修复分区引导扇区。之后,您必须再次安装 GRUB——这一次,安装到 MBR,而不是 Windows 分区——来引导 Linux。
编辑 GRUB 启动菜单项
在启动菜单中选择一个条目后,您可以通过按 e 键来编辑它。如果您需要查找设备,请使用制表符补全,然后按 Esc 退出。然后您可以按 b 尝试启动。
device.map 错误
如果在安装或启动期间出现提及 /boot/grub/device.map 的错误,请运行:
# grub-install --recheck /dev/sda
强制 GRUB 重新检查设备映射,即使它已存在。在调整分区大小或添加/删除驱动器后,这可能是必需的。
KDE 重启下拉菜单失败
如果您通过包含 GRUB 中配置的所有操作系统列表的子菜单打开,选择了一个,并在重启后仍然引导到您的默认操作系统,那么您可能需要检查您的 /boot/grub/menu.lst 文件中是否包含以下行:
default saved
在 /boot/grub/menu.lst 文件中。
GRUB 无法找到或安装到任何 virtio /dev/vd* 或其他非 BIOS 设备
我在使用 virtio 设备作为硬盘安装 KVM 虚拟机中的 Arch Linux 时,在安装 GRUB 时遇到了麻烦。为了安装 GRUB,我发现了以下方法:键入 Ctrl+Alt+F2 或其他 F 键进入一个空闲的虚拟控制台。这假设您的根文件系统已挂载到 /mnt 文件夹,并且引导文件系统已挂载或存储在 /mnt/boot 文件夹中。
1. 确保所有必需的 GRUB 文件都存在于您的引导目录中(假设它已挂载在 /mnt/boot 文件夹中),方法是执行以下命令:
# ls /mnt/boot/grub
2. 如果 /mnt/boot/grub 文件夹已经包含所有必需的文件,请跳至步骤 3。否则,请执行以下命令(将 /mnt、your_kernel 和 your_initramfs 替换为实际的路径和文件名)。您还应该将 menu.lst 文件写入此文件夹:
# mkdir -p /mnt/boot/grub # if the folder is not yet present # cp -r /boot/grub/stage1 /boot/grub/stage2 /mnt/boot/grub # cp -r your_kernel your_initramfs /mnt/boot
3. 使用以下命令启动 GRUB shell:
# grub --device-map=/dev/null
4. 输入以下命令。用与您的设置相对应的正确设备和分区替换 /dev/vda 和 (hd0,0)。
device (hd0) /dev/vda root (hd0,0) setup (hd0) quit
5. 如果 GRUB 没有报告任何错误消息,那么您可能已经完成了。您还需要将适当的模块添加到 ramdisk 中。有关更多信息,请参阅 QEMU#Preparing an Arch Linux guest。
参见
- GNU GRUB
- GRUB Grotto
- Boot debugging - 使用 GRUB 进行调试,设置模块值
- 使用 GRUB legacy 启动