Linux系统的启动是一个涉及硬件、固件和软件协同工作的复杂过程,从用户按下电源键到最终进入用户界面,经历了一系列精心设计的初始化阶段,理解这一流程不仅有助于系统管理,也能在出现启动故障时快速定位问题,以下从硬件加电开始,逐步拆解Linux系统的完整启动链路。
电源开启与BIOS/UEFI初始化
按下电源键后,计算机首先执行的是主板固化固件(BIOS或UEFI)的加电自检(POST),POST阶段会检测CPU、内存、显卡、硬盘等核心硬件是否正常,若发现硬件故障,通常会通过蜂鸣器或错误码提示,硬件自检通过后,固件会根据预设的启动顺序(如硬盘、U盘、网络)寻找引导设备。
传统BIOS采用16位实模式,仅支持2TB以下容量的MBR分区,而现代UEFI(统一可扩展固件接口)则采用32/64位保护模式,支持GPT分区、Secure Boot安全启动(验证引导加载器和内核签名)以及快速启动(Fast Boot,跳过部分硬件检测),UEFI还会读取引导设备的EFI系统分区(ESP),加载其中的引导加载器程序,这是与BIOS的关键区别之一。
引导加载器(GRUB2)阶段
主流Linux发行版普遍使用GRUB(Grand Unified Bootloader)作为引导加载器,其中GRUB2是当前版本,当固件找到引导设备后,会加载GRUB2的第一阶段引导程序(位于硬盘的MBR或ESP分区),该程序负责加载第二阶段引导程序,并读取GRUB2的配置文件(通常为/boot/grub2/grub.cfg
或/boot/grub/grub.cfg
)。
GRUB2配置文件定义了启动菜单项、内核路径、initramfs文件路径及内核参数,若系统安装多个操作系统,GRUB2会显示菜单供用户选择;若未设置超时,默认启动第一个条目,选定后,GRUB2会将内核(如/boot/vmlinuz-5.15.0-76-generic
)和初始RAM磁盘(initramfs,如/boot/initrd.img-5.15.0-76-generic
)加载到内存中,并将控制权交给内核。
GRUB2配置文件关键参数示例:
menuentry "Ubuntu Linux" { linux /boot/vmlinuz-5.15.0-76-generic root=/dev/sda2 ro quiet splash initrd /boot/initrd.img-5.15.0-76-generic }
linux
行指定内核路径和根文件系统位置(root=/dev/sda2
),ro
表示以只读模式挂载根文件系统(后续会切换为读写);initrd
行加载initramfs,为内核提供启动初期的驱动和工具。
内核加载与解压
内核被加载到内存后,首先进行自解压(现代内核通常为压缩格式,如zImage或bzImage),解压完成后,内核会初始化核心硬件子系统(如进程调度、内存管理、中断处理),并检测CPU、总线等设备。
随后,内核会挂载根文件系统(rootfs),此时根文件系统尚未完全可用,因此需要借助initramfs提供的临时环境,initramfs是一个内存中的微型文件系统,包含必要的驱动程序(如存储驱动、RAID驱动、LVM驱动)、文件系统工具(如mount
、fsck
)和二进制文件(如/sbin/init
),内核会以initramfs为根,执行/init
脚本(通常是/usr/lib/systemd/systemd
或/sbin/init
),完成根文件系统的挂载和切换。
initramfs的核心作用:
- 为内核提供启动初期所需的硬件驱动(如SATA、NVMe、RAID),否则内核可能无法识别真实根文件系统;
- 在挂载真实根文件系统前,检查并修复文件系统错误(通过
fsck
); - 挂载真实根文件系统后,清理临时环境并切换到真实根文件系统。
systemd初始化系统
当内核切换到真实根文件系统后,会启动系统的第一个进程(PID为1),该进程由initramfs中的/init
脚本决定,现代Linux发行版普遍采用systemd作为init系统,取代了传统的SysVinit和Upstart。
systemd启动流程的核心是“并行化”和“依赖管理”:
- 挂载基本文件系统:systemd首先挂载
/proc
(进程信息)、/sys
(设备信息)、/dev
(设备文件)等虚拟文件系统,这些文件系统为内核和用户空间提供交互接口。 - 启动systemd-initrd.target:若仍在initramfs环境,systemd会执行initramfs的清理任务;若已切换到真实根文件系统,则继续后续流程。
- 解析依赖关系:systemd通过单元文件(Unit File,
.service
、.target
、.mount
等)定义服务间的依赖关系,例如network.target
依赖sysinit.target
(系统初始化目标),而sysinit.target
又依赖local-fs.target
(本地文件系统挂载)。 - 启动默认目标:systemd的默认目标(Default Target)通常为
graphical.target
(图形界面)或multi-user.target
(命令行多用户),默认目标由/etc/systemd/system/default.target
文件定义,实际是符号链接,如default.target -> graphical.target
。
systemd目标与传统运行级别的对应关系:
传统运行级别 | systemd目标 | 说明 |
---|---|---|
0 | poweroff.target | 关机 |
1 | rescue.target | 救援模式(单用户) |
2,3,4 | multi-user.target | 多用户命令行模式 |
5 | graphical.target | 多用户图形界面模式 |
6 | reboot.target | 重启 |
系统服务启动与用户登录
在确定默认目标后,systemd会根据依赖关系并行启动所需服务。multi-user.target
需要启动sshd
(SSH服务)、cron
(定时任务)、network.service
(网络服务)等;graphical.target
则额外启动display-manager.service
(如gdm3
、sddm
图形登录管理器)。
服务启动过程中,systemd会通过socket
(套接字)、device
(设备)、mount
(挂载点)等激活器(Activator)按需启动服务,而非全部常驻内存,从而提高资源效率,当有SSH连接请求时,sshd.socket
会触发sshd.service
启动。
服务启动完成后,若为图形界面模式,系统会加载X Window System或Wayland显示服务器,启动图形登录界面(如GDM、SDDM),用户输入用户名和密码后,登录进程(如/bin/bash
或桌面环境)启动,最终进入桌面环境或命令行终端。
相关问答FAQs
Q1:Linux启动过程中卡在GRUB菜单界面,无法进入系统,如何解决?
A:通常由GRUB配置错误或根文件系统问题导致,可尝试以下步骤:
- 进入GRUB菜单界面,选择“Advanced options for Ubuntu”或类似条目,查看是否能进入恢复模式;
- 若无法进入,通过GRUB命令行(按
c
键)手动指定内核和initramfs路径,linux (hd0,gpt2)/boot/vmlinuz-5.15.0-76-generic root=/dev/sda2 ro initrd (hd0,gpt2)/boot/initrd.img-5.15.0-76-generic boot
- 若能进入系统,检查
/boot/grub2/grub.cfg
中的root
参数是否正确(根文件系统设备名可通过lsblk
或fdisk -l
确认); - 若GRUB配置丢失,可重新生成:
sudo update-grub
。
Q2:如何查看Linux系统启动耗时及慢的服务?
A:使用systemd提供的systemd-analyze
命令:
- 查看总启动耗时:
systemd-analyze
,显示从内核启动到系统就绪的总时间; - 查看详细启动时间分布:
systemd-analyze blame
,按耗时排序列出各服务启动时间; - 生成启动流程图:
systemd-analyze plot > boot-plot.svg
,用SVG查看器打开可视化流程; - 分析特定服务依赖:
systemd-analyze critical-chain sshd.service
,查看sshd.service
的启动依赖链,定位瓶颈。
通过以上工具,可快速定位启动缓慢的服务(如某驱动加载失败或服务依赖过多),针对性优化。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/28202.html