彻底搞定 Grub

tr:彻底搞定 Grub (未完成)


Troubleshooters.Com and T.C Linux Library Present
Grub From the Ground Up

Copyright (C) 2005 by Steve Litt, All rights reserved. Material provided as-is, use at your own risk.

转载并翻译自 troubleshooters 网站,译文遵循 GNU FDL,仅正文部分可自由修改,重发布时正文之外的部分必须同时原样发布。译者对未告知作者表示歉意,但对误读的后果表示不负责。

彻底搞定 Grub

目录
* 免责声明
* 总结
* 制作简单的 grub 启动软盘
* 你一定要知道的事情
* 使用 grub 来查找文件
* 制作全功能的 grub 启动软盘
* 从软盘安装 grub
* 使用完全安装的 grub

Disclaimer

This document contains a series of exercises accessing, and in some cases overwriting, your boot loader. There's a significant possibility of overwriting your existing boot loader, which can lead to lost time and even lost data. There may be other risks.

You use this document at your own risk. I am not responsible for any damage or injury caused by your use of this document, or caused by errors and/or omissions in this document. If that's not acceptable to you, you may not use this document. By using this document you are accepting this disclaimer.

免责声明

本文档包括一系列的实验,读取甚至重写你的引导程序 (boot loader)。重写你现有的引导程序的可能性非常大,可能导致费时的修复甚至数据丢失。另外还有其他危险。

使用本文档,你要自己承担危险。我对使用本文档,误读文档或是忽略部分文档造成的任何损失不负责。如果你无法接受,那么就不要使用本文档。如果使用了本文档,那么就视为已经接受了这份免责声明。

[正文开始]

总结

grub 是一个超一流的引导程序,但是文档很少。很多地方它比 lilo 出色得多。例如,使用 Knoppix 重建一个 grub 引导程序,比起重建一个 lilo 引导程序要容易得多。但是,除非你很熟悉 grub,否则你会感到正相反。grub 经常会送上一个提示符
代码:
grub>
但是不告诉你应当做什么。你可能听说过只要三个命令就可以成功重启,但是究竟是哪三个?grub 的文档就是那样,除非你已经知道了它是什么意思,否则就看不明白。

本文要解决的,正是这种尴尬的情况。本文将教你足够专业的 grub 技能,使你可以在一台安装了 grub 的机器上 (只要安装了就可以,不必作为引导程序) 创建 grub 启动软盘,使用这张软盘中的简单的引导程序来启动一台 linux 机器,然后使用这张软盘来真正地将 grub 安装为引导程序。

本文不讨论使用 grub 来引导 (或配置多引导) Windows,mach,BSD 或其他非 linux 操作系统。也许我会再写一篇有关的文档。但是,当你对 grub 的原则和实践比较熟悉之后,研究一下已有的文档,你就会学会如何用 grub 来引导非 linux 操作系统了。

制作简单的 grub 启动软盘

本文大部分都是关于在 “grub>” 提示符下应当做什么的内容,因此你必须可以进入这样的环境。最简单的办法,是使用一张简单的 grub 启动软盘。在任何安装了 grub 的机器上都可以创建它,无论这台机器是否用 grub 引导。下列 bash 命令展示了如何制作简单的 grub 启动软盘
代码:

[root@mydesk grub]# cd /boot/grub
[root@mydesk grub]# cat stage1 stage2 > /dev/fd0u1440
[root@mydesk grub]#


要提醒一句。在 1990 年假如买 50 张软盘,其中超过 45 张会是质量很好的。如今假如你买到的软盘中有一半是好的,重格式化之后可以再用,就很不错了。1990 年软驱的价格接近 100 美元,可以工作相当长的时间。如今的软驱只有原来 1/10 的价格,工作时间却也只有原来的 1/10。因此,多创建几张 grub 启动软盘,如果在启动过程中发生读错误,可以换张别的。

别着急,虽然要进入 “grub>” 提示符环境,只要将做好的软盘插入软驱,重启电脑,调整 bios 设置为从软驱启动优先,然后重启继续就可以了。但是首先,你必须知道一些东西……

