作为开发者,我们几乎每天都和Linux打交道,但你是否曾好奇,从按下电源到出现登录提示,系统内部究竟经历了什么?本文将带你一步步拆解Linux的完整启动流程,理解每个环节背后的原理与作用。如果你想与其他开发者交流系统层面的心得,欢迎来到 云栈社区 一起探讨。
下图清晰地展示了Linux从开机到登录的八个核心步骤。

步骤 1 - 按下电源开机后,BIOS(基本输入输出系统)或 UEFI(统一可扩展固件接口)固件会从非易失性存储器中加载,并执行 POST(上电自检)。
步骤 2 - BIOS/UEFI 会检测系统连接的各类硬件设备,包括 CPU、内存(RAM)和存储设备。
步骤 3 - 选定用于启动操作系统的引导设备,可选设备包括硬盘、网络服务器或光盘驱动器(CD-ROM)。
步骤 4 - BIOS/UEFI 运行引导加载程序(GRUB),该程序会提供选择菜单,供用户选择要启动的操作系统或内核功能项。
步骤 5 - 内核加载就绪后,系统切换至用户空间。内核会启动 systemd 作为第一个用户空间进程,该进程负责管理系统进程与服务、检测剩余所有硬件、挂载文件系统,并启动桌面环境。
步骤 6 - 系统启动时,systemd 会默认激活 default.target(默认目标单元),同时执行其他配套单元。
步骤 7 - 系统运行一系列启动脚本,完成系统环境的配置。
步骤 8 - 系统为用户展示登录界面,至此系统启动完成,进入可用状态。
步骤1:BIOS/UEFI固件加载与POST上电自检
1.1 BIOS/UEFI固件的唤醒机制
电源键触发后,电源管理单元向主板提供稳定供电,固化于主板ROM芯片中的BIOS(基本输入输出系统)或UEFI(统一可扩展固件接口)固件随即启动,作为硬件与操作系统的底层交互接口,承担系统启动的初始化引导任务。
BIOS作为传统固件方案,诞生于20世纪70年代,长期承担计算机启动引导功能。其运行于16位实模式,引导过程完全依赖MBR(主引导记录)。MBR位于硬盘第一个扇区,占用512字节存储空间,包含分区表信息与引导代码,BIOS读取并执行该引导代码后,方可推进后续启动流程。随着计算机技术的发展,尤其是操作系统向32位、64位升级,BIOS的局限性日益凸显,16位模式及1MB内存地址空间的限制,已无法满足现代计算机的启动需求。
UEFI作为BIOS的继任者,是由UEFI论坛发布的标准固件接口,采用32位或64位保护模式,支持2TB及以上大容量硬盘,可通过GPT(GUID分区表)替代传统MBR。相较于MBR,GPT分区表不仅突破硬盘容量限制,还具备更可靠的分区结构及更多分区数量支持。此外,UEFI自带图形用户界面,提升启动过程中的交互便捷性,其固件代码维护性更强,开机检测耗时更短,可显著提升系统启动效率。
1.2 POST上电自检的核心任务
BIOS/UEFI固件启动后,立即执行POST(Power-On Self-Test,上电自检)流程。POST的核心目标是全面验证核心硬件的正常运行状态,规避硬件故障导致的启动中断。
POST自检优先对CPU进行检测,核查CPU寄存器、缓存的运行状态,确认其型号、频率等关键参数符合设计标准。CPU作为计算机的核心运算单元,其稳定性直接决定系统整体运行可靠性。内存作为数据存储与交换的核心组件,同样是POST检测的重点内容,系统通过快速读写测试,验证内存控制器与内存条的通信稳定性,以及内存寻址、存储功能的完整性,内存检测通过是系统正常存储与读取数据的前提。
显卡是POST检测的关键环节之一,固件将初始化显卡控制器并尝试输出显示信号。若显卡存在接口松动、硬件损坏等问题,将出现黑屏、花屏等显示异常,直接影响系统输出信息的获取。
此外,POST还将检测键盘、鼠标等输入设备,以及硬盘、SSD、光驱等存储设备,确认各类设备与主板连接正常且可被系统识别。存储设备若无法被识别,将导致操作系统无法加载,启动流程终止。
若某一硬件检测失败,系统将通过蜂鸣声代码或屏幕提示输出故障信息,例如“NO VIDEO”提示指向显卡故障,“Hard Drive Not Found”提示硬盘未被识别。不同厂商的BIOS/UEFI蜂鸣声代码定义存在差异,可通过查阅主板手册定位具体故障原因。所有硬件检测通过后,系统将发出短促提示音,标志POST自检完成,启动流程继续推进。
步骤2:BIOS/UEFI的全量硬件检测
POST完成核心硬件初步验证后,BIOS/UEFI将开展全量硬件检测,覆盖主板芯片组、各类扩展设备及外部设备,确保硬件生态的稳定性,为操作系统加载及运行提供可靠支撑。
主板芯片组作为硬件系统的核心枢纽,负责协调CPU、内存、存储设备及各类外部设备的数据传输与通信,是本次检测的重点。BIOS/UEFI将全面核查芯片组的型号、版本及功能完整性,例如检测北桥芯片与CPU、内存、显卡等高速设备的通信通道通畅性,北桥芯片故障将严重影响系统性能;同时验证南桥芯片对USB控制器、SATA控制器等低速设备的控制能力,保障数据传输的稳定性与可靠性。
USB控制器作为外部USB设备的连接核心,其检测至关重要。BIOS/UEFI将核查USB控制器的端口数量、传输速率,以及设备识别与枚举能力,USB控制器故障可能导致U盘无法读取、USB鼠标键盘失灵等问题。检测过程中,固件通过向USB控制器发送指令,验证其对不同类型USB设备的兼容性与响应效率。
除USB设备外,BIOS/UEFI还将检测键盘、鼠标、打印机等常见外部设备:对键盘,检测按键扫描码的正常性,判断是否存在按键粘连或损坏;对鼠标,检测其移动、点击功能及与主板的通信稳定性。设备故障时,固件将通过屏幕提示输出故障信息,便于故障定位。
与POST仅聚焦核心硬件的检测模式不同,本次全量检测覆盖主板全组件及各类外部设备,可有效规避操作系统启动后因硬件兼容性或故障导致的运行异常。所有硬件检测通过后,BIOS/UEFI进入下一启动环节。
步骤3:选定系统启动设备
BIOS/UEFI完成全量硬件检测并确认正常后,进入启动设备选择环节。该环节将依据预设启动顺序(Boot Order),从各类存储设备中筛选可引导的存储介质,作为操作系统加载的载体。
BIOS/UEFI选择启动设备时遵循严格的优先级规则,通常将硬盘(HDD/SSD)设为首选启动设备。硬盘作为操作系统的主流存储载体,具备数据稳定性高、读取速度快的优势,可保障系统快速启动。若硬盘中安装多个操作系统,固件将按内置规则优先启动默认操作系统所在分区。
除硬盘外,U盘、网络服务器、光盘驱动器(CD-ROM)均为常见启动设备。U盘广泛应用于系统安装、维护场景,将U盘制作成启动盘并调整启动顺序后,系统可从U盘读取引导程序执行相关操作。网络服务器启动主要应用于无盘工作站、瘦客户机等特殊场景,此类设备无本地存储,需通过网络从服务器获取操作系统镜像及相关文件完成启动,实现集中化管理与部署。光盘驱动器虽已逐步淘汰,但在部分旧设备及特定软件安装场景中仍可发挥作用。
传统BIOS模式下,选定启动设备后,固件将读取该设备的MBR扇区。MBR仅占用512字节,包含三部分核心内容:前446字节为主引导程序,负责加载操作系统核心;中间64字节为分区表,记录硬盘各分区的起始位置与大小;最后2字节为有效标志符“55AA”,用于验证MBR有效性。BIOS读取MBR后,先验证标志符,验证通过则执行主引导程序,继续推进操作系统加载。
UEFI模式的启动流程更为简洁高效,固件直接读取EFI系统分区(ESP)中的引导程序。ESP分区采用FAT32文件系统,存储.efi后缀的引导文件,固件将查找“bootx64.efi”“grubx64.efi”等核心引导文件并执行,进而启动操作系统。相较于BIOS,UEFI不仅支持更大容量硬盘,还可提供更灵活的启动配置。
实际应用中,可根据需求在BIOS/UEFI设置界面手动调整启动顺序。例如从U盘安装系统时,开机按下对应快捷键(通常为Del、F2、F10等,具体因主板型号而异),进入“Boot”选项界面,将U盘设为第一启动项,保存配置并重启后,即可实现从U盘启动。
步骤4:BIOS/UEFI 运行引导加载程序 (GRUB)
4.1 GRUB的分阶段引导原理
BIOS/UEFI选定引导设备后,将加载引导程序。Linux系统中,应用最广泛的引导程序为GRUB(GRand Unified Bootloader)。GRUB作为硬件与操作系统内核的衔接核心,采用分阶段引导设计,有效解决BIOS/UEFI无法直接识别Ext4、LVM、XFS等复杂Linux文件系统的问题。
GRUB第一阶段(Stage1)驻留于硬盘MBR或EFI分区,该阶段引导程序高度精简,核心功能为定位并加载下一阶段引导程序。由于MBR存储空间有限(仅512字节,需容纳分区表及启动标志),留给引导程序的空间不足446字节,无法承载完整功能的GRUB引导器,因此Stage1仅完成基础硬件初始化,包括屏蔽中断、关闭处理器缓存等,为后续引导程序加载创造稳定环境。
GRUB第二阶段(Stage1.5)包含文件系统驱动程序,是GRUB与Linux文件系统实现通信的核心。借助该阶段的驱动程序,GRUB可读取/boot/grub目录下的相关内容。Stage1.5由Stage1根据预设信息从硬盘特定位置读取至内存,完成与下一阶段引导的衔接准备。
GRUB第三阶段(Stage2)为引导程序核心,采用C语言编写。该阶段将加载图形化启动菜单,提供可视化交互界面;同时读取grub.cfg配置文件,获取内核文件路径、根文件系统位置、启动参数等关键信息。随后,GRUB将Linux内核文件(通常命名为vmlinuz)与初始化内存盘(initrd或initramfs)加载至内存,完成内核启动的准备工作。
4.2 GRUB的核心功能实现
Stage2加载完成并读取grub.cfg配置文件后,GRUB核心功能正式发挥作用。grub.cfg作为GRUB的核心配置文件,包含启动菜单项、默认启动项、超时时间、内核启动参数等关键配置。例如,set default=0用于将第一个菜单项设为默认启动项,set timeout=5用于设置启动菜单显示时长为5秒。
多操作系统环境中,GRUB的多系统引导功能具备极高实用性。开机后,用户可通过键盘上下箭头键在GRUB启动菜单的不同操作系统选项间切换。以Linux与Windows双系统为例,GRUB将在菜单中列出两个系统的启动选项,选定对应选项并确认后,GRUB将按配置加载相应系统内核:针对Windows系统,GRUB通过chainloader +1指令将引导权移交至Windows引导程序;针对Linux系统,GRUB读取配置文件中指定的内核路径,同时传递根文件系统路径、只读挂载、启动参数等关键信息。
GRUB支持启动时临时修改内核启动参数,在启动菜单界面按下e键即可进入编辑模式,对内核命令行进行调整。例如,添加initcall_debug参数可用于硬件调试,添加nouveau.modeset=0 rd.driver.blacklist=nouveau参数可禁用nouveau驱动,为NVIDIA驱动安装提供支持。临时修改仅对本次启动有效,若需永久修改,需编辑/etc/default/grub文件,调整参数后执行对应命令:Debian/Ubuntu系统执行update-grub,RHEL/CentOS/Fedora系统执行grub2-mkconfig -o /boot/grub2/grub.cfg,使修改生效。
用户选定启动项并确认后,GRUB按配置将Linux内核与初始化内存盘载入内存。内核作为Linux系统核心,包含操作系统核心代码,负责系统资源管理、进程调度及硬件驱动提供;初始化内存盘为临时文件系统,存储启动根文件系统所需的驱动程序与工具。加载完成后,GRUB将系统控制权移交至内核,引导使命完成,系统进入内核初始化阶段。
步骤5:切换用户空间与systemd启动
GRUB完成内核与初始化内存盘的加载后,Linux系统进入内核接管阶段,标志着系统从引导加载阶段正式过渡至内核初始化与用户空间构建阶段。
5.1 内核空间与用户空间的微妙转换
32位Linux系统中,每个进程拥有4GB虚拟地址空间,其中低3GB(0x00000000至0xBFFFFFFF)为用户空间,用于用户进程运行;高1GB(0xC0000000至0xFFFFFFFF)为内核空间,存储内核代码与数据结构,供所有进程共享。
内核空间作为操作系统的核心控制区域,运行在内核态的代码具备最高权限,可直接访问硬件设备、掌控系统资源;用户空间为普通应用程序的运行区域,运行在用户态的程序权限受限,无法直接操作硬件,需通过系统调用向内核请求服务。这种空间划分可有效隔离内核与用户程序,避免用户程序错误操作导致系统崩溃,显著提升系统稳定性与安全性。
系统从GRUB引导进入内核初始化阶段后,完成从引导程序环境至内核空间的切换。此时内核全面接管系统,依次完成中断处理机制初始化、内存管理体系构建、进程调度框架搭建等核心操作,为系统稳定高效运行奠定基础。
5.2 systemd:用户空间的“领航者”
内核完成初始化并挂载根文件系统后,将启动systemd进程作为首个用户空间进程,其进程ID(PID)固定为1。systemd作为用户空间的核心管理组件,承担系统进程与服务管理、剩余硬件检测、文件系统挂载、桌面环境启动等关键职责,是用户空间运行的核心枢纽。
systemd采用单元(Unit)管理模式,将系统中的服务、套接字、挂载点、设备等各类资源抽象为独立单元,实现统一管理。每个单元对应独立配置文件,详细定义单元属性、依赖关系及启动、停止方式。
以Nginx服务为例,其对应的systemd服务单元配置文件通常位于/etc/systemd/system/nginx.service或/usr/lib/systemd/system/nginx.service路径。配置文件中,[Unit]部分描述服务基本信息与依赖关系,例如Description=The nginx web and reverse proxy server定义服务描述,After=network-online.target remote-fs.target nss-lookup.target明确Nginx服务需在网络、远程文件系统、名称服务查找等目标单元启动后启动。
[Service]部分定义服务运行方式:Type=forking表示服务采用fork方式启动(主进程创建子进程后退出,子进程负责实际运行);ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf指定服务启动命令及配置文件路径;ExecReload=/usr/sbin/nginx -s reload与ExecStop=/usr/sbin/nginx -s quit分别定义服务配置重载与停止命令。
[Install]部分用于设置服务开机自启与依赖关系,WantedBy=multi-user.target表示该服务在多用户模式下被依赖,系统切换至multi-user.target目标时,Nginx服务自动启动。通过灵活的配置设计,systemd可精准控制各服务的启动顺序与运行状态,保障各类服务协同工作。
并行启动是systemd的核心特性之一,可显著提升系统启动效率。传统初始化系统中,服务需按顺序逐个启动,单个服务故障可能导致后续服务启动中断;systemd可分析服务依赖关系,实现多个独立服务的并行启动,充分利用多核处理器优势,缩短启动耗时。例如,启动Nginx、MySQL、Redis等服务时,systemd可实现三者并行启动,无需等待前一服务完成,大幅提升启动效率。
systemd启动过程中,将按预设规则依次激活sysinit.target、basic.target、multi-user.target等目标单元:sysinit.target负责系统基础初始化,包括系统时钟设置、内核模块加载等;basic.target完成系统基本配置,包括基础文件系统挂载、日志服务启动等;multi-user.target为多用户模式目标,激活后启动用户登录、网络等相关服务,提供完整多用户工作环境。若系统启用图形界面,systemd将额外激活graphical.target目标单元,启动GDM、SDDM等显示管理器,呈现桌面环境,完成从内核空间至用户空间的过渡,为用户使用提供支撑。
步骤6:systemd的default.target统筹调度
systemd进程启动后,default.target目标单元成为系统服务启动与配置的核心,其激活标志着系统进入服务调度关键阶段。
systemd管理体系中,default.target替代传统SysVinit的运行级别概念,本质为符号链接,根据系统环境不同,通常指向multi-user.target(多用户文本模式)或graphical.target(图形界面模式)。服务器环境中,为保障稳定性与资源利用率,default.target多指向multi-user.target,系统启动后直接进入文本模式,专注于网络服务提供与后台任务处理;桌面环境中,default.target指向graphical.target,启动后自动加载显示管理器,呈现图形界面,满足用户便捷操作需求。
systemd激活default.target时,将递归处理其依赖关系,按顺序激活所需目标单元,如basic.target与sysinit.target。其中,sysinit.target负责系统基础初始化,包括内核模块加载(提供硬件支持)、交换空间启用(内存不足时存储临时数据)、本地文件系统挂载(保障系统数据访问与管理);basic.target在sysinit.target基础上完成系统进一步配置,包括日志服务启动(记录系统运行事件,便于故障排查)、系统消息总线启动(实现系统组件间高效通信)。
除激活依赖目标单元外,default.target还将启动一系列相关服务单元。这些服务单元以符号链接形式存放在/etc/systemd/system/default.target.wants目录,指向/usr/lib/systemd/system目录下的实际服务配置文件。例如,network.service负责网络接口配置,搭建系统通信通道;sshd.service提供安全远程登录服务,支持管理员远程管理系统。各服务将按自身配置与依赖关系有序启动,协同保障系统正常运行。
systemd的并行启动特性在本阶段得到充分体现。与传统SysVinit的顺序启动模式不同,systemd通过分析服务依赖关系,实现独立服务的并行启动,充分利用多核处理器优势,缩短系统启动耗时。例如,启动Nginx、MySQL、Redis等服务时,无需等待前一服务启动完成,可并行推进,加快系统进入可用状态的速度。
实际应用中,可通过systemctl命令查看default.target的依赖关系与服务状态:systemctl list-dependencies default.target可清晰展示default.target的依赖单元及层次关系;systemctl status 服务名.service可查看具体服务的运行状态,判断服务是否正常启动及是否存在故障,为启动过程中的故障排查提供支撑。
步骤7:环境配置!执行系统启动脚本
default.target目标单元激活后,systemd按配置依次执行rc.sysinit、rc.local等启动脚本。此类脚本承担系统环境变量设置、网络参数配置、swap分区启用、用户自定义服务加载等关键任务,为系统正常运行提供基础保障。
rc.sysinit脚本作为系统初始化的核心脚本,率先执行一系列基础关键任务。环境变量设置方面,该脚本将常用命令路径、系统配置参数等存入环境变量,便于系统与应用程序随时调用,例如设置PATH环境变量,实现可执行文件的快速查找,无需输入完整路径。网络参数配置方面,rc.sysinit读取/etc/sysconfig/network等配置文件,获取IP地址、网关等关键信息,完成网络初始化,搭建系统通信通道,保障系统正常接入网络。
swap分区启用是rc.sysinit的重要职责。swap分区作为系统虚拟内存,当物理内存不足时,系统将临时不用的数据存入swap分区,避免系统卡顿或崩溃。rc.sysinit将检查/etc/fstab文件中的swap分区配置,激活swap分区,为系统提供额外内存支持,保障系统运行流畅性。
rc.local脚本主要用于执行用户自定义启动任务,为用户提供个性化启动配置入口。用户可将自定义脚本或命令添加至rc.local,实现系统启动时的自动执行,例如自动挂载额外文件系统、启动自定义服务等。需注意,rc.local脚本需具备可执行权限,且命令与路径配置准确,否则将导致脚本执行失败。
不同Linux发行版的启动脚本执行顺序与配置方式存在差异。以CentOS系统为例,rc.sysinit位于/etc/rc.d/目录,启动早期执行,完成系统基础初始化;rc.local默认无执行权限,需通过chmod +x /etc/rc.d/rc.local命令赋予可执行权限,方可正常运行。Ubuntu系统中,rc.sysinit的功能分散至多个upstart脚本与systemd单元,rc.local通过rc-local.service服务管理,可通过systemctl enable rc-local.service命令启用自动执行功能。
各类启动脚本协同工作,完成系统环境的全面配置,确保系统运行所需的参数与服务全部到位,使Linux系统启动后快速进入最佳工作状态,提供高效可靠的服务支撑。
步骤8:呈现登录界面与系统就绪
所有启动脚本执行完毕后,systemd启动终端或图形界面服务,呈现登录界面,标志着Linux系统完成从通电至可用的全流程启动,正式进入可使用状态。
文本模式下,systemd启动getty服务,为各终端设备创建登录提示。用户输入正确的用户名与密码后,系统执行身份验证,验证通过后进入用户shell环境,用户可通过命令行执行各类操作,开展日常工作。
图形界面模式下,systemd激活display-manager.service服务,启动GDM、SDDM等显示管理器。显示管理器呈现登录界面,提供用户切换、语言选择等功能,用户输入账号密码并通过验证后,进入GNOME、KDE等桌面环境,通过图形化操作实现系统使用。
Linux启动流程各环节紧密衔接、环环相扣,协同运转。任一环节出现问题,均可能导致启动失败:例如BIOS/UEFI无法检测硬件,将导致引导设备无法找到;GRUB配置错误,将导致内核无法加载;systemd服务依赖冲突,将影响系统整体功能。
深入掌握Linux启动流程,不仅可实现启动故障的快速定位与高效解决,还可根据实际需求优化系统:服务器环境中,可精简不必要的服务、优化启动脚本,提升启动速度与稳定性;桌面环境中,可选择适配的显示管理器与桌面环境,构建个性化系统。
【大厂标准】Linux C/C++ 后端进阶学习路线
Linux内核学习指南,硬核修炼手册