深入剖析FreeBSD的启动过程
启动计算机并加载操作系统的过程,通常被称为“bootstrap process”,或简称为“booting” 。FreeBSD的启动过程极具灵活性,能很好地适应各种实际变化,不仅允许用户选择启动同一计算机上安装的不同操作系统,还能选择同一操作系统的不同版本。本文将详细描述其中可能涉及的配置选项,以及如何定制FreeBSD的启动过程,内容涵盖内核启动前的各项事宜,包括设备探测、init启动等。在系统启动时,当屏幕文本颜色由白变灰,若不太确定启动情况,便能看到系统的检测信息。
一、启动过程的基本概念
打开计算机并启动操作系统,看似简单,实则蕴含一个有趣的两难问题。从定义上讲,计算机在操作系统启动前,并不具备执行任务的能力,包括从磁盘运行程序。那么,操作系统究竟是如何启动的呢?这就如同《The Adventures of Baron Munchausen》中描述的场景:一个人沿着检修孔往下爬,然后通过抓住自己的解靴带(bootstrap)又爬了上来。在计算机发展早期,“bootstrap”这一术语被用于描述加载操作系统的机制,后来简称为“booting” 。
在x86系统中,加载操作系统的重任主要由基本输入输出系统(BIOS)承担。BIOS首先会检查磁盘的主引导记录(MBR),MBR位于磁盘的特定位置。BIOS加载并运行MBR,而MBR除了加载操作系统外,还能执行其他任务。
若计算机仅安装了一个操作系统,标准的MBR便能发挥作用。它会搜索磁盘上的第一个启动slice,然后在该slice上运行代码,以加载引导操作系统的其余部分程序。
倘若磁盘上安装了多个操作系统,就可以安装不同的MBR。这种MBR能够显示不同操作系统的列表,允许用户选择要启动的系统。FreeBSD就采用了这样的MBR,当然,其他操作系统也会提供各自的MBR。
二、FreeBSD的启动阶段
FreeBSD的bootstrap系统可分为三个阶段:
- 第一阶段:运行MBR,此阶段MBR的作用是将计算机带入特定状态。
- 第二阶段:执行的程序相比第一阶段有所增加。
- 第三阶段:完成操作系统的加载任务。
之所以将这一过程划分为三个阶段,是因为PC的标准对程序大小有限制。通过这种分阶段的方式,FreeBSD得以提供一个较为灵活的加载程序。
内核启动后,会对设备进行探测和初始化。一旦内核启动完成,就会将控制权交给用户处理进程init。init负责确定磁盘是否可用,接着启动用户级资源配置,加载文件系统,设置网卡以激活网络,最后启动所有在FreeBSD运行时通常会启动的进程。
三、FreeBSD启动过程中的关键组件
MBR与/boot/boot0:FreeBSD的MBR驻留在/boot/boot0上,不过这只是一个拷贝,真正的MBR必须放置在磁盘的特定部分,且位于FreeBSD区域之外。boot0十分简单,主引导区的程序仅有512字节。若已安装FreeBSD的MBR,且计算机上还安装了多个操作系统,启动时将会看到如下熟悉的画面:
F1 DOS F2 FreeBSD F3 Linux F4?? F5 Drive 1 Default: F2
其他操作系统,如Windows,可能会用自身的MBR覆盖已有的MBR。若遇到这种情况,或者想要替换为FreeBSD的MBR,可使用以下命令:
fdisk -B -b /boot/boot0 device
其中,device指的是用于启动的设备,例如第一个IDE磁盘ad0、第二个IDE控制器上的第一个磁盘ad2、第一个SCSI磁盘da0等。
/boot/boot1与/boot/boot2:这两个文件是位于磁盘同一区域的同一个程序的两个部分。由于磁盘空间的限制,它们被分割开来,但安装时必须放在一起。它们位于启动slice的启动扇区,/boot目录中的文件只是真实文件的副本,真实文件存储在FreeBSD文件系统之外。
- boot1同样简单,可能只有512字节。当FreeBSD存储的磁盘分区信息的磁盘标签(Disklabel)清晰可辨时,找到它后便可执行boot2。
- boot2相对复杂一些,它记录着FreeBSD的文件系统,便于在其上查找文件,同时还提供了一个简单的接口,用于选择要运行的内核或引导程序。Loader更为复杂,它提供了易于使用的启动配置信息,通常在boot2之后运行,但以前它可以直接运行内核。boot2画面类似如下:
>> FreeBSD/i386 BOOT Default: 0:ad(0,a)/kernel boot:
若需要替换已安装的boot1和boot2,可使用disklabel命令:
disklabel -B diskslice
这里的diskslice是启动系统的磁盘和slice的位置,比如ad0s1,表示第一个IDE磁盘的第一个slice。需要注意的是,如果在disklabel命令中仅使用磁盘名称,如ad0,将会创建一个危险的磁盘,因为没有指定slice。所以在按下RETURN键之前,务必反复检查disklabel命令。
/boot/loader:引导程序loader是启动过程三步中的最后一步,位于文件系统的/boot/loader。Loader使用一套易于使用的内建命令集进行友好配置,同时还具备一套复杂的命令集,通过强大的接口进行备份。
- Loader的执行过程:在初始化过程中,loader会探测到控制台和一些磁盘,并确定从哪个磁盘启动。之后,它会设置为可变化状态,解释程序开始启动,命令也会被解释执行。默认情况下,启动程序会停顿10秒钟(期间可按任意键继续),然后启动内核。若进程被打断,用户可使用命令调整参数、卸载或装载模块,最后进入系统或重新启动。若想深入了解技术细节,可阅读loader的联机手册。
Loader内建命令:
autoboot seconds
:在规定时间内若未被打断,将继续启动内核,默认倒计时时间为10秒钟。boot [-options] [kernelname]
:直接配合给定参数启动内核。boot - conf
:在启动时,使用自动的变量配置模块,此命令仅在先用unload
时才有意义,且通常用于改变一些变量,如kernel
。help [topic]
:显示来自/boot/loader.help的求助信息,若给定的主题(topic)是索引(index),则会显示所有主题列表。include filename...
:执行给定文件,该文件将被逐行读入并执行,一旦出现错误,include
命令将直接停止。load [-t type] filename
:加载kernel
、kernel
模块或原先指定的文件类型,后跟文件名。文件后的任何参数都将传递给该文件执行。ls [-l] [path]
:列出给定路径中的文件。若未指定路径,将显示root目录的文件列表。若带有-l
参数,将同时显示文件大小。lsdev [-v]
:列出所有可加载模块的设备,若指定-v
参数,将列出更详细的信息。lsmod [-v]
:显示已加载的模块,若指定-v
参数,将一并列出更详细的信息。more filename
:在显示的每一行添加终止符,显示指定文件的内容。reboot
:直接重新启动系统。set variable, set variable = value
:设置loader的环境变量。unload
:卸载所有已加载的模块。
Loader举例:
- 在单用户模式下启动普通内核:
boot -s
- 卸载普通内核和模块,然后引导旧(或另一个)内核:
- 在单用户模式下启动普通内核:
unload load kernel.old
这里可以使用kernel.GENERIC
,即安装光盘上的通用kernel,也可以使用kernel.old
。
- 按照以下步骤,配合原先的模块加载其他的kernel:
unload
set kernel = “kernel.old”
boot - conf
- 加载内核配置的脚本文件(这是一个自动脚本文件,用于执行在kernel启动阶段所需执行的命令):
load -t userconfig_script
/boot/kernel.conf
「倘若有所帮助,不妨酌情赞赏!」
感谢您的支持!
使用微信扫描二维码赞赏
你好,关于FreeBSD在安装操作系统时,进入"Escape to loader prompt."模式后,加载一个ko文件"load **.ko",总是提示找不到文件,关于这个ko,能提示一下哪里的问题吗,谢谢
@王女士
你是不是升级了kernel然后把系统升挂了? 这是进入了救援模式,ko一般是驱动程序。建议回滚