你一定要知道的事情

为了能用 grub 启动电脑,你必须知道如下内容:
1. 包含内核的分区
2. 分区中,内核所在的目录路径和文件名
3. 包含 /sbin/init 的分区
另外,可能需要知道 initrd 文件所在的分区,路径和文件名,但是在 grub 中通常不是必要的。
引用:

注意
我遇到过内核在没有 initrd 语句时 panic 的情况,它只能在存在 initrd 的情况下启动。但是,等到启动完成,我可以去掉 initrd 语句,重新运行 grub 的安装命令,这时启动时就不需要 initrd 语句了。如果你遇到内核 panic 的情况,不清楚原因,那么就加上一句 initrd 语句。

现在来看一个例子。假设一台系统将 /dev/hda1 挂载为 /boot,将 /dev/hda9 挂载为 /。在 /boot 目录中,内核的文件名是 vmlinuz-i686-up-4GB。现在我们可以回答上面四个问题了:
1. 包含内核的分区是 /dev/hda1,如果用 grub 的说法就是 (hd0,0)
2. 分区中,内核所在的目录路径和文件名是 /vmlinuz-i686-up-4GB (记住,由于 /dev/hda1 被直接挂载到 /boot,因此内核就在它的根目录)
3. 包含 /sbin/init 的分区是 /dev/hda9

这种情况下,要引导系统,应当输入这样的命令
代码:
grub> root (hd0,0)
grub> kernel /vmlinuz-i686-up-4GB root=/dev/hda9
grub> boot

这样的命令对于引导一台 Linux 主机通常已经足够了。单独的 root 语句给出了包含内核的分区。 kernel 语句描述了分区中,内核文件的路径和文件名。参数 root= 给出了包含 /sbin/init 的分区,这当然是系统的根分区了。

小心这里出现了两个 root 关键字。单独的那个是 grub 看到的根分区,包含着内核。而作为 kernel 语句参数的,是启动后的系统看到的根分区,包含着 /sbin/init。

还要小心有时使用 grub 的分区表示,有时使用 linux 的分区表示。除了 kernel 语句中的 root= 参数之外,都应当使用 grub 的分区表示 ((hd0,0))。在 root= 参数中,使用的是 linux 的分区表示。在 linux 的表示中,驱动器以 a 表示第一个 IDE 端口的主驱动器,b 表示第一个 IDE 端口的从驱动器,c 表示第二个 IDE 端口的主驱动器,d 表示第二个 IDE 端口的从驱动器,其他 IDE 端口以此类推。在 linux 的表示中,驱动器内的分区号从 1 开始。

在 grub 的分区表示中,第一块可读取的硬盘驱动器是 (hd0),第二块可读取的硬盘驱动器 (即使它被连接在第三,第四或更高的 IDE 端口上) 是 (hd1),以此类推。在 grub 的分区表示中,分区号从 0 开始。因此,/dev/hda1 与 (hd0,0) 是相同的分区。

有时,你需要指定 initrd,尽管这种情况很少。这样的话,只要在 kernel 语句之后,boot 语句之前,添加这样一句
代码:
initrd /initrd-i686-up-4GB.img

如果要使用 initrd 语句,那么你使用的 initrd 文件必须与你使用的内核文件相匹配。

另一种从 grub 启动的方法是将 grub 的 root 语句与 kernel 语句结合到一起:
代码:
grub> kernel (hd0,0)/vmlinuz-i686-up-4GB root=/dev/hda9
grub> boot

如果这样做的话,在 initrd 语句中也必须结合 root 语句。

引导外语的发行版

假如你的母语是美国英语,但是使用 grub 来启动一台丢失了引导程序的 Knoppix 机器,前面提到的命令可以启动 Knoppix,但是各种消息提示甚至键盘布局将是德语的。如果你想得到美国英语的环境,可以在 kernel 语句后面添加参数 lang=us,就像这样:
代码:
grub> kernel (hd0,0)/vmlinuz-i686-up-4GB root=/dev/hda9 lang=us
grub> boot
或者
grub> root (hd0,0)
grub> kernel /vmlinuz-i686-up-4GB root=/dev/hda9 lang=us
grub> boot


