当一台装有 CentOS 8 的服务器按下电源键后,一系列复杂而有序的流程便悄然启动,理解这一启动过程不仅是系统管理员进行故障排查、性能优化的基础,也是深入掌握 Linux 系统工作原理的关键,与传统的 SysVinit 不同,CentOS 8 采用了更为先进的 systemd
作为其初始化系统和服务管理器,这使得其启动流程更加高效且可配置。
本文将详细剖析 CentOS 8 从加电到用户可登录的完整启动旅程,涵盖硬件初始化、引导加载程序、内核加载、initramfs
以及 systemd
的核心作用。
硬件初始化与 MBR/GPT 引导
一切始于硬件,当电源接通,计算机的主板会自动执行存储在 ROM 或 Flash 芯片中的基本输入/输出系统 (BIOS) 或其现代继任者——统一可扩展固件接口 (UEFI)。
- POST (开机自检):无论 BIOS 还是 UEFI,其首要任务都是执行开机自检,这个过程会检测 CPU、内存、硬盘等关键硬件是否存在并工作正常。
- 引导设备查找:POST 成功后,固件会根据预设的启动顺序(可在 BIOS/UEFI 设置中配置)查找可引导的设备,如硬盘、USB 驱动器或网络接口。
- 加载引导扇区:找到引导设备后,固件会读取该设备的最开始部分,对于使用传统 BIOS 的系统,它会读取主引导记录 (MBR);对于使用 UEFI 的系统,它会读取 EFI 系统分区 (ESP) 中的引导程序。
MBR 和 ESP 是两种不同的引导方案,其主要区别如下:
特性 | BIOS (MBR) | UEFI (GPT) |
---|---|---|
分区表 | MBR (主引导记录),支持最多4个主分区 | GPT (GUID 分区表),支持几乎无限数量的分区 |
磁盘大小 | 最大支持约 2TB | 理论上支持极大容量 (远超当前需求) |
安全性 | 较低,无安全启动功能 | 支持 Secure Boot,可验证引导程序的签名 |
引导文件 | 存储在 MBR 和磁盘的“间隙”中 | 存储在独立的 EFI 系统分区 (FAT32 格式) |
GRUB2 引导加载程序
CentOS 8 使用 GRUB2 (GRand Unified Boot Loader version 2) 作为其默认的引导加载程序,它的核心职责是加载 Linux 内核和初始内存盘到内存中,并将控制权交给内核。
- Stage 1:位于 MBR 或 ESP 中的非常小的一段代码,其唯一目的是加载下一阶段的引导程序。
- Stage 1.5 (可选):位于 MBR 和第一个分区之间,或 ESP 中,它包含文件系统驱动程序,使 GRUB 能够识别常见的文件系统(如 ext4),从而找到下一阶段的配置文件。
- Stage 2:这是 GRUB 的核心部分,通常位于
/boot/grub2/
目录下,它会读取其配置文件/boot/grub2/grub.cfg
,并向用户显示一个菜单(如果配置了多个内核或操作系统)。
grub.cfg
文件定义了可用的内核选项、内核参数、initramfs
镜像位置等信息,需要注意的是,这个文件通常由 grub2-mkconfig
工具根据 /etc/default/grub
和 /etc/grub.d/
目录下的脚本自动生成,不建议手动直接编辑。
用户在 GRUB 菜单中选择一个内核后(或等待超时后使用默认内核),GRUB2 会执行以下操作:
- 将选定的内核文件(
/boot/vmlinuz-4.18.0-...el8.x86_64
)加载到内存中。 - 将对应的
initramfs
镜像文件(/boot/initramfs-4.18.0-...el8.x86_64.img
)加载到内存中。 - 将内核启动参数传递给内核。
- 将 CPU 的控制权完全移交给已加载的内核。
内核加载与 initramfs
内核被解压缩并开始执行时,它首先会进行自身的初始化,包括探测和初始化硬件设备(CPU、内存、中断控制器等),并挂载一个临时的、基于内存的根文件系统——initramfs
。
initramfs
(initial RAM filesystem) 是一个至关重要的组件,为什么需要一个临时的根文件系统?因为真正的根文件系统 () 可能位于一些“复杂”的存储设备上,
- LVM (逻辑卷管理)
- 软件 RAID (如 mdadm)
- 加密分区 (如 LUKS)
核心内核本身通常不包含访问这些特殊存储设备所需的驱动程序和工具。initramfs
中恰好打包了这些必要的内核模块、用户空间工具(如 lvm
, mdadm
, cryptsetup
)以及一个小的初始化脚本。
initramfs
中的脚本会运行,加载所需的内核模块,激活 LVM 卷或 RAID 阵列,如果需要则提示输入密码以解密根分区,一旦真正的根文件系统被成功挂载到 /sysroot
,系统会执行 switch_root
操作,将根目录从内存中的 initramfs
切换到硬盘上的真实根文件系统 (),至此,initramfs
的使命完成,它占用的内存会被释放。
systemd
接管与服务启动
当真正的根文件系统被挂载后,内核会启动用户空间的第一个进程,在 CentOS 8 中,这个进程就是 /sbin/init
,它是一个指向 /usr/lib/systemd/systemd
的符号链接,这标志着 systemd
正式接管系统,成为所有进程的祖先 (PID 1)。
systemd
的核心是“单元”的概念,系统中的几乎所有资源都被抽象为一个单元,并由单元文件进行配置,常见的单元类型包括:
单元类型 | 描述 | 示例 |
---|---|---|
.service | 一个系统服务,通常是一个守护进程。 | httpd.service (Apache Web 服务器) |
.target | 一组单元的同步点,类似于旧的“运行级别”。 | multi-user.target (多用户模式) |
.mount | 一个文件系统的挂载点。 | home.mount (挂载 /home 分区) |
.device | 一个内核识别的设备。 | dev-sda.device (第一块 SCSI 硬盘) |
.socket | 一个进程间通信的套接字。 | Cups.socket (打印服务套接字) |
systemd
的启动流程是基于依赖关系的,它会解析所有单元文件,构建一个依赖关系图,然后按照这个图来启动服务,它使用 Wants=
、Requires=
、After=
、Before=
等指令来定义单元之间的关系,得益于这种依赖图,systemd
可以并行启动那些没有依赖关系的服务,从而大大缩短了系统启动时间。
整个启动过程围绕着一系列的“目标”展开:
systemd
首先启动default.target
,这是一个符号链接,通常指向graphical.target
(图形界面) 或multi-user.target
(命令行多用户模式)。default.target
会拉入它所依赖的一系列基础目标和单元,如sysinit.target
(系统初始化)、basic.target
(基础功能) 和local-fs.target
(本地文件系统挂载)。- 这些基础目标会依次完成硬件设备管理、文件系统检查与挂载、内核参数设置、日志系统启动等底层任务。
default.target
会启动所有配置为在该级别下运行的服务(.service
单元),如网络服务 (NetworkManager.service
)、SSH 服务 (sshd.service
) 等。
当 default.target
所需的所有服务都成功启动后,系统的启动流程便宣告完成,系统会启动 getty
进程在控制台提供登录提示,或者启动显示管理器(如 GDM)提供图形化登录界面,至此,CentOS 8 系统已完全准备好,等待用户进行交互。
相关问答 (FAQs)
问题1:如何查看 CentOS 8 的启动过程以及各个服务所花费的时间?
回答:CentOS 8 提供了强大的 systemd-analyze
工具来分析启动性能,你可以使用以下命令:
systemd-analyze
:查看系统启动到每个阶段(固件、引导加载程序、内核、用户空间)所花费的总时间。$ systemd-analyze Startup finished in 1.234s (firmware) + 2.567s (loader) + 3.890s (kernel) + 8.765s (userspace) = 16.456s
systemd-analyze blame
:列出所有正在运行的单元,并按它们启动时花费的时间进行降序排列,这对于找出拖慢启动速度的“罪魁祸首”非常有用。$ systemd-analyze blame 8.765s NetworkManager-wait-online.service 3.210s firewalld.service 1.500s sshd.service ...
systemd-analyze critical-chain
:以“关键链”的形式展示启动流程,这条链路上的单元是后续重要单元启动的前提,它可以帮你识别出启动路径上的瓶颈。
问题2:我安装了一个新内核,但想让它作为默认启动项,或者我想给内核传递一个启动参数,应该如何操作?
回答:修改 GRUB2 的默认设置需要谨慎操作,主要分为三个步骤:
修改配置文件:编辑
/etc/default/grub
文件。- 更改默认内核:找到
GRUB_DEFAULT
参数,默认值通常是saved
,表示使用上次选择的内核,你可以将其设置为0
(表示菜单中的第一个内核) 或1
(第二个内核),也可以直接写成内核的完整名称(GRUB_DEFAULT="CentOS Linux (4.19.0-...el8.x86_64) 8 (Core)"
)。 - 添加启动参数:找到
GRUB_CMDLINE_LINUX
参数,在引号内添加你需要的参数,net.ifnames=0 biosdevname=0
用于统一网卡命名,或systemd.unit=rescue.target
用于直接进入救援模式。GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=cl/root rhgb quiet net.ifnames=0"
- 更改默认内核:找到
重新生成 GRUB 配置:这是最关键的一步,否则你的修改不会生效,运行以下命令,该命令会读取
/etc/default/grub
和/etc/grub.d/
中的文件,并生成最终的/boot/grub2/grub.cfg
。# sudo grub2-mkconfig -o /boot/grub2/grub.cfg
(对于 UEFI 系统,路径通常是
/boot/efi/EFI/centos/grub.cfg
,但-o
参数使用上述路径通常也能正确处理)重启系统:保存所有更改并重启系统,新的 GRUB 配置就会生效。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复