概述
在本文中,学习如何为一个 Linux 系统设计一个磁盘分区布局。您将学习:
- 为独立的分区或磁盘分配文件系统和交换空间;
- 根据系统的预定用途调整设计;
- 确保系统能够启动。
本文讨论 PC 引导过程和 Linux 中使用的两个主要的启动加载程序 — LILO 和 GRUB — 帮助您准备 Linux Professional Institute's Junior Level Administration (LPIC-1) 考试 101 中主题 102 下的目标 102.2。该目标的权值为 2。我们还将向您介绍 GRUB 2,尽管它不是当前考试目标的必要内容。
先决条件
要充分地利用本系列文章,您应当对 Linux 以及在其中运行本文介绍的命令的 Linux 系统有一个基本的了解。您还应该熟悉文章 “学习 Linux,101:硬盘布局” 中讨论的硬盘驱动器布局。在某些情况下,程序的不同版本可能使用不同的方式格式化输出,因此您的结果可能并不总是与本文所示的清单和图形完全一样。
注意:本文中的图像是从启动过程初期采集的屏幕截图。如果您正在使用一个屏幕读取器阅读本文,您可能会发现拥有对应的配置文件以便参考的好处;从本文后面的 下载 部分下载它们。
启动过程概述
在我们深入 LILO 和 GRUB 之前,首先了解一下 PC 如何启动或
引导。称为
BIOS(
Basic
Input
Output
Service,基本输入输出服务)的代码存储在一个非临时内存中,比如 ROM、EEPROM
或
闪存。当 PC 打开或重新启动时,这个代码将执行。通常,它执行一个启动自测(POST)来检查机器。最后,它从引导驱动器上的主引导记录(MBR)加载第一个扇区。
所述,MBR 也包含分区表,因此 MBR 中的可执行代码量低于 512 字节,这个代码量不算多。注意,每个磁盘(甚至是软盘)都在它的 MBR 中包含可执行代码,即使这个代码只够输出一条消息,比如 “Non-bootable disk in drive A:”。由 BIOS 从第一个扇区加载的代码称为第一阶段启动加载程序
或
阶段 1 启动加载程序。
MS DOS、PC DOS 和 Windows® 使用的标准硬盘驱动器 MBR 检查分区表以发现标记为 active
的引导驱动器上的主分区,从该分区加载第一个扇区,并将控制权传递给已加载代码的开始部分。这个新的代码片段也称为
分区引导记录。分区引导记录实际上是另一个阶段 1 启动加载程序,但这个启动加载程序只能从分区加载一组块。这组新块中的代码称为
阶段 2 启动加载程序。根据 MS-DOS 和 PC-DOS 的使用方式,阶段 2 启动加载程序直接加载操作系统的剩余部分。这就是操作系统在启动并运行之前加载自身的方式。
这种方式对于只有单个操作系统的系统很有效。如果您想使用多个操作系统(比如 OS/2、Windows XP 和 3 个不同的 Linux 发行版)时又该怎么办呢?您可以
使用某个程序(比如 DOS FDISK 程序)来更改活动分区并重新启动,但这种方法比较麻烦。而且,一个磁盘只能拥有 4 个主分区,且标准 MBR 只能拥有一个活动主分区;它不能从一个逻辑分区启动。但我们假设的示例引用了 5 个操作系统,每个操作系统都需要一个分区。该怎么办呀!
解决方案是使用一些特殊代码,允许用户选择要引导的操作系统。这样的示例包括:
- Loadlin
- 一个 DOS 可执行程序,它从一个运行的 DOS 系统被调用,启动一个 Linux 分区。当设置一个多启动系统比较复杂且存在风险时,这个程序能够派上用场。
- OS/2 Boot Manager
- 这个程序安装在一个小型专用分区上。这个分区被标记为活动,标准 MBR 引导过程启动 OS/2 Boot Manager,该程序显示一个菜单,允许选择要启动的操作系统。
- 一个智能启动加载程序
- 这个程序驻留在一个操作系统分区上,通过一个活动分区的分区引导记录或者主引导记录调用。程序示例包括:
- BootMagic,Norton PartitionMagic 的一部分
- LILO,即 LInux LOader
- GRUB,即 GRand Unified Boot 加载程序(现在称为 GRUB Legacy)
- GRUB 2,最近才在常用发行版中新出现的一个新的启动加载程序
显然,如果您将系统控制权传递给某个拥有超过 512 字节的代码来完成它的任务,那么允许从逻辑分区启动或者从不在启动驱动器上的分区启动就不太困难。所有这些解决方案都允许这些可能性,原因是它们可以从任意一个分区加载一个引导记录,或者它们在一定程度上理解要启动引导过程需要加载哪个或哪些文件。
链式加载
当一个引导程序获取控制权之后,它可能做的一件事就是加载另一个引导程序。这称为链式加载(chain loading),这种加载在以下情况下最有可能发生:当位于主引导记录中的引导程序加载位于一个分区引导记录中的启动加载程序时。上述情况在以下两种情况下总是发生:当一个 Linux 启动加载程序被要求启动一个 Windows
或
DOS 分区时;或者当一个系统的 Linux 启动加载程序被要求加载另一个系统的启动加载程序时。
Linux 启动加载程序
从现在开始,我们将主要关注 LILO 和 GRUB,因为它们是多数 Linux 发行版包含的启动加载程序。LILO 已经存在一段时间了,而 GRUB 更新一些。最初的 GRUB 现在变成了 GRUB Legacy,GRUB 2 正在 Free Software Foundation 的赞助之下开发(参见 参考资料 了解更多细节)。我们将简要讨论 GRUB 2,主要是使您理解 GRUB 和 GRUB 2 之间的主要区别以及它们是如何共存的。在本文余下部分中,我们将假定 GRUB 即 GRUB Legacy,除非上下文特别暗指 GRUB 2。LILO 的一个新版本 ELILO
(它设计用于启动使用 Intel 的
Extensible Firmware Interface(
EFI)而非 BIOS 的系统)现在也可用。参见
参考资料 了解关于 GRUB 2 和 ELILO 的其他信息。
您的发行版的安装过程也许允许您选择要设置的启动加载程序。GRUB 和 LILO 都能处理多数现代磁盘,尽管有些发行版(特别是 Fedora)不再包含 LILO。不要忘了,磁盘技术已经取得了迅猛发展,因此应该总是确保您选择的启动加载程序、Linux 发行版(或者其他操作系统)以及您的系统 BIOS 能够处理您的新款磁盘。否则,就可能导致数据损失。同样,如果您正在将一个新发行版添加到一个现有系统,您可能需要确保您的 MBR 中有最新的 LILO
或
GRUB。如果您打算从一个 LVM
或
RAID 磁盘启动,那么还需要相当新的 GRUB
或
LILO 版本。
在 LILO 和 GRUB 中使用的阶段 2 加载程序允许您从几个操作系统或版本中选择要加载的系统。但是,LILO 和 GRUB 的差别很大:无论何时您升级内核或对您的系统进行其他更改,对系统的一个更改都需要您重新创建 LILO 启动设置,而 GRUB 能够通过一个您可以编辑的配置文本文件来完成这个任务。GRUB 2 还要求重新构建一个通常存储在 /etc 中的配置文件。
LILO
LILO(即 LInux LOader)是两个最常用的 Linux 启动加载程序之一。可以将 LILO 安装到您的可引导硬盘驱动器的 MBR 中,或者安装到一个分区的分区引导记录中。也可以将它安装到可移动设备上,比如软盘、CD 和 USB 磁盘。如果您还不熟悉 LILO,那么在软盘或 USB 磁盘上练习是一个不错的注意,我们的示例就是这样做的。
在 Linux 安装期间,您通常需要指定 LILO
或
GRUB 为引导程序。如果您选择 GRUB,您可能没有安装 LILO。如果是这样,那么您需要安装它的包。您可能想安装 lilo-doc 包,以便获得其他文档和示例。此后,我们假定您已经安装了 LILO 包。
您使用一个配置文件来配置 LILO,这个配置文件通常是 /etc/lilo.conf。您可以使用 liloconfig 命令(通常位于 /usr/sbin 中)来生成一个启动配置文件,然后根据需要编辑它。清单 1 中的配置文件就是按照这种方式生成的。这个文件的注释比较合理,lilo 和 lilo.conf 的手册页面将向您提供更多帮助。这是一个典型的 LILO 配置文件,可用于包含 Windows 和一个或多个 Linux 系统的双启动系统上。
清单 1. /etc/lilo.conf 示例
# Originally generated by liloconfig - modified by Ian Shields
# This allows booting from any partition on disks with more than 1024
# cylinders.
lba32
# Specifies the boot device (floppy)
boot=/dev/fd0
# Specifies the device that should be mounted as root.
# If the special name CURRENT is used, the root device is set to the
# device on which the root file system is currently mounted. If the root
# has been changed with -r , the respective device is used. If the
# variable ROOT is omitted, the root device setting contained in the
# kernel image is used. It can be changed with the rdev program.
root=/dev/sda7
# Bitmap configuration for /boot/coffee.bmp
bitmap=/boot/coffee.bmp
bmp-colors=12,,11,15,,8
bmp-table=385p,100p,1,10
bmp-timer=38,2,13,1
# Enables map compaction:
# Tries to merge read requests for adjacent sectors into a single
# read request. This drastically reduces load time and keeps the map
# smaller. Using COMPACT is especially recommended when booting from a
# floppy disk.
compact
# Install the specified file as the new boot sector.
# LILO supports built in boot sectors, you only need
# to specify the type, choose one from 'text', 'menu' or 'bitmap'.
# new: install=bmp old: install=/boot/boot-bmp.b
# new: install=text old: install=/boot/boot-text.b
# new: install=menu old: install=/boot/boot-menu.b or boot.b
# default: 'menu' is default, unless you have a bitmap= line
# Note: install=bmp must be used to see the bitmap menu.
# install=menu
install=bmp
# Specifies the number of _tenths_ of a second LILO should
# wait before booting the first image. LILO
# doesn't wait if DELAY is omitted or if DELAY is set to zero.
# delay=20
# Prompt to use certain image. If prompt is specified without timeout,
# boot will not take place unless you hit RETURN. Timeout is in tenths of
# a second.
prompt
timeout=200
# Enable large memory mode.
large-memory
# Specifies the location of the map file. If MAP is
# omitted, a file /boot/map is used.
map=/boot/map
# Specifies the VGA text mode that should be selected when
# booting. The following values are recognized (case is ignored):
# NORMAL select normal 80x25 text mode.
# EXTENDED select 80x50 text mode. The word EXTENDED can be
# abbreviated to EXT.
# ASK stop and ask for user input (at boot time).
# <number> use the corresponding text mode. A list of available modes
# can be obtained by booting with vga=ask and pressing [Enter].
vga=normal
# Defines non-standard parameters for the specified disk.
#disk=/dev/sda
# bios=0x80
# If you are using removable USB drivers (with mass-storage)
# you will need to tell LILO to not use these devices even
# if defined in /etc/fstab and referenced in /proc/partitions.
# Adjust these lines to your devices:
#
# disk=/dev/sda inaccessible
# disk=/dev/sdb inaccessible
# These images were automagically added. You may need to edit something.
image=/boot/vmlinuz-2.6.31-14-generic
label="Lin 2.6.31-14"
initrd=/boot/initrd.img-2.6.31-14-generic
read-only
image=/boot/vmlinuz-2.6.31-20-generic
label="Lin 2.6.31-20"
initrd=/boot/initrd.img-2.6.31-20-generic
read-only
image=/boot/memtest86+.bin
label="Memory Test+"
read-only
# If you have another OS on this machine (say DOS),
# you can boot if by uncommenting the following lines
# (Of course, change /dev/sda1 to wherever your DOS partition is.)
other=/dev/sda6
label="Fedora 8"
other=/dev/sda1
label="Windows XP"
我们将通过创建一个启动软盘来测试我们的配置,因此我们指定靠近文件顶部的 boot=/dev/fd0。我们还将提示超时增加到 20 秒(200 个 0.1 秒增量),并添加了第二个 “other” 条目来链式加载到 Fedora 8 分区上的启动加载程序(/dev/sda6)。LILO 在一个配置文件中只允许一个 root 命令,因此它可以启动根分区中的多个映像,但需要链式加载到另一个启动加载程序来启动另一个不同安装中的映像,比如我们的示例中的 Fedora 8 (/dev/sda6)
或
Windows XP (/dev/sda1)。
您使用 /sbin/lilo 中的 lilo 命令来编写一个阶段 1 引导记录,并使用通常位于 /etc/lilo.conf 中的配置信息(比如上面的示例)来创建一个映像文件(/boot/map)。我们稍后将提到一些辅助用法。
现在,如果我们使用一个 Linux 文件系统(比如 ext2)来格式化一个软盘,我们将运行 lilo 命令(/sbin/lilo)来创建一个可引导软盘。清单 2 显示了我们的输出。注意,lilo 命令拥有 5 个级别的详细程度,为每个级别指定一个额外的 -v 参数。这个示例使用 lilo -v -v 创建。
清单 2. 使用 lilo 创建一个可引导软盘
LILO version 22.8, Copyright (C) 1992-1998 Werner Almesberger
Development beyond version 21 Copyright (C) 1999-2006 John Coffman
Released 19-Feb-2007, and compiled at 10:52:38 on Aug 25 2009
Running Linux kernel 2.6.31-14-generic on i686
Ubuntu
raid_setup returns offset = 00000000 ndisk = 0
BIOS VolumeID Device
Reading boot sector from /dev/fd0
pf_hard_disk_scan: ndevs=1
0800 54085408 /dev/sda
device codes (user assigned pf) = 0
device codes (user assigned) = 0
device codes (BIOS assigned) = 1
device codes (canonical) = 1
mode = 0x03, columns = 80, rows = 25, page = 0
Using BITMAP secondary loader
Calling map_insert_data
Secondary loader: 19 sectors (0x3800 dataend).
Warning: The boot sector and map file are on different disks.
bios_boot = 0x00 bios_map = 0x80 map==boot = 0 map S/N: 54085408
Mapping bitmap file /boot/coffee.bmp
Calling map_insert_file
Compaction removed 592 BIOS calls.
Bitmap: 603 sectors.
BIOS data check was okay on the last boot
Boot image: /boot/vmlinuz-2.6.31-14-generic
Setup length is 26 sectors.
Compaction removed 7452 BIOS calls.
Mapped 7601 sectors.
Mapping RAM disk /boot/initrd.img-2.6.31-14-generic
Compaction removed 14696 BIOS calls.
RAM disk: 14930 sectors.
Added Lin_2.6.31-14 *
Boot image: /boot/vmlinuz-2.6.31-20-generic
Setup length is 26 sectors.
Compaction removed 7468 BIOS calls.
Mapped 7617 sectors.
Mapping RAM disk /boot/initrd.img-2.6.31-20-generic
Compaction removed 14704 BIOS calls.
RAM disk: 14938 sectors.
Added Lin_2.6.31-20
Boot image: /boot/memtest86+.bin
Setup length is 4 sectors.
Compaction removed 243 BIOS calls.
Mapped 254 sectors.
Added Memory_Test+
Boot other: /dev/sda6, loader CHAIN
Pseudo partition start: 43198848
Compaction removed 0 BIOS calls.
Mapped 6 (4+1+1) sectors.
Added Fedora_8
Boot other: /dev/sda1, on /dev/sda, loader CHAIN
Compaction removed 0 BIOS calls.
Mapped 6 (4+1+1) sectors.
Added Windows_XP
BIOS VolumeID Device
80 54085408 0800
Writing boot sector.
/boot/boot.0200 exists - no boot sector backup copy made.
Map file size: 336896 bytes.
RAID device mask 0x0000
One warning was issued.
我们现在拥有了我们的可引导 LILO 软盘。如果 LILO 遇到一个错误,您可能会看到一条错误消息,引导扇区将不被写入。这条错误消息将使您对需要修复的问题有所了解。
如果我们使用刚才创建的软盘并重新启动机器,我们将看到一个类似于图 1 中的提示。注意屏幕顶部的倒数计时器,它从 20 秒向下倒数(200 个 0.1 秒)。如果在 20 秒内没有选择,那么突出显示的选项(第 1 个,本例中的 Lin_2.6.31-14)将自动启动。
图 1. LILO 启动屏幕您可以使用方向键上下移动选择列表。图 2 显示如何选择较新的 Lin_2.6.31-20 内核,它是第二个选项。注意,计时器的值不再显示。按 Enter 键启动这个内核。
图 2. 使用 LILO 选择另一个启动目标当您测试完您的启动软盘后,更改您的 lilo.conf 文件中的 boot=/dev/fd0 条目来安装 MBR
或
一个分区引导记录上的 LILO。例如,boot=/dev/sda 将把 LILO 安装到您的第一个硬盘驱动器的主引导记录中。
现在您已经初步了解了 LILO 及其配置文件。您可以从 lilo 命令行覆盖一些配置选项。使用 man lilo
或
man lilo.conf,您将在 lilo 手册页面中发现更多信息。您还可以在与 lilo
或
lilo-doc 包一起安装的 PostScript 用户指南中发现更多信息。这个用户指南应该安装在您的 documentation 目录中,但具体位置可能根据系统不同而不同。定位这个文件的一种方法是通过 grep 过滤包列表。清单 3 展示了如何定位基于 Debian 的 Ubuntu 9.10 系统的用户指南,本文使用的就是这种方法。
清单 3. 使用 dpkg 定位 LILO 用户指南
ian@pinguino:~$ dpkg -L lilo-doc | grep "ps"
/usr/share/doc/lilo-doc/user.ps.gz
/usr/share/doc/lilo-doc/tech.ps.gz
在一个基于 RPM 的系统(比如 Fedora)上的对应命令为: rpm -ql lilo-doc | grep "ps"
LILO 辅助命令:
LILO 拥有几个辅助命令:
- lilo -q
- 显示映射文件中的信息。
- lilo -R
- 设置 lilo 为只在下一次重新启动时自动启动指定系统。这对于自动重新启动远程系统非常方便。
- lilo -I
- 显示关于一个内核的路径的信息。
- lilo -u
- 卸载 lilo 并恢复此前的引导记录。
当 LILO 启动一个 Linux 系统时,您可能想要在启动时间提供其他参数。例如,如果您的图形启动没有工作,您可能想要启动到模式 3
或
单用户模式中来恢复。如果您选择一个条目并按 TAB 键,您应该能看到一个使用您选择的标签名预先填充的终端窗口,如图 3 所示。在标签名后面键入的任何文本将被传递到内核。例如,在我们的示例中,您将通过向下移动一行并按 TAB 键来选择最新的 Ubuntu 系统。如果您不首先选择一个名称,那么您可能必须键入在标签中指定的全名。您会发现使用比我们的示例更简单的标签可能是一个好主意:键入完整的 Lin_2.6.31.20 会很麻烦。
图 3. 使用 LILO 添加内核参数在图 3 中,我们添加 “single” 到启动参数,表明我们想启动到单一用户模式来进行某种系统恢复。参阅 恢复 小节,了解关于使用启动参数的更多信息。
还记得吗,使用 LILO 时,无论何时更新配置文件(/etc/lilo.conf),都必须 运行 lilo 命令。如果您添加、移动或删除分区,或者进行其他可能会使生成的启动加载程序失效的更改,也需要运行 lilo 命令。
GRUB
GRUB(即 GRand Unifood Boot loader)是两个最常用的 Linux 启动加载程序的另外一个。与 LILO 相似,GRUB 可以安装到您的可启动硬盘驱动器的 MBR 中,或者安装到一个分区的分区引导记录中。它还可以安装到可移动设备中,比如软盘、CD 和 USB 磁盘。如果您还不熟悉 GRUB,那么在一张软盘或 USB 磁盘上进行练习是一个好主意,我们的示例就是这样做的。
GRUB,或 GNU GRUB,现在在 Free Software Foundation 的赞助下开发。作为一个新版本,GRUB 2 还处于开发之中,并开始包含在 Linux 发行版中,因此原始的 GRUB 0.9x 版本现在称为 Grub Legacy。
在 Linux 安装期间,您通常需要指定 LILO
或
GRUB 为引导程序。如果您选择 LILO,您可能没有安装 GRUB。如果是这样,那么您需要安装它的包。此后,我们假定您已经安装了 GRUB 包。
GRUB(Legacy)拥有一个通常存储在 /boot/grub/grub.conf 中的配置文件。如果您的文件系统支持符号链接,就像大多数 Linux 文件系统一样,那么您可能拥有一个链接到 /boot/grub/grub.conf 的符号链接 /boot/grub/menu.lst。
grub 命令(/sbin/grub,或者在某些系统上为 /usr/sbin/grub)是一个小型、但比较强大的 shell,支持几个命令来安装 GRUB,启动系统,定位或显示配置文件,以及完成类似的任务。这个 shell 与第二阶段 GRUB 启动加载程序共享很多代码,这一点很有用,因为无须启动到第二阶段 GRUB 环境就可以了解 GRUB。GRUB 阶段 2 可以以菜单模式
运行,支持从菜单选择一个操作系统;也可以以
命令模式 运行,支持指定单独的命令来加载一个系统。还有其他命令,比如 grub-install,该命令使用 grub shell 并帮助自动化安装 GRUB 等任务。
清单 4 显示了部分 GRUB 配置文件。当您阅读代码时,要记住一件重要的事:GRUB,至少是 GRUB Legacy,从 0 而不是 1 开始计数驱动器、分区和其他需要计数的东西。还要注意,第一个内核行非常长。我们使用一个反斜杠(\)来表明为了版面需要而中断它的地方。
清单 4. /boot/grub/menu.lst GRUB 配置示例
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,5)
# kernel /boot/vmlinuz-version ro root=/dev/sda6
# initrd /boot/initrd-version.img
#boot=/dev/sda6
default=1
timeout=10
splashimage=(hd0,5)/boot/grub/splash.xpm.gz
#hiddenmenu
password --md5 $1$RW1VW/$4XGAklxB7/GJk0uO47Srx1
title Upgrade to Fedora 11 (Leonidas)
kernel /boot/upgrade/vmlinuz preupgrade \
repo=hd::/var/cache/yum/preupgrade stage2=\
hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/install.img \
ks=hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/ks.cfg
initrd /boot/upgrade/initrd.img
title Fedora (2.6.26.8-57.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.8-57.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.8-57.fc8.img
title Fedora (2.6.26.6-49.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.6-49.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.6-49.fc8.img
title GRUB Menu
rootnoverify (hd0,1)
chainloader +1
title Windows
rootnoverify (hd0,0)
chainloader +1
与 LILO 配置文件一样,上面的第一组选项控制 GRUB 的操作方式。对于 GRUB 来说,这些选项称为菜单命令
,它们必须出现在其他命令前面。剩下的部分向我们想要允许 GRUB 启动的操作系统提供每映像(per-image)选项。注意,“title” 被认为是一个菜单命令。每个标题实例后面是一个或多个一般或菜单条目命令。我们的 LILO 示例是一个典型的包含 Windows 和两个 Linux 系统的双启动系统的基础示例。这个示例来自于我们前面使用的相同系统。事实上,它是从 LILO 菜单中的 “Fedora 8” 条目链式加载而来的启动菜单。您将发现,许多相同种类的元素同时出现在 LILO 和 GRUB 配置文件中。您可能会思考这个问题:如果您将这里的操作系统添加到前面的 LILO 示例中,需要进行什么更改?
在我们的示例的所有其他部分应用的菜单命令包括:
#
以 # 开头的所有行都是注释,GRUB 将对它们置之不理。这个特殊的配置文件最初由 Red Hat 安装程序 anaconda 生成。如果您在安装 Linux 时安装 GRUB,您可能会发现您的 GRUB 配置文件添加了一些注释。这些注释通常用于帮助系统升级程序,以便您的 GRUB 配置能够与升级后的内核保持同步。当您亲自编辑这个配置文件时,一定要注意为此目的而保留下来的任何标记。
default 指定用户在超时范围内没有做出任何选择时加载的系统。在我们的示例中,default=2 表示加载第三个条目。不要忘了,GRUB 从 0 而不是 1 开始计数。如果没有指定,那么默认值是启动第一个条目,条目编号为 0。
timeout 指定启动默认条目前的超时,以秒为单位。注意,LILO 以 0.1 秒作为超时单位,而 GRUB 使用 1 秒为超时单位。
splashimage 指定将与启动菜单一起显示的背景(或
splash)映像。GRUB 将第一个硬盘驱动器称为 (hd0),将该驱动器上的第一个分区称为 (hd0,0)。因此,splashimage=(hd0,6)/boot/grub/splash.xpm.gz 表示使用位于第一个硬盘驱动器的第 7 个分区上的文件 /boot/grub/splash.xpm.gz。注意,这个映像是一个使用 gzip 压缩的 XMP 文件。对 splashimage 的支持是一个补丁,您的发行版可能不包含它。
password 指定用户在能够解锁菜单并编辑一个配置行或输入 GRUB 命令前必须输入的密码。与 LILO 一样,这个密码可能是明文格式。GRUB 还允许将密码存储为一个 MD5 摘要,我们的示例就是这样做的。这样更安全一些,大多数管理员都会设置一个密码。如果不设置密码,用户就能够完全访问 GRUB 命令行。
我们的示例展示了两个 Fedora 8 内核,一个 “升级到 Fedora 11” 选项,Windows XP,以及一个链式加载的 “GRUB Menu” 选项。这些部分中使用的命令是:
- title
- 这是一个描述性标题,当 Grub 启动时显示为菜单项。您使用方向键上下移动标题列表并按 Enter 键选择一个特殊的条目。
- root
- 指定将被启动的分区。与 splashimage 一样,计数从 0 开始,因此指定为根 (hd0,6) 的第一个 Red Hat 系统实际上是在第一个硬盘驱动器的第 7 个分区上(本例中为 /dev/hda7),而指定为根 (hd1,10) 的第一个 Ubuntu 系统位于第二个硬盘驱动器上。GRUB 将尝试加载这个分区以检查它,并在某些情况下向启动的操作系统提供一些值。
- kernel
- 指定将被加载的内核映像以及任何必要的内核参数。这类似于结合使用 LILO 映像和一些附加命令。在本例中,我们拥有两个不同的 Fedora 8 内核,以及升级内核。
- initrd
- 初始 RAM 磁盘
的名称,包含您的文件系统被加载之前内核需要的模块。
- savedefault
- 本示例没有使用。如果菜单命令
default=saved 被指定,且
savedefault 命令针对一个操作系统被指定,那么操作系统将导致它变为默认值,直到指定了
savedefault 的另一个操作系统被启动。在这个示例中,default=2 将覆盖任何保存的默认值。
- boot
- 是一个可选参数,指示 GRUB 启动选中的操作系统。这是一个选项的所有命令都被处理时的默认动作。
- lock
- 本示例没有使用。这将不会启动指定的条目,直到输入一个密码。如果使用这个命令,那么还应该在初始选项中指定一个密码;否则,一个用户能够编辑您的锁定选项并启动系统,或者添加 “single” 到其中的一个条目。如果愿意,可以为单独的条目指定一个不同的密码。
- rootnoverify
- 类似于 root,除非 GRUB 不尝试加载文件系统或验证它的参数。这通常可用于 GRUB 不支持的文件系统,比如 NIFS。如果您想要 GRUB 加载一个硬盘驱动器上的主引导记录,以便(例如)访问一个不同的配置文件或者重新加载您的此前的启动加载程序,那么您可能会使用这个命令。
- chainloader
- 指定另一个文件将被加载为一个阶段 1 文件。值 “+1” 等同于 0+1,表示加载从扇区 0 开始的一个扇区,即,从由 root
或
rootnoverify 指定的设备加载第一个扇区。
现在,您已经对一个典型的 /boot/grub/grub.conf(或 /boot/grub/menu.lst)文件中可能包含的内容有所了解。还有许多其他 GRUB 命令,可以提供对启动过程的广泛控制,以及帮助安装 GRUB 和完成其他任务。您可以在 GRUB 手册中了解关于这些命令的更多信息,可以通过在您的系统上运行 info grub 命令来获取这个手册。
现在我们拥有了一个 GRUB 配置文件,我们需要创建一个启动软盘来测试它。最简单的方法是使用清单 5 中展示的 grub-install 命令。如果您正在将 GRUB 安装到一个软盘或一个分区上,那么您应该首先卸载该设备。这不适用于将 GRUB 安装到一个硬盘驱动器的 MBR 上,因为您只加载分区(/dev/sda1、/dev/sda2 等)而不是整个硬盘驱动器(/dev/sda)。
清单 5. 将 GRUB 安装到一张软盘
[root@pinguino ~]# grub-install /dev/fd0
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
(fd0) /dev/fd0
(hd0) /dev/sda
注意:您可能使用 GRUB 设备名 (fd0) 而不是 /dev/fd0,但是如果您的确那样做,则必须用引号括起它,以免 shell 解释圆括号。例如: grub-install '(fd0)'
设备映射告诉您 GRUB 如何将您的磁盘的内部视图 (fd0, hd0, hd1) 匹配到 Linux 视图 (/dev/fd0, /dev/sda, /dev/sdb)。在带有一个或两个 IDE 硬盘驱动器以及可能还有一个软盘驱动器的系统上,这可能是正确的。如果一个设备映射已经存在,那么 GRUB 将重新使用它,无需探测。如果您只是添加一个新驱动器并想强制生成一个新设备映射,那么添加 --recheck 选项到 grub-install 命令。有时,您可能会看到一条如清单 6 所示的消息。在这个示例中,您还需要添加 --recheck 选项到 grub 命令,以强制 GRUB 探测可用设备并重新构建一个设备映射。
清单 6. 将 GRUB 安装到一张软盘
[root@pinguino ~]# grub-install /dev/fd0
/dev/fd0 does not have any corresponding BIOS drive.
如果您使用一张空白软盘开始并且现在加载它,那么您将发现该软盘现在仍然是空白。所发生的事是 GRUB 将一个自定义的阶段 1 加载程序写入该软盘的第一个扇区。这不在文件系统中显示。这个阶段 1 加载程序将从您的硬盘驱动器加载阶段 2 和配置文件。尝试启动软盘,您将看到您的菜单显示之前有很少的 IO 活动。与 LILO 一样,您使用上下方向键来选择不同的启动目标。
图 4. 使用 GRUB 启动测试完您的启动软盘后,就可以在您的硬盘驱动器的 MBR 中安装 GRUB 了。对于第一个 IDE 硬盘驱动器,您应该使用:
grub-install /dev/sda
或
grub-install '(hd0)'
要将它安装到分区 11 的分区引导记录,使用:
grub-install /dev/sda11
或
grub-install '(hd0,10)'
别忘了 GRUB 从 0 开始计数。
与 LILO 一样,可以添加启动参数。事实上,您可以编辑 GRUB 配置中的任意命令,或者甚至在启动时加载另一个配置文件。如果您使用一个密码,您将需要输入 p 命令,然后输入您的密码。然后,您选择一个条目并输入 e 命令来编辑它。选择想要编辑的行并再次输入 e。通过输入新的字符或删除现有字符编辑这一行,然后按 Enter 键返回菜单。输入 b 命令以使用修改后的值启动您的系统。图 5 展示这个过程的命令编辑阶段,其中您将 “single” 添加到内核语句以启动到单用户模式中。
图 5. 使用 GRUB 启动到单用户模式
系统更新
大多数发行版提供一些工具来更新系统。这些工具通常能意识到正在使用的启动加载程序,并将自动更新您的配置文件。如果您构建您自己的自定义内核,或者愿意使用一个带有非标准名称或位置的配置文件,那么您可能需要亲自更新配置文件。
- 如果您使用 LILO,那么无论何时您更新您的配置文件或进行添加一个硬盘驱动器或删除一个分区这样的更改,都必须运行 lilo 命令。
- 如果您使用 GRUB,您可以编辑 /boot/grub/grub.conf 文件来进行您的更改,GRUB 阶段 2 加载程序将在您重新启动时读取这个文件。您通常不需要只因为添加一个新内核而重新安装 GRUB。但是,如果您移动一个分区,或者添加一些驱动器,那么您可能需要重新安装 GRUB。别忘了阶段 1 加载程序非常小,它只拥有阶段 2 加载程序的一列块地址。移动分区和已处理更改,以便阶段 1 可以不再定位阶段 2。我们稍后将介绍一些恢复策略,并讨论 GRUB 的阶段 1.5 加载程序。
- 如果您在不同的分区内运行多个 Linux 系统.
恢复
现在我们来看一些您仔细准备的启动设置可能会出错的地方,特别是当您安装并启动多个操作系统时。需要记住的第一点是抵制您的初始恐慌冲动。恢复通常很简单。这里介绍的一些策略可以帮助您渡过各种危机。
能够对一台机器进行物理访问的任何人都拥有许多权力。同样,对一个 GRUB 命令行拥有访问权的任何人也能访问您的系统上的文件,这对一个运行系统提供的任何所有权或其他安全条款来说并不是一件好事。当您选择您的启动加载程序时一定要牢记这些问题。对于 LILO 和 GRUB 的选择主要是一个个人喜好问题。选择最适合您的特殊需求和工作方式的加载程序。
另一个安装会损坏您的 MBR
有时您将安装另一个操作系统并在无意中覆盖您的 MBR。有些系统,比如 DOS 和 Windows,总是安装它们的 MBR。通常很容易就能从这种情况恢复。如果您养成在每次运行 lilo
或
重新安装 GRUB 时都创建一张启动软盘的习惯,那么您就会免除很多烦恼。只需从该软盘启动到您的 Linux 系统并重新运行 lilo
或
grub-install 即可。
如果您没有一张启动软盘,但是仍然拥有几乎所有 Linux 发行版,那么您通常可以在一个恢复模式中启动 Linux 安装媒体。当您这样做时,您的硬盘驱动器上的根文件系统将要么在某个奇怪的恢复点被加载,要么完全不被加载。您可以使用 chroot 命令来使这个奇怪的加载点变为您的根目录(/)。然后运行 lilo
或
grub-install 来创建一张新的启动软盘或重新安装 MBR。我喜欢创建一张软盘并使用它来启动,这样能够确保我在继续操作并重写 MBR 之前一切正常,但您可能比我更具勇气。以还原模式启动一张 CD
或
DVD 可能会向您提供一个选项菜单,或者可能只是使您进入拥有根权限的单用户模式。如果您试图将我们在 LILO 示例中使用的 Ubuntu 9.10 系统启动到单用户模式,您将看到一个如图 6 所示的菜单。突出显示的选项将使您进入一个带有网络连接的根 shell。
图 6. Ubuntu 9.10 恢复菜单这样的一个菜单是还原媒体的一个常用选择。对于我们的还原示例,我们不使用一张 CD,而是将 Ubuntu 9.19 系统启动到在前面的关于 LILO 的小节中描述的单用户模式。然后,我们逐步执行为另一个系统(这里是 /dev/sda6 上的 Fedora 8 系统)创建一张启动软盘的典型步骤。无论您从一张还原 CD
或
相同的系统上的另一个 OS 启动,这些步骤都是相似的,但是可能已经为您完成了某些步骤(比如加载将被还原的映像)。
当您最终到达一个根提示时,您可能想要执行清单 7 中的全部或部分代码。对于我们的示例,我们创建一个加载点(/mnt/sysimage),在这个新的根中加载一些特殊的文件系统,然后 chroot 到已加载的系统。cat /etc/issue 命令展示 chroot 命令的效果,这使得目标目录成为文件系统的新的根,至少在我们使用 Ctrl-d
或
exit 命令退出执行了 chroot 的环境之前是这样的。
清单 7 展示了我们在此前的配置示例中使用的相同环境中的一个示例。将这个示例视为您作为根用户登录的一个终端窗口。换句话说,要小心对待即将写入您的硬盘驱动器的内容。
清单 7. 使用一个还原系统并 chroot
root@pinguino:~# mkdir /mnt/sysimage
root@pinguino:~# mount /dev/sda6 /mnt/sysimage
root@pinguino:~# cd /mnt/sysimage
root@pinguino:~# mount -t proc none proc/
root@pinguino:~# mount -t sysfs none sys/
root@pinguino:~# mount -o bind /dev dev/
root@pinguino:~# cat /etc/issue
Ubuntu 9.10 \n \l
root@pinguino:~# chroot /mnt/sysimage
root@pinguino:~#
sh-3.00# chroot /mnt/sysimage
[root@oinguine /]# cat /etc/issue
Fedora release 8 (Werewolf)
Kernel \r on an \m
[root@oinguine /]# grub-install /dev/fd0
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
(fd0) /dev/fd0
(hd0) /dev/sda
[root@oinguine /]#
当您拥有您的可启动软盘之后,按下 Ctrl-d 键退出 chroot 环境并重新启动您的系统,别忘了移除您可能使用过的任何安装 CE
或
恢复媒体。如果您碰巧没有方便的安装 CD
或
DVD,那么可以使用许多在线提供的实时恢复 LINUX CDs,或者一些软盘或 USB 磁盘。请参见
参考资料 了解更多细节。
尽管超出了本文的范围,您可能想了解这一点:也可以使您的 MBR 启动一个 Windows 2000
或
Windows XP 系统,并在一个分区引导记录上安装 LILO
或
GRUB。ntldr 启动程序也可以链式加载其他引导扇区,但是设置可能比较麻烦。您需要将这个引导扇区复制到一个 Windows 分区(通常使用 dd 命令)并修改隐藏的 boot.ini 文件来实现上述操作。
移动一个分区
如果您移动了一个分区且忘记了您的启动设置,您就会遇到一个意外问题。通常, LILO 和 GRUB 会拒绝加载。LILO 可能会打印一个 “L”,表明阶段 1 被加载,然后停止运行。这里发生的事情是:阶段 1 加载程序(它需要加载一列扇区以达到阶段 2 加载程序)可能从它拥有的地址加载一些扇区,但这些扇区不再拥有阶段 2 签名。如果您使用此前介绍的方法来构建一张启动软盘,别忘了 lilo
或
grub-install 放置到该软盘上的全部内容是一个单一的启动扇区,因此您的启动软盘也可能帮不上忙。那么重新启动,检查您的系统并在您的 MBR 中重新安装您的启动加载程序。
您可能已经注意到,我们的配置示例对分区使用一些标签和 UUIDs (Universally Unique IDs)。例如:
kernel /boot/vmlinuz-2.6.26.8-57.fc8 ro root=LABEL=FEDORA8 rhgb quiet
或
kernel /boot/upgrade/vmlinuz preupgrade repo=hd::/var/cache/yum/preupgrade stage2=\
hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/install.img \
ks=hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/ks.cfg
当我移动分区时,我经常使用这样的 UUIDs 来帮助避免问题。您仍然需要更新 GRUB
或
LILO 配置文件并重新运行 lilo,但是您不必更新 /etc/fstab。当您在一个系统上创建一个分区映像,并在另一个系统上的一个不同位置上恢复该映像时,这尤其方便。当您从一个驱动器(比如一个 USB 驱动器)启动且该驱动器并不总是连接在相同的位置时,这也很方便。
使用引导分区
用于恢复(或者可能是避免)它的另一种方法是使用一个独立的分区来启动。当您拥有一个测试系统,系统上有几个发行版且您可能需要频繁重新构建该系统时,这种方法尤其有用。这个引导分区不必非常大,大约 100MB 左右即可。但是这个分区应该不太可能被移动,且不太可能由于添加或删除另一个分区而影响它的分区编号。在一个混合 Windows 和 Linux 环境中,/dev/sda2(或者 /dev/hda2,取决于您的磁盘的标签设置方式)通常是一个不错的引导分区的选择。清单 8 展示了一个小型引导分区(/dev/sda2)中的条目,这个分区实际上由我们一直作为示例使用的系统上的主引导记录加载。
清单 8. 通过 GRUB 使用一个小型引导分区
# menu.lst - See: grub(8), info grub, update-grub(8)
# grub-install(8), grub-floppy(8),
# grub-md5-crypt, /usr/share/doc/grub
# and /usr/share/doc/grub-doc/.
## default num
# Set the default entry to the entry number NUM. Numbering starts from 0, and
# the entry number 0 is the default if the command is not used.
#
# You can specify 'saved' instead of a number. In this case, the default entry
# is the entry saved with the command 'savedefault'.
default 0
## timeout sec
# Set a timeout, in SEC seconds, before automatically booting the default entry
# (normally the first entry defined).
timeout 10
## password ['--md5'] passwd
# If used in the first section of a menu file, disable all interactive editing
# control (menu entry editor and command-line) and entries protected by the
# command 'lock'
# e.g. password topsecret
# password --md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
# password topsecret
title Fedora 8 (sda6) Grub menu
root (hd0,5)
chainloader +1
boot
# Ubuntu 9.10 uses GRUB 2, so use kernel to drive GRUB 2 menu.
title Ubuntu 9.10 (sda7)
root (hd0,6)
kernel /boot/grub/core.img
# This is a divider, added to separate the menu items below from the Debian
# ones.
title Other operating systems:
root
# Windows XP
title Windows NT/XP
root (hd0,0)
savedefault
chainloader +1
当您的根分区使用一个您的启动加载程序不支持的文件系统时,也需要拥有一个引导分区。例如,当根分区(/)使用 GRUB Legacy 不支持的 LVM 时,将 /boot 分区格式化为 ext2
或
ext3 非常常见。
如果您的系统上拥有多个发行版,不要 在它们之间共享 /boot 分区。记住将 LILO
或
GRUB 设置为从稍后将作为 /boot 加载的分区启动。还要记住一点:一个发行版的更新程序通常将会更新该系统的 GRUB
或
LILO 配置。在一个包含多个系统的环境中,您可能想要将一个带有其自己的 /boot 分区的系统作为主系统,并在您的一个系统需要配置文件时手动更新该文件。另一种方法是使每个系统都安装一个启动加载程序到它自己的分区引导记录中并使您的主系统为这些单独的系统链式加载分区引导记录,从而向您提供一个两阶段菜单过程。
构建一个自含式启动软盘或 CD-ROM
最后,我们将更仔细地检查 GRUB,以及如何构建一个独立的软盘或 CD,它们将使您到达一个 GRUB 提示,无论您的硬盘驱动器出现了什么情况。
还记得关于硬盘上的柱面的知识吗?即使您将柱面视作带有现代驱动器的虚构实体,您的文件系统的许多方面还涉及到它们。特别是,您将发现分区使用几个必不可少的在柱面边界上对齐的柱面。在一个分区内部,许多文件系统还以柱面作为单位来管理空间。在许多 UNIX® 和 Linux 系统上,文件系统的布局存储在一个超块(superblock)中,它是文件系统的第一个分配单元。对于 ext2
或
ext3 这样的文件系统和相对较大的硬盘驱动器,空间将被分割为几个区域,每个区域的开始部分有一个超块副本。如果您不小心使用 fdisk 这样的程序混淆了分区边界,这将有助于恢复。
柱面思想的另一个好处是 MBR 后面的磁盘的开始处有一些空间。GRUB 通过以下方式来利用这个好处:在这个空间中嵌入一个阶段 1.5 启动加载程序,或者在可能时将其放置在一个分区上的类似的未使用空间中。这个阶段 1.5 加载程序理解包含阶段 2 的分区上的文件系统,因此能够在一定程度上更好地保护系统免受正在被移动的文件的影响。
这样的确不错,但它如何关联到一张可启动软盘呢?的确,软盘没有太多空间,也没有多少柱面概念,因此,如果您想要从一张软盘同时启动 GRUB 的阶段 1 和阶段 2,您需要安装阶段 1 并将阶段 2 复制到引导扇区后面的扇区。清单 9 展示了这样一个示例。使用一张空白软盘,因为这个过程将损坏数据。您应该复制您的 GRUB 发行版带有的文件而不是来自您的 /boot/grub 目录的文件,因为 /boot/grub/stage2 已经被修改为使用您的硬盘驱动器分区。您可以在 /usr/share/grub 目录的一个子目录中找到原始的 stage1 和 stage2 文件。在我们的示例中,它们位于 /usr/share/grub/i386-redhat 中。
清单 9. 创建一张 GRUB 启动软盘
[root@pinguino ~]# ls /usr/share/grub/
i386-redhat
[root@pinguino ~]# cd /usr/share/grub/i386-redhat/
[root@pinguino i386-redhat]# ls -l st*
-rw-r--r-- 1 root root 512 2008-05-28 12:05 stage1
-rw-r--r-- 1 root root 109212 2008-05-28 12:05 stage2
-rw-r--r-- 1 root root 109212 2008-05-28 12:05 stage2_eltorito
[root@pinguino i386-redhat]# dd if=stage1 of=/dev/fd0 bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.29007 s, 1.8 kB/s
[root@pinguino i386-redhat]# dd if=stage2 of=/dev/fd0 bs=512 seek=1
213+1 records in
213+1 records out
109212 bytes (109 kB) copied, 7.4094 s, 14.7 kB/s
[root@lyrebird root]# ls /usr/share/grub
i386-redhat
[root@lyrebird root]# cd /usr/share/grub/i386-redhat
[root@lyrebird i386-redhat]# ls -l st*
-rw-r--r-- 1 root root 512 Aug 3 2004 stage1
-rw-r--r-- 1 root root 104092 Aug 3 2004 stage2
[root@lyrebird i386-redhat]# dd if=stage1 of=/dev/fd0 bs=512 count=1
1+0 records in
1+0 records out
[root@lyrebird i386-redhat]# dd if=stage2 of=/dev/fd0 bs=512 seek=1
203+1 records in
203+1 records out
如果您在执行这个操作之前使用的是一张由 MS-DOS 格式化的软盘,且您现在试图加载这张软盘,那么 mount 命令将产生一个错误。将 stage2 复制到这张软盘的引导扇区(seek=1)的后面将损坏您的软盘上的文件系统。
创建一个可引导的 GRUB CD 的方法基本相似,但是您在您的硬盘驱动器上准备这个 CD 映像。您将需要一个临时目录,比如 grubcd,并包含子目录 boot 和 boot/grub。然后,您需要将 stage2_eltorito 文件从您的 GRUB 发行版复制到您刚刚创建的 grub 子目录中。然后使用 genisoimage 来创建一个可引导的 .iso 映像文件,您可以使用您喜欢的刻录工具来将该文件刻录到 CD 中。清单 10 展示了如何将这个 CD 映像创建为 grubcd.iso。
清单 10. 创建一个 GRUB 可引导 CD 映像
[ian@pinguino ~]$ mkdir -p grubcd/boot/grub
[ian@pinguino ~]$ cp /usr/share/grub/i386-redhat/stage2_eltorito grubcd/boot/grub
[ian@pinguino ~]$ genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot \
> -boot-load-size 4 -boot-info-table -o grubcd.iso grubcd
I: -input-charset not specified, using utf-8 (detected in locale settings)
Size of boot image is 4 sectors -> No emulation
Total translation table size: 2048
Total rockridge attributes bytes: 760
Total directory bytes: 4576
Path table size(bytes): 34
Max brk space used 0
233 extents written (0 MB)
您可以在任意一台 PC 上启动 CD
或
软盘;PC 上不需要有一个 Linux 系统。如果您现在启动该软盘,您将注意到一个延迟,这时它正在从软盘加载阶段 2。类似地,如果您启动 CD,它将从 CD 加载 GURB shell。不管您启动哪一个,您都将会得到一个 GRUB 启动提示。按 Tab 键查看您可用的命令列表。尝试 help commandname 命令,获取关于
commandname 命令的帮助。清单 11 展示了 GRUB 命令行。
清单 11. GRUB 命令行
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
grub>
Possible commands are: blocklist boot cat chainloader clear cmp color configfile
debug device displayapm displaymem dump embed find fstest geometry halt help
hide impsprobe initrd install ioprobe kernel lock makeactive map md5crypt
module modulenounzip pager partnew parttype password pause quit read reboot
root rootnoverify savedefault serial setkey setup terminal terminfo testload testvbe
unhide uppermem vbeprobe
grub> help rootnoverify
rootnoverify: rootnoverify [DEVICE [HDBIAS]]
Similar to `root', but don't attempt to mount the partition. This
is useful for when an OS is outside of the area of the disk that
GRUB can read, but setting the correct root device is still
desired. Note that the items mentioned in `root' which derived
from attempting the mount will NOT work correctly.
grub> find /boot/grub/grub.conf
(hd0,1)
(hd0,5)
grub>
在这个示例中,我们已经发现,在我们的第一个硬盘驱动器的两个不同分区上有一些 GRUB 配置文件。我们可以使用 configfile 命令从其中一个配置文件加载 GRUB 菜单。例如:configfile (hd0,1)/boot/grub/grub.conf
这将加载那个配置文件的菜单,我们可以从这个点启动系统。您可以在 GRUB 手册中深入了解这些 grub 命令。尝试在一个 Linux 终端窗口中输入 info grub 命令来打开这个手册。
下面是我们结束 GRUB 介绍之前的最后一点。前面讲过,阶段 2 GRUB 文件会损坏软盘上的文件系统。如果您想要创建一个从软盘加载 GRUB 文件(包括一个配置文件)的可引导 GRUB 恢复软盘,可以通过以下步骤来完成这个任务:
- 使用 mkdosfs 命令在软盘上创建一个 DOS FAT 文件系统,并使用 -R 选项来为阶段 2 文件保留足够的扇区。
- 加载软盘。
- 在软盘上创建一个 /boot/grub 目录。
- 将 GRUB stage1、stage2 和 grub.conf 文件复制到软盘上的 boot/grub 目录。如果想要,也可以复制您的 splash 映像文件。
- 编辑软盘上的 grub.conf 文件,以便它引用软盘上的 splash 文件。
- 卸载软盘。
- 使用 grub 命令 shell 中的 GRUB root 和 setup 命令在软盘上设置 GRUB。
清单 12 展示了这个过程。
清单 12. 在包含一个文件系统的软盘上安装 GRUB
[root@pinguino ~]# mkdosfs -R 220 /dev/fd0
mkdosfs 2.11 (12 Mar 2005)
[root@pinguino ~]# mkdir /mnt/floppy
[root@pinguino ~]# mount /dev/fd0 /mnt/floppy
[root@pinguino ~]# mkdir -p /mnt/floppy/boot/grub
[root@pinguino ~]# cp /boot/grub/stage1 /mnt/floppy/boot/grub
[root@pinguino ~]# cp /boot/grub/stage2 /mnt/floppy/boot/grub
[root@pinguino ~]# cp /boot/grub/splash* /mnt/floppy/boot/grub
[root@pinguino ~]# cp /boot/grub/grub.conf /mnt/floppy/boot/grub
[root@pinguino ~]# umount /dev/fd0
[root@pinguino ~]# grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
grub> root (fd0)
Filesystem type is fat, using whole disk
grub> setup (fd0)
Checking if "/boot/grub/stage1" exists... yes
Checking if "/boot/grub/stage2" exists... yes
Checking if "/boot/grub/fat_stage1_5" exists... no
Running "install /boot/grub/stage1 (fd0) /boot/grub/stage2 p /boot/grub/grub.c
onf "... succeeded
Done.
这个最后的示例也展示了这样一个事实:可以在一个 Linux shell 中运行 grub 命令。这是了解 GRUB 的一种好方法,无需总是重新启动您的机器。您需要根权限才能运行 grub,您能执行 GRUB 可以完成的大部分任务,除了实际重新启动系统。
GRUB 2
GRUB 2 是完全重新编写的,以便使其更模块化并且可移植。它面向多个不同的架构和启动方法,拥有许多新特性。
关于 GRUB 2,您发现的第一件事可能是它不作为一个分区启动加载程序安装。尽管我指出 Ubuntu 安装程序将 GRUB 安装在已安装 Ubuntu 9.10 的分区(/dev/sda7)上,那个分区也不能通过链式加载启动。本小节的剩余部分将简要介绍 GRUB 2,这些信息足以帮助您开始使用它,无论是单独使用还是与 GRUB Legacy 联合使用。
版本 GRUB 2 for PCs 在 grub-pc 包中分发。您将发现几个程序,它们通常位于 .usr/bin
或
/usr/sbin 中,且是 grub-pc 包的一部分,如清单 13 所示。在本文撰写之时,这些程序的手册页面很少。尝试使用 --help 选项来运行这些程序以获得更多信息,或者搜索 Internet 获得其他帮助。
清单 13. /usr/bin 和 /usr/sbin 中的 GRUB 2 可执行文件
ian@pinguino:~$ dpkg -L grub-pc|grep "bin/"
/usr/bin/grub-mkimage
/usr/bin/grub-mkrescue
/usr/sbin/grub-setup
/usr/sbin/update-grub2
/usr/sbin/update-grub
/usr/sbin/grub-install
/usr/sbin/upgrade-from-grub-legacy
/usr/sbin/grub-set-default
/usr/sbin/grub-reboot
GRUB 2 的核心是一个多引导内核(/boot/grub/core.img)和一个配置文件(/boot/grub/grub.cfg)。如果您运行 grub-install 并设置目标为您的 MBR(例如:grub-install /dev/sda),这些文件将自动生成。运行 grub-install --help(如清单 14 所示)来了解被调用来完成所有这些工作的程序。有些程序与 Grub Legacy 类似,但也有一些新程序,比如 --modules、--grub-setup、--grub-mkimage 等。
清单 14. grub-install 的 GRUB 2 帮助
ian@pinguino:~$ grub-install --help
Usage: grub-install [OPTION] install_device
Install GRUB on your drive.
-h, --help print this message and exit
-v, --version print the version information and exit
--modules=MODULES pre-load specified modules MODULES
--root-directory=DIR install GRUB images under the directory DIR
instead of the root directory
--grub-setup=FILE use FILE as grub-setup
--grub-mkimage=FILE use FILE as grub-mkimage
--grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
--grub-probe=FILE use FILE as grub-probe
--no-floppy do not probe any floppy drive
--recheck probe a device map even if it already exists
--force install even if problems are detected
--disk-module=MODULE disk module to use
INSTALL_DEVICE can be a GRUB device name or a system device filename.
grub-install copies GRUB images into the DIR/boot directory specified by
--root-directory, and uses grub-setup to install grub into the boot
sector.
Report bugs to <bug-grub@gnu.org>.
因此,如果您运行 grub-install /dev/sda,这个过程将为您构建一个核心映像文件,构建一个配置文件,并将 GRUB 安装到您的 MBR 中。如果您还没有准备好将您的整个设置提交到 GRUB 2,您可以亲自构建这些部分,然后从 GRUB Legacy
或
LILO 启动 GRUB 2。
构建 GRUB 2 核心映像
构建一个新的核心映像文件的最简单的方法是运行带有 --grub-setup=/bin/true 选项的 grub-install 命令,这将导致 /bin/true 而不是真正的 GRUB 2 安装程序运行,如清单 15 所示。我们首先删除现有的 core.img,以便展示真的生成了这个文件。
清单 15. grub-install 的 GRUB 2 帮助
ian@pinguino:~$ sudo rm /boot/grub/core.img
ian@pinguino:~$ sudo grub-install --grub-setup=/bin/true /dev/sda
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
(hd0) /dev/sda
ian@pinguino:~$ ls -l /boot/grub/core.img
-rw-r--r-- 1 root root 25105 2010-04-08 12:10 /boot/grub/core.img
构建 GRUB 2 配置文件
GRUB 2 配置文件通常是 /boot/grub/grub.cfg。与 GRUB Legacy 不同,您通常不应该编辑这个文件。您应该使用 grub-mkconfig
或
update-grub 命令(它是 grub-mkconfig 的前端)来构建它。这些命令在 /etc/default/grub 中寻找背景、超时等等,然后运行 /etc/grub.d/ 中的可执行文件来构建配置文件的各个部分,比如文件头、一个针对当前 Linux 发行版的区域、几个针对其他操作系统的区域、以及您自己的自定义增加项。如果您需要定制 GURB 2 菜单,您应该将您的更改添加到 /etc/grub.d/ 中的一个文件(比如 40_custom),或者添加您自己的文件。记住,该文件必须是可执行文件。然后,您将运行 update-grub 来生成一个新的 /boot/grub/grub.cfg 文件,如清单 16 所示。
清单 16. 使用 update-grub 构建一个 GRUB 2 配置文件
ian@pinguino:~$ sudo update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-2.6.31-20-generic
Found initrd image: /boot/initrd.img-2.6.31-20-generic
Found linux image: /boot/vmlinuz-2.6.31-14-generic
Found initrd image: /boot/initrd.img-2.6.31-14-generic
Found memtest86+ image: /boot/memtest86+.bin
Found GRUB boot loader on /dev/sda1
Found Fedora release 8 (Werewolf) on /dev/sda6
done
清单 17 展示了结果配置文件中的几个条目。我们已经说过,为了版面美观,我们使用一个后置反斜杠(\)来分割较长的行。注意,menuentry 小节看起来更像 shell 脚本,而不像不带有 GRUB Legacy 逻辑的纯命令。与 GRUB Legacy 不同的另一个变化是现在分区编号从 1 开始,尽管磁盘编号仍然从 0 开始。因此 /dev/sda7 在 GRUB 2 中是 (hd0,7),而在 GRUB Legacy 中则为 (hd0,6)。
清单 17. GRUB 2 配置文件节选
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=white/black
set menu_color_highlight=black/white
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
menuentry "Ubuntu, Linux 2.6.31-20-generic" {
recordfail=1
if [ -n ${have_grubenv} ]; then save_env recordfail; fi
set quiet=1
insmod ext2
set root=(hd0,7)
search --no-floppy --fs-uuid --set 8954fa66-e11f-42dc-91f0-b4aa480fa103
linux /boot/vmlinuz-2.6.31-20-generic \
root=UUID=8954fa66-e11f-42dc-91f0-b4aa480fa103 ro quiet splash
initrd /boot/initrd.img-2.6.31-20-generic
}
menuentry "Ubuntu, Linux 2.6.31-20-generic (recovery mode)" {
recordfail=1
if [ -n ${have_grubenv} ]; then save_env recordfail; fi
insmod ext2
set root=(hd0,7)
search --no-floppy --fs-uuid --set 8954fa66-e11f-42dc-91f0-b4aa480fa103
linux /boot/vmlinuz-2.6.31-20-generic
root=UUID=8954fa66-e11f-42dc-91f0-b4aa480fa103 ro single
initrd /boot/initrd.img-2.6.31-20-generic
}
从 Grub Legacy 启动 GRUB 2
如前所述,您不能从一个分区引导记录链式加载 GRUB 2。但是,当您构建您的核心映像和配置文件之后,您可以添加一个条目到您的 GRUB Legacy grub.conf
或
menu.lst 文件以启动 GRUB 2 核心映像,该映像然后将显示您构建的 GRUB 2 菜单。清单 18 展示了在清单 8 中已经使用过的条目。由于这个配置文件针对 GRUB Legacy,根条目将 /dev/sda7 指定为 (hd0,6)。
清单 18. 将启动 GRUB 2 核心映像的 Grub Legacy 配置条目
# Ubuntu 9.10 uses GRUB 2, so use kernel to drive GRUB 2 menu.
title Ubuntu 9.10 (sda7)
root (hd0,6)
kernel /boot/grub/core.img
当您从您的 GRUB Legacy 菜单选择这个条目时,您将看到一个类似于图 7 的菜单,其中第一个条目被突出显示,后面的条目在清单 17 中展示过。
图 7. GRUB 2 菜单示例您可能会企图尝试在一个分区引导记录中安装 GRUB 2。如果这样,您可能会看到与清单 19 类似的输出。
清单 19. 试图将 GRUB 2 安装到一个分区引导记录中
ian@pinguino:~$ sudo grub-install /dev/sda7
grub-setup: warn: Attempting to install GRUB to a partition instead of the MBR.
This is a BAD idea.
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.
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
(hd0) /dev/sda
这解释了当我安装 Ubuntu 9.10 时试图在 /dev/sda7 中安装 GRUB 2 为什么会失败。有一点值得注意,这个版本的 Ubuntu 将把 GRUB 2 安装为一个新安装,但如果您正在升级现有的 Ubuntu 安装,它将保留现有的引导程序。
GRUB 2 的还原媒体
GRUB 2 带有一个 grub-mkrescue 命令,以帮助您创建一个还原软盘或 CD 映像。请参阅帮助或手册页面了解细节信息。
结束语
现在,您已经学习了传统 Linux 系统的两个主要的启动加载程序,包括如何从错误和启动问题恢复。您还简要了解了 GRUB 2,它目前不包含在 LPI 目标中,但它开始出现在主要的 Linux 发行版中。