单一分区时的设置
前面的例子中,系统中有一个专门划分的 /boot 分区。现代计算机的BIOS都可以引导 1024 柱面之后的系统了,因此很多人不再为 /boot 单独分区。也就是说,根分区是 /dev/hda1,而 /boot 仅仅是根分区中的一个目录。这时你需要使用这样的命令:
代码:
grub> root (hd0,0)
grub> kernel /vmlinuz-i686-up-4GB root=/dev/hda1
grub> boot

仅有的不同之处在于,这里 grub 的 root 与系统的 root 相同。

使用 grub 来搜索
通常你知道包含内核的分区,以及内核的路径和文件名,还有启动后应当挂载的分区。这种情况下启动非常简单。
但是,有时事情不那么简单。比如说,你不小心安装了配置错误的 LILO ,或者重装了 Win$,不经意间覆盖了 MBR 中的引导管理器。这时你最需要 grub 的帮助,但是对于系统中包含内核的分区情况,根分区的情况以及内核的文件名却一无所知。幸好,grub 可以帮你。
第一步是找到包含内核的分区,以及包含 /sbin/init 的分区。在 grub> 提示符下输入这样的命令
代码:
find /sbin/init

在一台安装了多个不同的 linux 系统的主机上,机器将回应类似下面的结果:
引用:
grub> find /sbin/init
(hd0,8)
(hd0,11)
(hd1,11)
grub>

在这个例子中,你会发现有三个分区包含了 /sbin/init
引用:
Grub 分区号 linux 分区号
(hd0,8) /dev/hda9
(hd0,11) /dev/hda12
(hd1,11) /dev/hde12 (从这里可以推断出,hd1 映射到了 hde,因为这台机器上有两块硬盘,分别接到了 hda 和 hdc)

接下来,查找包含内核的所有分区。首先,我们假设至少有一个内核的文件名是 vmlinuz
代码:
grub> find /vmlinuz
(hd0,0)
(hd0,11)
(hd1,11)
grub>

然后,搜索包含在 /boot 目录中的 vmlinuz
代码:
grub> find /boot/vmlinuz
(hd0,11)
(hd1,11)
grub>

这次找到了前一次三个结果中的两个,因此可以推断出,(hd0,0) 是某个系统的 /boot 分区。
grub 的 find 命令功能有限。它只能找到普通文件,无法查找目录。通常必须指定整个的目录路径,尽管在上面的实验中,搜索 /vmlinuz 时也找到了两处 /boot/vmlinuz。不要依赖于这种行为。
另一种在 grub 中查找信息的技术,是使用文件名补全的特性。假如你知道了内核位于 (hd0,0),并且内核文件名以 vml 起头。输入这样的命令,但是不执行,而是在输入之后按下 tab 键:
代码:
null (hd0,0)/vml

grub 会进行补全,就好像在 shell 命令行提示符下那样
代码:
grub> null (hd0,0)/vmlinuz
Possible files are: vmlinuz vmlinuz-2.6.3-7mdk vmlinuz-2.6.3-7mdk-i686-up-4GB
vmlinuz-i686-up-4GB
grub>

