29.3. 使用 GRUB 引导

GRUB (Grand Unified Bootloader) 由两段组成。stage1 包含 512 个字节,将被写入硬盘分区的 MBR 或引导扇区,或者软盘中。随后,装载 stage2。此段包含实际程序代码。第一段的唯一任务就是装载引导装载程序的第二段。

stage2 可以访问文件系统。当前,支持 Ext2、Ext3、ReiserFS、Minix,以及 Windows 使用的 DOS FAT 文件系统。在某种程度上还支持 BSD 系统使用的 JFS、XFS、UFS 和 FFS。从版本 0.95 开始,GRUB 还能够从包含 ISO 9660 标准文件系统、符合“El Torito”规范的 CD 或 DVD 进行引导。即使是在引导系统之前,GRUB 也可以访问支持的 BIOS 磁盘设备(BIOS 检测到的软盘或硬盘、CD 驱动器和 DVD 驱动器)的文件系统。因此,对 GRUB 配置文件 (menu.lst) 进行更改不要求重安装引导管理器。当引导系统时,GRUB 重装载菜单文件以及内核或初始 RAM 磁盘 (initrd) 的有效路径和分区数据,并对这些文件进行定位。

GRUB 的实际配置是基于三个文件进行的,下面对这三个文件进行介绍:

/boot/grub/menu.lst

此文件包含有关可通过 GRUB 进行引导的分区或操作系统的所有信息。没有这些信息就无法将系统控制传递到操作系统。

/boot/grub/device.map

此文件将 GRUB 和 BIOS 符号中的设备名转换为 Linux 设备名。

/etc/grub.conf

此文件包含 GRUB shell 正确安装引导装载程序所需的参数和选项。

可以通过多种方式控制 GRUB。可以在图形菜单(启动屏幕)中选择现有配置的引导项。配置是从文件 menu.lst 装载的。

在 GRUB 中,在引导前可以更改所有引导参数。例如,可以通过这种方式更正编辑菜单文件时出现的错误。还可以通过输入提示以交互的方式输入引导命令(请参见第 29.3.1.3 节 “在引导过程中编辑菜单项”)。GRUB 能够在引导前确定内核和 initrd 的位置。通过这种方式,您甚至可以引导在引导装载程序配置中不存在任何项的已安装操作系统。

GRUB shell 在已安装系统中提供 GRUB 的仿真。它可用于安装 GRUB 或在应用新设置前对这些设置进行测试。请参见第 29.3.4 节 “GRUB Shell”

29.3.1. GRUB 引导菜单

带有引导菜单的图形启动屏幕基于 GRUB 配置文件 /boot/grub/menu.lst,该文件包含有关可以通过菜单引导的所有分区或操作系统的所有信息。

每次引导系统时,GRUB 都从文件系统装载菜单文件。出于此原因,不必每次更改文件后都重安装 GRUB。使用 YaST 引导装载程序修改 GRUB 配置,如第 29.4 节 “使用 YaST 配置引导装载程序”中所述。

