12.3. MBR 和引导阶段一、二、三

12.3.1. MBR,/boot/boot0

FreeBSD MBR 放置在 /boot/boot0。 这是真实 MBR 的一份 复制品,真正的 MBR 必须放在磁盘上 FreeBSD 分区以外的特定部分。

boot0 是非常简单的,因为在 MBR 里的代码只有 512 字节。 如果您安装了 FreeBSD MBR 且装了多个操作系统, 在引导时您会看到如下的内容:

Example 12-1. boot0 截屏

F1 DOS
F2 FreeBSD
F3 Linux
F4 ??
F5 Drive 1

Default: F2

其它操作系统,特别是 Windows® 95,以用自己的 MBR 覆盖现有 MBR 而著称。如果发生了这种事情,或者您想用 FreeBSD 的 MBR 覆盖现有的 MBR,您可以使用以下的命令:

# fdisk -B -b /boot/boot0 device

device 是要写入 MBR 的设备名,比如 ad0 代表第一个 IDE 磁盘,ad2 代表第二个 IDE 控制器上的第一个 IDE 磁盘, da0 代表第一个 SCSI 磁盘,等等。

如果您是 linux 用户,您可能更喜欢使用 LILO 来控制引导过程,您可以编辑 /etc/lilo.conf 文件,或者在安装 FreeBSD 过程中选择 Leave The Master Boot Record Untouched 选项。 如果您安装了 FreeBSD 引导管理器,您可以启动 linux 然后更改 LILO 的配置文件 /etc/lilo.conf,加入以下的选项:

other=/dev/hdXY
table=/dev/hdb
loader=/boot/chain.b
label=FreeBSD

这样就可以通过 LILO 来引导 FreeBSD 和 linux 了。 在我们的例子中,我们使用 XY 确定驱动器号和分区。 如果您使用的是 SCSI 驱动器,您需要将 /dev/hdXY 改成 /dev/sdXY, 这里再次使用了 XY 的语法。 如果您安装的两个系统在同一驱动器上,loader=/boot/chain.b 选项可以去掉。现在您可以执行 /sbin/lilo -v 使修改生效。

12.3.2. 第一阶段,/boot/boot1,和第二阶段, /boot/boot2

概念上,第一,第二阶段同属于一个程序,处于磁盘的相同区域。但由于空间限制, 它们被分为两部分。可是您总是会一起安装它们。

它们放置在引导分区的引导扇区里。在引导扇区里能找到 boot0MBR 以及其它用于引导系统的程序。/boot 目录下的文件是真实文件的拷贝,真实文件放置在 FreeBSD 文件系统之外。

boot1 非常简单,因为它再多也只能有 512 字节, 只能识别储存着分区信息的 disklabel, 及寻找执行 boot2

boot2 稍微有点加强,能够理解 FreeBSD 的文件系统以便于寻找里面的文件, 能提供选择内核和加载器的简单界面。

因为 loader 有着更强的功能, 提供了一套易于使用的引导配置,boot2 一般都执行 loader, 但以前它的任务是直接运行内核。

Example 12-2. boot2 的屏幕输出

>> FreeBSD/i386 BOOT
Default: 0:ad(0,a)/kernel
boot:

如果您要更改已安装的 boot1boot2,请使用命令 disklabel(8)

# disklabel -B diskslice

diskslice 是用于引导的磁盘和分区, 比如 ad0s1 代表第一个 IDE 磁盘上的第一个分区。

dangerously dedicated如果您在 disklabel(8) 命令中只使用了磁盘名,比如 ad0,就会破坏磁盘上的所有分区。 这当然不是您所希望的,所以在按下 回车 之前 一定要对命令进行多次确认。

12.3.3. 第三阶段,/boot/loader

加载器 (loader) 是三个阶段中的最后阶段, 且是放置在文件系统之中的,一般是文件 /boot/loader

loader 被作为一种友好的配置方式,使用了一组内建且易用的命令集。 这些命令由一个强大的多的解释器支持构建,其本身带有复杂得多的命令集。

12.3.3.1. Loader 程序流程

初始时,loader 会探测控制台和磁盘,识别是从哪块盘引导的。 它会根据这些信息设置变量, 启动解释器以接受通过脚本或交互方式传来的用户命令。

loader 然后会读取并运行 /boot/loader.rc, 默认地读取 /boot/defaults/loader.conf 以设置可靠的默认变量,读取 /boot/loader.conf 对这些变量作本地修改。loader.rc 依据这些变量进行动作,加载任何被选择的模块和内核。

最后,默认地,loader 会停留 10 秒等待按键, 若没有发生中断,就开始引导内核。如果被中断,用户会得到一个命令行提示符, 在这里用户得更改变量、卸载所有模块、加载模块、最后引导 或重新引导。

12.3.3.2. Loader 内建的命令

这些是最常用的 loader 命令.对所有可用命令的解释请参见 loader(8)

autobootseconds

在给定的时间内如果没有中断发生就引导内核。它显示一个倒数计时, 默认的时间范围是 10 秒。

boot [-options] [kernelname]

立即按照给定的选项 (如果有的话) 和内核名 (如果是内核的) 引导内核。

boot-conf

基于变量对各种模块进行自动配置 (和引导内核时发生的一样)。 您只须记住要先使用 unload 命令, 然后修改一些变量,比如 kernel

help [topic]

显示从文件 /boot/loader.help 读取的帮助信息。如果给定的主题是 index, 那么列出来的是所有可用的主题。

include filename ...

通过给定的文件名处理文件。文件被读入,然后被一行一行地解释。 任何错误都会立即中止 include 命令。

load [-t type] filename

加载内核、内核模块,或者是给定类型的文件 (通过给定的文件名)。 任何在文件名后面的参数都会被传给文件。

ls [-l] [path]

显示给定路径或者是根目录 (如果路径没有指定) 下面的文件列表。 如果指定了 -l 选项,文件大小也会显示。

lsdev [-v]

列出所有可以加载模块的设备。 如果指定了-v 选项,会显示出更多的细节。

lsmod [-v]

显示已被加载的模块。如果指明了 -v 选项, 会显示更多的细节。

more filename

显示指定的文件,每隔 LINES 停顿一次。

reboot

立即重启系统。

set variable, set variable=value

设置 loader 的环境变量。

unload

移除所有已被加载的模块。

12.3.3.3. Loader 示例

这里有一些实际中 loader 用法的示例

  • 只是简单的引导默认内核,不同的是进入单用户模式:

    boot -s
    
  • 卸载默认内核和模块,然后加载旧的 (或者其它) 的内核:

    unload
    load kernel.old
    

    您可以使用被称为通用内核的 kernel.GENERIC, 或者您以前安装的内核 kernel.old (当您升级或配置了您自己的内核等时候)。

    Note: 使用以下命令加载常用的模块和另一个内核:

    unload
    set kernel="kernel.old"
    boot-conf
    
  • 加载内核配置脚本:

    load -t userconfig_script /boot/kernel.conf