上面的实验中,null 并不是一个关键字。这里专门找了一个并非关键字的单词,你也可以使用 whatever 或者 bogus 等等其他非关键字的单词。当你看到提示中的列表时,你就可以输入更多提示,然后再次按下 tab,就好像在 shell 命令行提示符下那样。这样做尽可能地减少了输入错误。
有时 grub 也不能找到所有需要的信息。如果你需要更多信息,最好用 knoppix——参见 Troubleshooters.Com 的 Knoppix Knowhow 网页。
制作完整的 grub 启动软盘
在本文档的开始,你创建了一张简单的不包括文件系统的 grub 启动软盘。对于启动系统,它已经足够了,但是还不能用来安装 grub。要安装 grub,需要一张包含文件系统的 grub 启动软盘。可以在任何安装了 grub 的 linux 系统中制作它。下面是详细步骤
代码:
[root@mydesk root]# mkfs -t ext2 -c /dev/fd0u1440
[root@mydesk root]# umount /dev/fd0
[root@mydesk root]# umount /dev/fd0u1440
[root@mydesk root]# mkdir /mnt/test
[root@mydesk root]# mount /dev/fd0u1440 /mnt/test
[root@mydesk root]# mkdir -p /mnt/test/boot/grub
[root@mydesk root]# cp /boot/grub/stage1 /mnt/test/boot/grub
[root@mydesk root]# cp /boot/grub/stage2 /mnt/test/boot/grub
[root@mydesk root]# chmod a-w /mnt/test/boot/grub/stage2
umount /dev/fd0u1440
[root@mydesk root]# grub
grub> root (fd0)
grub> setup (fd0)
grub> quit

[root@mydesk root]#

这样就做好了一张可启动的 grub 软盘。最好在软盘上加入一个 menu.lst 文件作为范例。menu.lst 文件为 grub 增加了一个菜单,在将 grub 安装到其他机器中时十分重要。在需要启动的机器上,你可以修改这个 menu.lst 文件,创建启动时的菜单,然后将 grub 安装到系统中。注意在上面那些步骤执行完之前,绝对不要将 menu.lst 范例复制到软盘上。下面是如何加入范例文件的步骤。注意必须再次运行 mount 和 umount。
代码:
[root@mydesk root]# mount /dev/fd0u1440 /mnt/test
[root@mydesk root]# cp -p /usr/share/doc/grub-doc-0.93/menu.lst /mnt/test/boot/grub/
stage1 stage2
[root@mydesk root]# cp -p /usr/share/doc/grub-doc-0.93/menu.lst /mnt/test/boot/grub/menu.lst.example
[root@mydesk root]# umount /dev/fd0u1440
[root@mydesk root]#

通过软盘安装 grub
除非已经做完了前面所有的实验,否则不要做这一个。另外,必须理解 grub 命令行的操作,这很重要。

警告
接下来的实验教你如何在一台安装了 grub 的计算机上创建一张 grub 启动软盘,然后使用这张软盘在另外一台计算机上启动并配置 grub。这个过程会将第二台计算机上原有的引导管理器删除。如果顺利的话,grub 会替代原有的引导管理器,但是没人能保证一切顺利。实际上,这篇文档只针对 linux 的情况,如果你的机器上是 windows 或者 BSD 系统,这篇文章没办法帮你恢复。
因此,第二台计算机必须是一台专门用于实验,即使丢失了数据和操作系统也没有关系的机器

在创建完整的 grub 启动软盘的实验中,你已经创建了一张软盘,包含 stage1, stage2 和一个叫做 menu.lst.example 的范例菜单文件。现在,是在另一台机器上使用这张软盘的时候了。正如在警告中提到那样,这必须是一台实验系统,即使引导管理器被错误覆盖了也没有关系。
如果那台机器上已经安装了 grub,我们可以暂时将相关文件移动到别的地方。运行这样的命令
代码:
mv /boot/grub /boot/orggrub
mv /sbin/grub /sbin/orggrub
mv /sbin/grub-install /sbin/orggrub-install

也就是说,将 /boot/grub 改名,并且将所有与 grub 有关的可执行文件都改名。这样,你可以模拟一台从未安装过 grub 的机器。以后要想用到它们,可以再用几个 mv 命令改回来。可惜,要改回来修改过的 MBR 就不是这么简单了。
在实验系统中插入那张 grub 启动软盘,正确地关闭计算机,再次启动它。在 BIOS 自检过程中,将计算机的 first boot drive 设置为 floppy
基本上过程是这样
1. 从 grub 启动软盘启动
2. 将软驱上的文件复制到硬盘上的 /boot/grub 目录
3. 配置计算机上的 /boot/grub/menu.lst 文件
4. 重启,同样从 grub 启动软盘启动,安装 grub
从 grub 启动软盘启动
代码:
grub> root (hd0,0)
grub> kernel /vmlinuz-i686-up-4GB root=/dev/hda9
grub> boot

