Linux启动流程详解
操作系统的启动分为两个阶段引导(boot)和启动(startup),引导阶段开始于打开电源开关,结束于内核初始化完成和systemd进程。启动阶段接管了剩余的工作,直到操作系统进入可操作状态。
操作系统的开机引导和启动过程很容易理解,主要分为以下几个部分:
- BIOS上电自检(POST)
- 引导装载程序(GRUB2)
- 内核初始化
- 启动systemd,其是所有进程之父
上电自检
上电自检的过程其实Linux什么也没做,上电主要由硬件部分来完成,这对于所有的操作系统都一样,接通电源后,开始执行BIOS基本输入输出系统(Basic I/O System)的POST上电自检(Power On Self Test)过程。BIOS上电自检确认硬件的基本功能正常,然后产生一个BIOS中断和INT 13H,该中断指向某个接入的可引导设备的引导扇区,它所找到的包含有效的引导记录的第一个引导扇区装在到内存中,并且内核的控制权也从引导扇区转移到此段代码。
引导扇区是引导加载器真正的第一阶段,大多数Linux发行版本使用的引导加载器有三种:GRUB、GRUB2和LILO。GRUB2是最新的,也是使用最广泛的。
GRUB2
GRUB2 全称是 GRand Unified BootLoader,Version 2(第二版大一统引导装载程序)。它是目前流行的大部分 Linux 发行版本的主要引导加载程序。GRUB2 是一个用于计算机寻找操作系统内核并加载其到内存的智能程序。
GRUB通过/boot/grub/grub.conf进行配置。而/boot/grub2/grub.cfg配置GRUB2
两个GRUB的最主要作用都是把内核加载到内存运行,基本工作方式也一致,主要阶段也保持相同,都可分为三个阶段
阶段1
如上文 POST(上电自检)阶段提到的,在 POST 阶段结束时,BIOS 将查找在接入的磁盘中查找引导记录,其通常位于 MBR(主引导记录Master Boot Record),它加载它找到的第一个引导记录中到内存中,并开始执行此代码。引导代码(及阶段 1 代码)必须非常小,因为它必须连同分区表放到硬盘的第一个 512 字节的扇区中。 在传统的常规 MBR 中,引导代码实际所占用的空间大小为 446 字节。这个阶段 1 的 446 字节的文件通常被叫做引导镜像(boot.img),其中不包含设备的分区信息,分区是一般单独添加到引导记录中。
·由于引导记录必须非常的小,它不可能非常智能,且不能理解文件系统结构。因此阶段 1 的唯一功能就是定位并加载阶段 1.5 的代码。为了完成此任务,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。在加载阶段 1.5 代码进入内存后,控制权将由阶段 1 转移到阶段 1.5。
阶段1.5
如上所述,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。该空间由于历史上的技术原因而空闲。第一个分区的开始位置在扇区 63 和 MBR(扇区 0)之间遗留下 62 个 512 字节的扇区(共 31744 字节),该区域用于存储阶段 1.5 的代码镜像 core.img 文件。该文件大小为 25389 字节,故此区域有足够大小的空间用来存储 core.img。
因为有更大的存储空间用于阶段 1.5,且该空间足够容纳一些通用的文件系统驱动程序,如标准的 EXT 和其它的 Linux 文件系统,如 FAT 和 NTFS 等。GRUB2 的 core.img 远比更老的 GRUB1 阶段 1.5 更复杂且更强大。这意味着 GRUB2 的阶段 2 能够放在标准的 EXT 文件系统内,但是不能放在逻辑卷内。故阶段 2 的文件可以存放于 /boot
文件系统中,一般在 /boot/grub2
目录下。
注意 /boot
目录必须放在一个 GRUB 所支持的文件系统(并不是所有的文件系统均可)。阶段 1.5 的功能是开始执行存放阶段 2 文件的 /boot
文件系统的驱动程序,并加载相关的驱动程序。
阶段2
GRUB 阶段 2 所有的文件都已存放于 /boot/grub2
目录及其几个子目录之下。该阶段没有一个类似于阶段 1 与阶段 1.5 的镜像文件。相应地,该阶段主要需要从 /boot/grub2/i386-pc
目录下加载一些内核运行时模块。
GRUB 阶段 2 的主要功能是定位和加载 Linux 内核到内存中,并转移控制权到内核。内核的相关文件位于 /boot
目录下,这些内核文件可以通过其文件名进行识别,其文件名均带有前缀 vmlinuz。你可以列出 /boot
目录中的内容来查看操作系统中当前已经安装的内核。
GRUB2 跟 GRUB1 类似,支持从 Linux 内核选择之一引导启动。Red Hat 包管理器(DNF)支持保留多个内核版本,以防最新版本内核发生问题而无法启动时,可以恢复老版本的内核。默认情况下,GRUB 提供了一个已安装内核的预引导菜单,其中包括问题诊断菜单(recuse)以及恢复菜单(如果配置已经设置恢复镜像)。
阶段 2 加载选定的内核到内存中,并转移控制权到内核代码。
内核
内核文件都是以一种自解压的压缩格式存储以节省空间,它与一个初始化的内存映像和存储设备映射表都存储于 /boot
目录之下。
在选定的内核加载到内存中并开始执行后,在其进行任何工作之前,内核文件首先必须从压缩格式解压自身。一旦内核自解压完成,则加载 systemd 进程(其是老式 System V 系统的 init 程序的替代品),并转移控制权到 systemd。
这就是引导过程的结束。此刻,Linux 内核和 systemd 处于运行状态,但是由于没有其他任何程序在执行,故其不能执行任何有关用户的功能性任务。
启动过程
启动过程紧随引导过程之后,启动过程使 Linux 系统进入可操作状态,并能够执行用户功能性任务。
systemd
systemd 是所有进程的父进程。它负责将 Linux 主机带到一个用户可操作状态(可以执行功能任务)。systemd 的一些功能远较旧式 init 程序更丰富,可以管理运行中的 Linux 主机的许多方面,包括挂载文件系统,以及开启和管理 Linux 主机的系统服务等。但是 systemd 的任何与系统启动过程无关的功能均不在此文的讨论范围。
首先,systemd 挂载在 /etc/fstab
中配置的文件系统,包括内存交换文件或分区。据此,systemd 必须能够访问位于 /etc
目录下的配置文件,包括它自己的。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
相当于单用户模式。
(LCTT 译注:“target” 是 systemd 新引入的概念,目前尚未发现有官方的准确译名,考虑到其作用和使用的上下文环境,我们认为翻译为“目标态”比较贴切。以及,“unit” 是指 systemd 中服务和目标态等各个对象/文件,在此依照语境译作“单元”。)
注意,所有的目标态target和服务service均是 systemd 的单元unit。
https://linux.cn/article-8807-1.html