菜单文件中包含命令。语法非常简单。每行都包含一条命令,后跟可选参数,可选参数之间用空格隔开,就像在 shell 中一样。出于历史原因,某些命令允许在第一个参数前使用 =。注释以井号 (#) 开头。

若要在菜单概述中标识菜单项,请为每项指定一个 title。关键字 title 后的文本(包括任何空格)显示为菜单中的可选择选项。当选择此菜单项时,将执行下一个 title 前的所有命令。

最简单的情况是重定向到其他操作系统的引导装载程序。命令是 chainloader,参数通常是 GRUB 中另一个分区的引导块 block notation。例如:

chainloader (hd0,3)+1

GRUB 中的设备名在第 29.3.1.1 节 “硬盘和分区的命名约定”中有所解释。上面的示例指定第一个硬盘第四个分区中的第一个块。

使用命令 kernel 指定内核映像。第一个参数是指向分区中内核映像的路径。命令行上的其他参数将被传递到内核。

如果内核不具有访问根分区的内置驱动程序,则必须用单独的 GRUB 命令指定 initrd,该命令的唯一参数便是指向 initrd 文件的路径。因为 initrd 的装载地址会被写入装载的内核映像中,所以 initrd 命令必须紧接在 kernel 命令之后。

命令 root 简化了内核和 initrd 文件的指定。root 的唯一参数是一个 GRUB 设备或 GRUB 设备上的分区。此设备用于所有内核、initrd 或下一个 root 命令前未显式指定设备的其他文件路径。此命令不用于安装过程中生成的 menu.lst 文件。它仅仅使手工编辑更容易。

每个菜单项的末尾都间接指定 boot 命令,因此无需将其写入菜单文件中。但是,如果以交互方式使用 GRUB 进行引导,则必须在最后输入 boot 命令。该命令本身没有参数。它只引导装载的内核映像或指定的链装载程序。

在写入所有菜单项之后,将其中一项定义为 default 项。否则,将使用第一项(项 0)。您还可以指定在一段时间后引导默认项的超时值(以秒为单位)。timeoutdefault 通常在各菜单项前面。示例文件在 第 29.3.1.2 节 “示例菜单文件” 中有所介绍。

29.3.1.1. 硬盘和分区的命名约定

GRUB 用于硬盘和分区的命名约定不同于普通 Linux 设备使用的命名约定。在 GRUB 中,分区的编号从 0 开始。因此,(hd0,0) 是第一块硬盘的第一个分区。在普通台式机上,作为 Primary Master(第一个 IDE 控制器上的主设备)连接的硬盘所对应的 Linux 设备名为 /dev/hda1

4 个可能的主分区所分配的分区号为 03。逻辑分区的编号从 4 开始:

(hd0,0)   first primary partition of the first hard disk 
(hd0,1)   second primary partition 
(hd0,2)   third primary partition 
(hd0,3)   fourth primary partition (usually an extended partition) 
(hd0,4)   first logical partition 
(hd0,5)   second logical partition 

GRUB 不区分 IDE、SCSI 和 RAID 设备。BIOS 或其他控制器识别的所有硬盘将按照 BIOS 中显示的引导顺序进行编号。

不过,GRUB 不能将 Linux 设备名准确映射为 BIOS 设备名。它借助某种算法生成这一映射并将其保存到文件 device.map 中,可以根据需要对该文件进行编辑。有关文件 device.map 的信息在 第 29.3.2 节 “文件 device.map” 中有所介绍。

完整的 GRUB 路径包含写在括号中的设备名和指向指定分区的文件系统中文件的路径。路径以斜线开头。例如,在具有一个 IDE 硬盘(该硬盘的第一个分区中包含 Linux)的系统上,可以按如下方式指定可引导内核:

(hd0,0)/boot/vmlinuz

29.3.1.2. 示例菜单文件

以下示例说明了 GRUB 菜单文件的结构。该示例安装包括 /dev/hda5 下的 Linux 引导分区、/dev/hda7 下的引导分区和 /dev/hda1 下的 Windows 安装。

gfxmenu (hd0,4)/message 
color white/blue black/light-gray 
default 0
timeout 8 

title linux 
   kernel (hd0,4)/vmlinuz root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd 

title windows 
   chainloader(hd0,0)+1 

title floppy
   chainloader(fd0)+1 

title failsafe 
   kernel (hd0,4)/vmlinuz.shipped root=/dev/hda7 ide=nodma \ 
   apm=off acpi=off vga=normal nosmp maxcpus=0 3 
   initrd (hd0,4)/initrd.shipped

第一块定义了启动屏幕的配置:

gfxmenu (hd0,4)/message

背景图像 message 位于 /dev/hda5 中。

color white/blue black/light-gray

颜色方案:白色(前景色)、蓝色(背景色)、黑色(所选内容)、浅灰色(所选内容的背景)。颜色方案对启动屏幕没有任何影响,它只影响通过按 Esc 键退出启动屏幕后所访问的可自定义的 GRUB 菜单。

default 0

第一个菜单项 title linux 是默认情况下引导的对象。

timeout 8

如果 8 秒钟后无任何用户输入,GRUB 将自动引导默认项。要检测自动引导,请删除 timeout 行。如果设置 timeout 0,GRUB 将立即引导默认项。

第二块(也就是最大的块)列出了各个可引导的操作系统。各个操作系统的不同部分由 title 引出。

  • 第一项 (title linux) 负责引导 SUSE Linux。内核 (vmlinuz) 位于第一块硬盘的第一个逻辑分区(引导分区)。内核参数(例如引导分区和 VGA 方式)也被追加在此处。引导分区是根据 Linux 命名约定 (/dev/hda7/) 指定的,这是因为此信息将被内核读取而与 GRUB 无关。initrd 也位于第一块硬盘的第一个逻辑分区中。

  • 第二项负责装载 Windows。Windows 将从第一块硬盘的第一个分区 (hd0,0) 引导。命令 chainloader +1 将导致 GRUB 读取并执行指定分区的第一个扇区。

  • 下一项支持从软盘进行引导,而无需修改 BIOS 设置。

  • 引导选项 failsafe 用一组内核参数启动 Linux,这些参数使 Linux 甚至可以在有问题的系统上引导。

随时可以根据需要更改菜单文件。GRUB 会在下次引导时使用修改后的设置。使用 YaST 或所选的编辑器对文件进行永久编辑。或者,使用 GRUB 的编辑功能可以以交互方式进行临时更改。请参见第 29.3.1.3 节 “在引导过程中编辑菜单项”

29.3.1.3. 在引导过程中编辑菜单项

在图形 GRUB 引导菜单中,使用箭头键选择要引导的操作系统。如果选择 Linux 系统,则可以在引导提示符处输入其他引导参数。若要直接编辑个别菜单项,请按 Esc 键退出启动屏幕并按 E 键。通过这种方式进行的更改仅适用于当前引导过程,不会被永久采用。

[Important]引导过程中的键盘布局

US 键盘布局是引导时唯一可用的键盘布局。

在激活编辑方式后,可以使用箭头键选择要编辑其配置的菜单项。若要使配置可以编辑,请再次按 E 键。通过这种方式,可以编辑不正确的分区或路径指定,从而防止它们对引导进程产生负面影响。按 Enter 键退出编辑方式并返回菜单。随后按 B 键引导此项。可以进行的进一步操作显示在底部的帮助文本中。

若要永久输入更改的引导选项并将它们传递到内核,则以 root 用户身份打开文件 menu.lst 并将相应的内核参数追加到现有的行上,用空格分隔:

title linux 
   kernel (hd0,0)/vmlinuz root=/dev/hda3 additional parameter
   initrd (hd0,0)/initrd

GRUB 会在下次引导系统时自动采用新参数。或者,还可以通过 YaST 引导装载程序模块进行此更改。将新参数追加到现有的行上,用空格分隔。

29.3.1.4. 使用通配符选择引导内核

特别是在开发或使用自定义内核时,您必须更改 menu.lst 中的项或编辑命令行来反映当前内核和 initrd 文件名。为简化这一过程,请使用通配符动态更新 GRUB 的内核列表。然后,符合特定模式的所有内核映像都被自动添加到可引导映像的列表中。但请注意,系统不对这一功能提供支持。

通过在 menu.lst 中输入附加菜单项激活通配符选项。为了可用,所有内核和 initrd 映像都必须具有常见基本名称和标识符,该标识符使内核与其关联的 initrd 匹配。以下面的设置为例:

initrd-default
initrd-test
vmlinuz-default
vmlinuz-test

此本例中,可以在一个 GRUB 配置中添加两个引导映像。要获得菜单项 linux-defaultlinux-test,需要 menu.lst 中的以下项:

title linux-*
   wildcard (hd0,4)/vmlinuz-*
   kernel (hd0,4)/vmlinuz-* root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-* 

在本例中,GRUB 在分区 (hd0,4) 中搜索与通配符匹配的项。这些项用于生成新的 GRUB 菜单项。在上一个示例中,GRUB 所表现出来的行为方式就好像以下项存在于 menu.lst 中一样:

title linux-default
   wildcard (hd0,4)/vmlinuz-default
   kernel (hd0,4)/vmlinuz-default root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-default 
title linux-test
   wildcard (hd0,4)/vmlinuz-test
   kernel (hd0,4)/vmlinuz-test root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-test 
    

如果没有以一致的方式使用文件名,或如果其中一个扩展文件(例如 initrd 映像)丢失,此配置都可能出现问题。

29.3.2. 文件 device.map

文件 device.map 将 GRUB 设备名映射为 Linux 设备名。 在包含 IDE 和 SCSI 硬盘的混合系统中, GRUB 必须通过特殊过程尝试确定引导顺序,因为 GRUB 不能访问 BIOS 上有关引导顺序的信息。GRUB 会将此分析的结果保存在文件 /boot/grub/device.map 中。对于 BIOS 中引导顺序设置为 IDE 在 SCSI 之前的系统,文件 device.map 如下所示:

(fd0)  /dev/fd0 
(hd0)  /dev/hda 
(hd1)  /dev/sda

因为 IDE、SCSI 和其他硬盘的顺序取决于不同的因素,并且 Linux 无法标识映射,所以可以在 device.map 文件中手工设置顺序。如果在引导时遇到问题,则检查此文件中的顺序是否对应于 BIOS 中的顺序,如果需要,使用 GRUB shell(如第 29.3.4 节 “GRUB Shell”中所述)对其进行临时修改。引导了 Linux 系统之后,便可以使用 YaST 引导装载程序模块或所选的编辑器对文件 device.map 进行永久编辑。

在手动更改 device.map 之后,请执行以下命令重安装 GRUB。此命令导致重装载文件 device.map 并且执行 grub.conf 中列出的命令:

 grub --batch < /etc/grub.conf

29.3.3. 文件 /etc/grub.conf

除了 menu.lstdevice.map 之外,第三个重要的 GRUB 配置文件就是 /etc/grub.conf。此文件包含 grub 命令正确安装引导装载程序所需的参数和选项:

root (hd0,4) 
   install /grub/stage1 d (hd0) /grub/stage2 0x8000 (hd0,4)/grub/menu.lst 
   quit

各个项的含义:

root (hd0,4)

此命令指示 GRUB 将以下命令应用到第一块硬盘的第一个逻辑分区(引导文件的位置)。

install parameter

运行 grub 命令应该使用参数 install。引导装载程序的 stage1 应该安装在第一块硬盘的 MBR 中 (/grub/stage1 d (hd0))。stage2 应该被装载到内存地址 0x8000 (/grub/stage2 0x8000)。最后一项 ((hd0,4)/grub/menu.lst) 指示 GRUB 查找菜单文件的位置。

29.3.4. GRUB Shell

GRUB 实际上以两种形式存在:作为引导装载程序,以及作为 /usr/sbin/grub 中的普通 Linux 程序。此程序被称为 GRUB shell。将 GRUB 作为引导装载程序安装在硬盘或软盘上的功能以 installsetup 命令的形式集成在 GRUB 中。当装载了 Linux 后在 GRUB shell 中可用。

但是,在启动 Linux 之前的引导过程中也可以使用 setupinstall 命令。这简化了无法再进行引导的有问题系统的修复工作,因为可以通过手工输入参数规避引导装载程序中有问题的配置文件。在引导过程中手工输入参数还可用于测试新设置而避免损坏本机系统。只要用类似于 menu.lst 中的语法输入试验配置文件即可。然后,测试此项的功能,而无需更改现有的配置文件。例如,要测试一个新内核,请输入命令 kernel 和指向新内核的路径。如果引导过程失败,则可以在下次引导时继续使用未修改的 menu.lst。同样,通过输入正确的参数,不管 menu.lst 文件是否有问题,都可以使用命令行界面引导系统。在运行的系统中,可以在 menu.lst 中输入正确的参数使系统永远可引导。

只有当将 GRUB shell 作为 Linux 程序运行时(通过输入 grub,如第 29.3.2 节 “文件 device.map”中所述),将 GRUB 设备映射为 Linux 设备名才有意义。出于此目的,程序将读取文件 device.map。有关详细信息,请参见第 29.3.2 节 “文件 device.map”

29.3.5. 设置引导口令

即使是在引导操作系统之前,GRUB 也支持对文件系统的访问。没有根权限的用户可以访问 Linux 系统中的文件,而一旦引导系统后,他们将无权访问这些文件。若要阻止这种访问或防止用户引导某些操作系统,可以设置引导口令。

[Important]引导口令和启动屏幕

如果对 GRUB 使用引导口令,则不显示通常的启动屏幕。

root 用户身份按如下步骤设置引导口令:

  1. 在根提示符处,输入 grub

  2. 在 GRUB shell 中对口令进行加密:

    grub> md5crypt 
    Password:**** 
    Encrypted:$1$lS2dv/$JOYcdxIn7CJk9xShzzJVw/
  3. 将经过加密的字符串粘贴到 menu.lst 文件的全局部分:

    gfxmenu (hd0,4)/message 
    color white/blue black/light-gray 
    default 0
    timeout 8 
    password --md5 $1$lS2dv/$JOYcdxIn7CJk9xShzzJVw/

    现在,只有在按 P 键并输入口令后,才可以在引导提示符处执行 GRUB 命令。但是,用户仍可以从引导菜单引导所有操作系统。

  4. 要防止从引导菜单引导一个或多个操作系统,请将项 lock 添加到 menu.lst 中不输入口令就不能引导的每个部分。例如:

    title linux 
    kernel (hd0,4)/vmlinuz root=/dev/hda7 vga=791 
    initrd (hd0,4)/initrd 
    lock

    在重引导系统并从引导菜单中选择 Linux 项后,将显示以下错误讯息:

    Error 32: Must be authenticated

    Enter 键进入该菜单。然后按 P 键,系统将提示您输入口令。在输入口令并按 Enter 键之后,将引导所选的操作系统(在本例中为 Linux)。