就像前面讲的那样,如果要启动外语的发行版,应当附加合适的 lang= 内核参数,来获得母语的工作环境。如果执行无误,你的实验系统就启动起来了。
将文件从软驱复制到硬盘的 /boot/grub 目录
首先,我们确定机器上没有 /boot/grub。如果有的话,将它改名。作为实验,不应该将系统中原有的东西覆盖掉。
然后运行这样的命令
代码:
mkdir /mnt/test
mount /dev/fd0u1440 /mnt/test
cp -Rp /mnt/test/boot/grub /boot

为这台计算机配置 /boot/grub/menu.lst 文件
如果你在阅读这份文档之前对 grub 一无所知,那么 grub 附带的 menu.lst 示例文件对你一点用处也没有。但是只要稍加学习,你就会懂得很多!现在你已经知道了如何在 grub> 提示符下启动一台机器;你也知道了 grub 根分区与 Linux 启动后看到的根分区有什么不同;你还知道了如何配置 grub 的 kernel 命令。
menu.lst 文件中列出的其实就是你在 grub> 提示符下使用的命令,只不过不包括 boot 命令罢了。示例文件中包括启动各种操作系统的命令,甚至包括 mach 和 windows。文件中还包含将 grub 安装到系统中的命令,以及改变菜单颜色的命令。这些都是无关紧要的。你要做的是将与 linux 无关的内容删掉,只配置 linux 相关的命令,使它们与你的实验系统的情况相匹配:内核所在的分区,linux 的根分区,内核的文件名……下面是一个配置过的文件,保存的文件名是 menu.lst
引用:
#
# Sample boot menu configuration file
#

# Boot automatically after 30 secs.
timeout 30

# By default, boot the first entry.
default 0

# Fallback to the second entry.
# fallback 1 # BE SURE TO COMMENT THIS OUT!!!!!!!!!!!!!!

# For booting GNU/Linux
title GNU/Linux
root (hd0,0)
kernel /boot/vmlinuz-2.6.7 root=/dev/hda1 lang=us

有一些需要注意的地方:
* 一定要将 fallback 1这个命令注释掉,因为我们只有唯一的选择,也就是 0 号选择
* default 0 命令的意思是指出用户超时未响应时,应当作出哪一个选择
* 如果你并不是启动一个外语的发行版,那么不需要 lang= 参数
* 命令 root (hd0,0) 应当作出调整,指向包含内核的分区
* 参数 root=/dev/hda1 应当作出调整,指向启动后将作为根分区的那个分区。它是以 linux 的方式命名的,不是 grub 的方式
* kernel 命令中的内核文件名应当使用相对于 grub 根分区的路径。在这个例子中,linux 的 /boot 和根分区是相同的分区,所以内核文件名是 /boot/vmlinuz-2.6.7;如果 linux 为 /boot 单独划出一个分区,假设这个分区是 /dev/hda1 (通常是这样),那么 kernel 命令应当使用的内核文件名是 /vmlinuz-2.6.7 而不是例子中那样,因为这时文件处于分区的根文件夹,只有当启动之后,这个分区被挂载后,提到 /boot 才有意义。
* grub 的默认菜单文件是 /boot/grub/menu.lst。也可以使用其他文件,但是…… (<jump through hoops 是什么意思?>) 最好使用默认值。
* 这些命令对你来说都不是新东西。在前面的练习中,你已经在 grub> 提示符下做过了所有的命令。
/boot/grub/menu.lst 文件做好之后,可以从软盘来安装 grub
重启,仍然使用软盘启动,安装 grub
保证软盘仍然在实验机器中,重启机器。机器从软驱启动后,会将你带到 grub> 提示符下。如果前面都做对了,接下来,安装就十分简单了。
代码:
grub> root (hd0,0)
grub> setup (hd0)
grub> reboot

