8.4. 使用 GRUB 配置启动过程

8.4.1. 介绍

引导加载是一个复杂的领域, 因此下面有几个警告。 和当前的引导加载器及硬盘上现存的任何其他操作系统相似, 它需要可引导。 如果计算机变得不可用(不能启动),要确保已经准备了应急启动盘来“救援” 这台计算机。

这个过程需要在硬盘的特殊位置写上一些特殊的GRUB 文件。我们强烈推荐您创建一张 Grub 引导软盘作为备份,插入一张空白软盘,并执行下面的命令:

cd /tmp
grub-mkrescue --image-type=floppy floppy.img
dd if=floppy.img of=/dev/fd0 bs=1440 count=1

GRUB有自己的驱动器和分区命名结构,形式是(hdn,m), 这里n是硬盘号, m是分区号。硬盘号从“0”开始,而分区号,对于主分区是从“1”开始,对于扩展分区是从“5”开始。 注意,这里的格式和以前版本的不同,以前版本的两个数值都是从“0”开始。 例如,对于GRUB,分区sda1(hd0,1),而分区 sdb3(hd1,3)。 相对应Linux, GRUB不将CD-ROM驱动器当做硬盘驱动器。例如,如果在hdb上使用光驱,而在hdc上放置第二块硬盘,那么第二块硬盘仍然是(hd1)

通过运行一下命令,你可以GRUB如何看待你的磁盘设备:

grub-mkdevicemap --device-map=device.map
cat device.map

引导分区的位置是影响到用户配置的选择。建议有一个单独的小分区(推荐为100MB)仅仅用于启动信息。 这样每一次安装,不管是LFS还是一些商业发行版,都可以访问相同的启动文件,并且可以从人体已启动的系统访问。如果你选择这样做,你将需要家长这个单独的分区,将当前/boot目录下的所有文件(例如在上一节刚刚编译的Linux内核)移动的这个新分区。 然后,你要卸载这个分区,在以/boot重新装载它。 如果这样,你要确保更新/etc/fstab文件。

使用当前的lfs分区也可以运行,但是对于多系统的配置会更困难。

8.4.2. 设置 Configuration

使用以上的信息, 确定适当的根分区(或引导分区,如果使用单独分区的话)指示符。对于下面的例子,假设根分区(或单独的引导分区)是sda2

将GRUB文件安装到/boot/grub

grub-install --grub-setup=/bin/true /dev/sda

我们使用 --grub-setup=/bin/true 是为了避免现在更新主引导记录(MBR)。用这种方法,我们可以在更改之前对安装进行测试,因为改变很难恢复。

生成 /boot/grub/grub.cfg:

grub-mkconfig -o /boot/grub/grub.cfg

在这里grub-mkconfig使用/etc/grub.d/目录中的文件来确定这些文件中的内容。这个配置文件看起来有点像:

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by /usr/sbin/grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set default=0
set timeout=5
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/10_linux ###
menuentry "GNU/Linux, Linux 2.6.30.2-lfs65" {
        insmod ext2
        set root=(hd0,2)
        search --no-floppy --fs-uuid --set 915852a7-859e-45a6-9ff0-d3ebfdb5cea2
        linux   /boot/vmlinux-2.6.32.8-lfs-6.6 root=/dev/sda2 ro
}
menuentry "GNU/Linux, Linux 2.6.30.2-lfs65 (recovery mode)" {
        insmod ext2
        set root=(hd0,2)
        search --no-floppy --fs-uuid --set 915852a7-859e-45a6-9ff0-d3ebfdb5cea2
        linux   /boot/vmlinux-2.6.32.8-lfs-6.6 root=/dev/sda2 ro single
}
menuentry "GNU/Linux, Linux 2.6.28-11-server" {
        insmod ext2
        set root=(hd0,2)
        search --no-floppy --fs-uuid --set 6b4c0339-5501-4a85-8351-e398e5252be8
        linux   /boot/vmlinuz-2.6.28-11-server root=UUID=6b4c0339-5501-4a85-8351-e398e5252be8 ro
        initrd  /boot/initrd.img-2.6.28-11-server
}
menuentry "GNU/Linux, Linux 2.6.28-11-server (recovery mode)" {
        insmod ext2
        set root=(hd0,2)
        search --no-floppy --fs-uuid --set 6b4c0339-5501-4a85-8351-e398e5252be8
        linux   /boot/vmlinuz-2.6.28-11-server root=UUID=6b4c0339-5501-4a85-8351-e398e5252be8 ro single
        initrd  /boot/initrd.img-2.6.28-11-server
}
### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
# 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.
### END /etc/grub.d/40_custom ###

注意,虽然警告不要编辑这个文件,但是只要你不重新运行grub-mkconfig,你就可以这样做。 search所在的行对于LFS系统没有意义, 因为这个命令需要需要处理initrd映像。如果在单独的分区上安装的话, linux 和 initrd 行,在文件名上就没有/boot。在本例中,也可以在/boot分区找到安装的UbuntuIn内核文件。

8.4.3. 测试 Configuration

GRUB的核心映像也是一个多引导的内核,因此如果你已经装载了一个GRUB,那么你可以通过这个老的引导装载器装载GRUB-1.97.2。 要做的这一点,你需要退出chroot环境,再重新进入它,以便完成本书剩余的本分。

/sbin/reboot
...
grub> root (hd0,1)
grub> kernel /boot/grub/core.img
grub> boot

注意, 上面的GRUB命令假定是遗留的GRUB。 此时会出现GRUB提示(非常像老的GRUB), 在
grub.cfg文件中,你可以探索到其中一个系统接口或引导。

8.4.4. 更新主引导记录

如果你像上面指出的一样测试了GRUB配置,那么就重新进入chroot环境。

[Warning]

警告

下面的命令会覆盖当前的引导装载器。 如果不想这样,就不要运行这个命令,比如,如果你使用第三方的启动管理器来管理主引导记录(MBR)的话。

更新MBR:

grub-setup '<DEVICE>'

将上面的 DEVICE 改成你的启动磁盘,通常是 '(hd0)' 或 /dev/sda。 如果你使用(hd0),一定要使用反斜杠转义符或单引号,以防止shell将它们解释成子shell。

如果你没有偏离上面的说明,那么这个程序使用下面的默认值是正确的:

  • boot image - boot.img

  • core image - core.img

  • directory - /boot/grub

  • device map - device.map

  • default root setting - guessed

[Note]

注意

如果在grub.cfg中没有找到'set root'指令,那么根设置就是用默认值。这就是内核和其他支持的文件搜索的分区。它和配置行中 'linux'行上的'root='参数不同,后者是内核以 '/'装载的分区。 在上面的grub.cfg例子中,这两个值都指向 /dev/sda2,但是如果有一个单独的引导分区,它们就不同了。