操作系统的启动分为两个阶段:引导boot和启动过startup,引导阶段开始于打开电源开关,结束于内核初始化完成和systemd进程成功运行,启动阶段接管了剩余工作,直到操作系统进入可操作状态。
总体可将LINUX开机启动过程分为四个步骤:
1. BIOS上电自检(POST)
2. 引导装载程序(GRUB2)
3. 内核初始化
4. 启动systemd,其为所有进程之父
注意,本文以 GRUB2 和 systemd 为载体讲述操作系统的开机引导和启动过程,是因为这二者是目前主流的 linux 发行版本所使用的引导装载程序和初始化软件。当然另外一些过去使用的相关软件仍然在一些 Linux 发行版本中使用。
一、引导过程
引导过程能以两种方式初始化,其一当系统处于关机状态时,打开电源即可开启系统引导过程;其二当操作系统已经在运行在本地用户,则用户可借助图形界面或命令行界面通过编程方式发起一个重启操作,从而触发系统引导过程。重启包括了一个关机和重新开始过程。
1. BIOS上电自检
上电自检主要是由硬件部分完成,当电脑电源接通时,即开始执行BIOS的POST(power on self test)过程,初始化硬件组件,用于检验电脑硬件基本功能是否正常。如果POST失败,那么电脑便不能使用,引导中断。
BIOS 上电自检确认硬件的基本功能正常,然后产生一个 BIOS 中断 INT 13H,该中断指向某个接入的可引导设备的引导扇区。它所找到的包含有效的引导记录的第一个引导扇区将被装载到内存中,并且控制权也将从引导扇区转移到此段代码。
引导扇区是引导加载器真正的第一阶段。大多数 Linux 发行版本使用的引导加载器有三种:GRUB、GRUB2 和 LILO。GRUB2 是最新的,也是相对于其他老的同类程序使用最广泛的。
2. GRUB2
GRUB2(grand unified bootloader,version 2),用于计算机寻找操作系统内核并加载其到内存的智能程序,被设计为兼容操作系统多重引导规范,能够用来引导不同版本的Linux和其他开源操作系统,还能链式加载专有操作系统的引导记录。
GRUB2可通过文件/boot/grub2/grub.conf进行配置
GRUB2分三个阶段将内核加载到内存中并运行:
2.1 POST阶段结束时,BIOS将查找在接入的磁盘中查找引导记录,通常位于MBR(master boot record),它加载找到的第一个引导记录到内存中,并开始执行此代码。引导代码必须非常小,因为它必须连同分区表放到硬盘的第一个512字节的扇区中。传统的MBR中,引导代码实际所占用空间大小为446字节,叫做引导镜像,其中不包含设备的分区信息,分区是一般单独添加到引导记录中。此阶段功能定位并加载下一阶段的代码。
2.2 该阶段代码必须位于引导记录与设备第一个分区之间的位置,第一个分区的开始位置在扇区 63 和 MBR(扇区 0)之间遗留下 62 个 512 字节的扇区(共 31744 字节),该区域用于存储阶段 1.5 的代码镜像 core.img 文件。该文件大小为 25389 字节,故此区域有足够大小的空间用来存储 core.img。该阶段功能是开始执行存放在下一阶段的/boot文件系统的驱动程序,并加载相关的去驱动程序。
2.3 该阶段主要从/boot/grub2/i386-pc目录下加载一些内核运行时模块,主要功能是定位和加载linux内核到内存中,并转移控制权到内核,内核相关文件位于/boot目录下,这些内核文件可以通过其文件名进行识别,其文件名均带有前缀 vmlinuz。
在选定的内核加载到内存中并开始执行后,在其进行任何工作之前,内核文件首先必须从压缩格式解压自身,一旦内核解压万完成,则加载systemd进程,并转移控制权到systemd。
此时,引导过程结束,Linux内核和systemd处于运行状态,但没有任何程序在执行,也不能执行任何用户的功能性任务。
二、启动过程
启动过程使Linux系统进入可操作状态,并能够执行用户功能性任务。
systemd是所有进程之父,负责将Linux主机带到一个用户可操作状态,可以管理运行中Linux主机很多方面,包括挂载文件系统,开机和管理Linux主机的系统服务等。
1. systemd挂载在/etc/fstab/中配置的文件系统,包括内存交换文件或分区。
systemd 借助其配置文件 /etc/systemd/system/default.target
决定 Linux 系统应该启动达到哪个状态(或目标态target)。default.target
是一个真实的 target 文件的符号链接。对于桌面系统,其链接到 graphical.target
,该文件相当于旧式 systemV init 方式的 runlevel 5。对于一个服务器操作系统来说,default.target
更多是默认链接到 multi-user.target
, 相当于 systemV 系统的 runlevel 3。 emergency.target
相当于单用户模式。
所有的目标态target和服务service都是systemd的单元unit
2. 启动过sysinit.target和basic.target
sysinit.target
和 basic.target
目标态可以被视作启动过程中的状态检查点。尽管 systemd 的设计初衷是并行启动系统服务,但是部分服务或功能目标态是其它服务或目标态的启动的前提。系统将暂停于检查点直到其所要求的服务和目标态都满足为止。
sysinit.target
状态的到达是以其所依赖的所有资源模块都正常启动为前提的,所有其它的单元,如文件系统挂载、交换文件设置、设备管理器的启动、随机数生成器种子设置、低级别系统服务初始化、加解密服务启动(如果一个或者多个文件系统加密的话)等都必须完成,但是在 sysinit.target 中这些服务与模块是可以并行启动的。
sysinit.target
启动所有的低级别服务和系统初具功能所需的单元,这些都是进入下一阶段 basic.target 的必要前提。
在 sysinit.target
的条件满足以后,systemd 接下来启动 basic.target
,启动其所要求的所有单元。 basic.target
通过启动下一目标态所需的单元而提供了更多的功能,这包括各种可执行文件的目录路径、通信 sockets,以及定时器等。
3. 初始化用户级目标态(mutil-user.target/graphical.target)
图 1 中,以 *
开头的目标态是通用的启动状态。当到达其中的某一目标态,则说明系统已经启动完成了。如果 multi-user.target
是默认的目标态,则成功启动的系统将以命令行登录界面呈现于用户。如果 graphical.target
是默认的目标态,则成功启动的系统将以图形登录界面呈现于用户,界面的具体样式将根据系统所配置的显示管理器而定。