机器将再次重启。应该把软盘拿出来,设置 BIOS 为从硬盘启动,你会看到只包含一个项目的 grub 菜单。就像这样:
[image]
按下回车,启动 menu.lst 文件中列出的这个内核。需要注意的地方:
* 不要在软驱灯亮着的时候取出软盘
* 如果没来得及取出软盘,系统将再次从软盘启动。这时只要启动之后,取出软盘,重启就可以了。
总结
整个就是这样。你创建了一张包含 stage1, stage2 和示例菜单文件的可启动的软盘,使用这张软盘向另一台机器安装了 grub 引导管理器。这就是如何将一台机器上糟糕的引导管理器换成 grub 的方法。
但是,这样的安装是不完全的。首先,没有安装 grub 的可执行文件
# grub
# grub-floppy
# grub-install
# grub-md5-crypt
# grub-reboot grub-terminfo
其次,很多 /boot/grub 中的文件也没有安装
# device.map
# e2fs_stage1_5
# jfs_stage1_5
# minix_stage1_5
# reiserfs_stage1_5
# xfs_stage1_5
最后,还缺少 /usr/share/doc/grub 目录的那些文档。
当你的机器可以稳定而正常地使用 grub 启动之后,应该使用某种包管理工具或者源代码来重新安装完整的 grub。小心一定要备份你现有的 /boot/grub/menu.lst
安装完整的 grub
总是要用 floppy 来启动,进入 grub> 提示符下或是将引导管理器安装到 MBR 上是非常无聊的。如果安装了完整的 grub,就不必再这样做了。你可以用 grub-install 来安装新配置好的引导管理器,不必劳神去制作启动软盘。另外,还可以用 grub 来预览 menu.lst 的效果。
例如,安装了 grub 之后 (或者通过改名,恢复了原有的 grub 之后),编辑 menu.lst,插入一个新启动项。我打算添加一个 2.4 内核作为第二选择,在第一选择无法启动时自动启动它。修改后的 menu.lst 就像这样
引用:
#
# Sample boot menu configuration file
#

# Boot automatically after 30 secs.
timeout 30

# By default, boot the first entry.
default 0

# Fallback to the second entry.
fallback 1

# For booting GNU/Linux
title 26
root (hd0,0)
kernel /boot/vmlinuz-2.6.7 root=/dev/hda1 lang=us

# For booting GNU/Linux
title 24
root (hd0,0)
kernel /boot/vmlinuz-2.4.27 root=/dev/hda1 lang=us

这样的文件提供了两个选择,一个是 2.6 内核的,名字叫做 "26",另一个是 2.4 内核的,名字叫做 "24"。下次启动机器时,就会看到两个选择 "26" 和 "24"。它们的行为是这样:默认启动 "26",但是如果 "26" 无法启动,那么就启动 "24"。
文件保存之后,执行这样的命令 grub-install /dev/hda 会将 grub 安装到硬盘的 MBR 上。
引用:
注意
也可以在 grub> 提示符下运行
grub> root (hd0,0)
grub> setup (hd0)
来达到这个命令 grub-install /dev/hda 的效果。这里,我们假设内核位于 (hd0,0) 也就是 /dev/hda1,并且我们要将 grub 安装到第一块硬盘的 MBR 上,也就是 /dev/hda

如果想预览菜单效果而不愿重启,可以用这个命令
代码:
grub --config-file \(hd0,0\)/boot/grub/menu.lst

注意要用反斜线将括号转义,否则 shell 会将它们理解为有特殊含义的字符。运行这个命令就会看到菜单,就像这样
[image]
在命令行运行的 grub 不会真的启动系统。(如果配置文件正确,那么 grub 会安静地退出)
[正文结束]

回到 Troubleshooters.Com
回到 Linux Library

后记:
按规矩,免责声明本不应翻译,但是这是 grub 的文档。
另外,原文禁止创造衍生作品,禁止翻译或转载,所以请懂英文的兄弟到那个强硬的固执的网站上去看原文。
原文地址:https://www.cnblogs.com/swordzj/p/2034791.html