资讯动态

Linux启动流程全解析:从BIOS到systemd的接力赛

发布时间:2026/10/21 5:44:51 来源:尧图企业网站定制
先别急着去啃内核源码也别一上来就盯着那满屏滚动的日志发呆。搞懂Linux启动过程最省力的方式是把它想象成一场接力赛。从你按下电源键到桌面或登录界面出现这中间的每一步都像是一棒接一棒的交棒过程每一棒都有明确的职责边界和交接条件。搞清楚了谁在跑、在哪交棒、交棒时需要满足什么条件整个系统的启动逻辑就豁然开朗了。这篇文章就是带你以“看接力赛”的视角把Linux启动全流程拆开揉碎。不管你是刚入门的运维新人还是被启动问题折磨过的老手看完你都能清晰地说出每个阶段发生了什么、出了问题该去哪查。我会结合实测命令和排查经验把启动过程中那些“只可意会”的细节变成你随时能上手用的工具。1. 启动流程全景五棒接力各有分工Linux启动从头到尾可以清晰地划分为五个阶段对应接力赛里的五个角色棒次阶段名称对应接力角色核心任务交付物交接棒第一棒固件阶段BIOS/UEFI裁判第一棒选手硬件自检找到可启动的磁盘启动设备指针第二棒Bootloader引导器GRUB2第二棒选手加载内核与initramfs到内存内核镜像initramfs第三棒内核初始化第三棒选手硬件抽象挂载initramfs切换到真正的根文件系统第四棒init/systemd启动第四棒选手启动系统服务与任务进入默认目标状态第五棒用户态服务与应用最后一棒启动显示管理器、网络等登录界面/Shell之所以把固件阶段也比作“第一棒选手”是因为早期的BIOS/UEFI不只是“裁判”它们本身也承担着从磁盘读取引导程序的任务。这个阶段虽然很短但却是整个接力赛的起点没有它后面的选手连上跑道的机会都没有。理解这张表你就抓住了Linux启动的“主线剧情”。接下来我们把每一棒都拉近一点看搞清楚每段路程里到底发生了什么。2. 第一棒与第二棒从通电到看到内核前的“暗箱操作”2.1 固件阶段BIOS与UEFI的关键选择这一棒发生在操作系统“睁眼”之前。你按下电源键CPU还是“失忆”状态它先去固定的物理地址读取固件代码这个地址就是中断向量表的一号复位向量。固件BIOS或UEFI开始执行首先是POST上电自检检查CPU、内存、显卡、键盘这些最基本的硬件是否存在。POST不通过机器会直接罢工有的主板用报警声提示有的直接黑屏。POST通过后固件开始它的第二阶段按你设定的启动顺序Boot Order依次去扫描硬盘、SSD、U盘、光驱甚至网卡寻找一个“可以启动的标记”。传统BIOS的做法读取设备第一个扇区的512字节MBR检查最后两个字节是不是0x55AA如果是就认为这个设备可启动然后把控制权交给MBR里的代码。UEFI的做法它不读MBR它直接扫描EFI系统分区ESP分区里的.efi文件比如\EFI\GRUB\grubx64.efi。找到后直接把这个文件加载到内存并执行。这里有个非常重要的实操点现在新买的电脑基本都是UEFI启动但UEFI里面常开着“CSM兼容模式”来兼容老系统。如果你遇到“U盘启动盘做好了插上却启动不了”的情况大概率不是U盘坏了而是启动模式不匹配。比如你的启动盘是用Legacy模式做的但BIOS里强制了UEFI Only它们之间就是“鸡同鸭讲”。2.2 BootloaderGRUB2的使命与配置实战固件找到了启动设备接下来就轮到Bootloader出场了。目前主流的Linux发行版用的是GRUB2它在整个启动过程中干三件事加载配置文件读取/boot/grub2/grub.cfg在RHEL系或/boot/grub/grub.cfg在Debian系这个文件就是GRUB的“比赛战术板”里面记录了可用内核列表、启动参数、默认启动项等。把内核加载进内存如果配置了initrd它还会把initramfs镜像一起加载到内存指定地址。转移控制权GRUB通过boot命令把CPU控制权正式交给内核入口。如果你家里装了双系统比如Windows和Linux共存GRUB会做一个“抢跑”动作它去扫描其他分区通过os-prober找到Windows的引导管理器并在菜单里生成一个“Windows Boot Manager”条目。实操中最常遇到的问题是内核更新后重启时GRUB菜单还是旧的。所以很多发行版在更新内核后会自动执行grub2-mkconfig -o /boot/grub2/grub.cfg来重新生成配置文件。如果你手动改了/etc/default/grub里的超时时间或默认启动项记得必须重新生成一次配置不然你改的内容不会生效这个坑我踩过不止一次。GRUB还有一个“救命功能”按e键进入编辑模式可以临时修改启动参数。比如你想临时进入单用户模式改密码不用重新做安装盘直接在GRUB菜单的光标处按e在linux16或linux那行末尾加上init/bin/bash或rd.break再按Ctrlx启动就行。这是真正能在关键时刻救你一命的操作。3. 第三棒的核心内核启动与initramfs的“空中加油”3.1 内核初始化从实模式到保护模式GRUB把内核加载进内存后处理器这时还处于“实模式”Real Mode这个模式下CPU只能访问1MB内存非常原始。内核刚被加载进来时也是一副“懵懂”状态。它的第一件事是把自己切换到“保护模式”Protected Mode或64位长模式从而获得完整的4GB甚至更大的内存访问能力。这段切换过程由内核镜像自带的startup_32和startup_64汇编代码完成随后进入start_kernel()函数这会初始化内核的各个子系统内存管理、进程调度器、文件系统、网络协议栈等。听起来很复杂但你可以把它理解为“内核这个大脑的各个脑叶依次苏醒”。3.2 initramfs为什么需要这个“临时拐杖”内核在启动早期磁盘驱动、文件系统驱动可能还没编译进内核本体而是以模块形式存放在根文件系统里。这就形成了一个“鸡生蛋还是蛋生鸡”的问题内核要加载根文件系统的内容但读取根文件系统又需要驱动。解决办法就是initramfs早期根文件系统。它是一个小型的、直接加载进内存的文件系统镜像里面包含了内核启动早期必须的驱动比如SATA控制器驱动、USB驱动、NVMe驱动和启动脚本。内核先把这个简单的小型根文件系统挂载起来用它作为“脚手架”加载齐所有驱动后再真正挂载你的磁盘根分区。这就像接力赛中第三棒选手在跑动中并不是直接冲向终点而是先在一个临时缓冲区里完成“空中加油”再继续跑。3.3 关键参数root与switch_root在GRUB的启动参数里你会看到root这个参数它指定了真正的根文件系统所在位置比如root/dev/mapper/centos-root或rootUUIDxxxx。内核拿到这个参数后在initramfs里执行完驱动加载就会执行switch_root命令把根目录从内存的initramfs切换到磁盘上的真实根分区。注意UUID比/dev/sdX更可靠因为/dev/sdX在Linux下会根据磁盘识别顺序动态变化比如插拔U盘后原来的/dev/sda可能变成/dev/sdb导致重启后找不到根分区。UUID是文件系统的唯一标识不随设备名变化。这也是很多安装程序默认用UUID的原因。如果你在initramfs阶段就卡住比如提示dracut-initqueue: timeout或者Failed to mount /sysroot十有八九是root参数写错了或者磁盘阵列、LVM的设备在initramfs里没有被正确组装。此时可以在GRUB菜单按e检查一下root的值然后临时改成正确的UUID再启动验证。4. 第四棒与第五棒init进程与systemd的“接力冲刺”4.1 从内核态到用户态init进程的诞生内核完成根文件系统切换后会启动第一个用户态进程。传统SysV init路径下内核会执行/sbin/init而在现代systemd发行版中它执行的是/usr/lib/systemd/systemd并通过符号链接让/sbin/init指向它。这个进程的PID永远是1它是所有进程的“老祖宗”。内核在进入用户态之前还会做一些收尾工作比如挂载/proc和/sysfs虚拟文件系统然后才会执行init程序。这看起来是一瞬间的事但这个过程对整个系统至关重要因为从这一秒开始内核不再是“独角戏”后续的系统初始化全部交给用户态工具。4.2 systemd的并行启动机制谈到用户态启动就绕不开systemd。它之所以流行很大原因就是它把原来SysV“串行启动”变成了“并行启动”。SysV的做法是一个脚本按顺序执行服务B要等A完全起来才能开始整体启动慢如蜗牛。sysv有时候一个网络服务起来了要等好几秒才轮到下一个。systemd的核心是unit单元每个unit是一个配置文件描述一个服务、套接字、设备或挂载点。它通过分析unit之间的依赖关系构建出一个“启动依赖树”只要能同时满足条件的服务就同时在多核CPU上并行启动。比如你的Apache服务只依赖network.target和local-fs.target那它就不用等MySQL启动完因为两者没有直接依赖关系。实际操作中你使用systemctl命令时背地里就是在和这套依赖系统打交道。比如systemctl disable httpd不只是把服务停止了还把它从开机启动的依赖链里去掉了。4.3 Target机制启动级别的新形态SysV时代我们用init 3或init 5来切换运行级别3代表多用户命令行5代表图形界面。systemd沿用了这个思想但把它抽象成了更灵活的target目标单元。特别地multi-user.target多用户命令行模式通常对应传统的运行级别3。graphical.target图形界面模式通常在multi-user的基础上再启动显示管理器。emergency.target紧急救援模式相当于带最小化环境的单用户模式。设置默认启动目标不需要改文件一条命令搞定# 查看当前默认目标 systemctl get-default # 设置默认进入图形界面 systemctl set-default graphical.target # 设置默认进入命令行界面 systemctl set-default multi-user.target理解target机制你就掌握了“开机进入哪个世界”的开关。很多系统调优的第一步就是把不需要的图形界面关闭能显著缩短启动时间。4.4 用户态服务的启动顺序与依赖实例现在我们把眼光放到一个具体服务上比如nginx。systemd如何知道要启动它它依赖什么我们可以直接查看服务的unit文件systemctl cat nginx.service具体例子以某发行版上的nginx.service为例[Unit] DescriptionA high performance web server and a reverse proxy server Wantsnetwork-online.target Afternetwork.target Documentationman:nginx(8) [Service] Typeforking PIDFile/run/nginx.pid ExecStartPre/usr/bin/rm -f /run/nginx.pid ExecStart/usr/sbin/nginx ExecReload/usr/sbin/nginx -s reload ExecStop/bin/kill -s QUIT $MAINPID PrivateTmptrue [Install] WantedBymulti-user.target这里几个关键点Afternetwork.target表示nginx要在网络服务启动之后才启动。这不是强依赖而是“顺序先后”的约定。WantedBymulti-user.target表示这个服务被multi-user.target“想要”开机进入多用户模式时它就会被自动拉起。Typeforking表示nginx会自己fork分离为后台守护进程systemd需要通过PIDFile来跟踪主进程的PID。如果你遇到“服务明明显示active但就是访问不了端口”需要检查的往往不是unit文件而是依赖链上的其他环节比如防火墙或SELinux。systemd只是负责“把服务拉起来”至于服务内部是否健康它只能通过ExecStartPost等脚本去探测。这点在排查时要注意别在错误的方向上浪费太多时间。5. 实操验证亲手“看”一场启动接力赛前面讲了那么多理论不如亲手验证一遍。Linux系统其实留下了大量“比赛录像”关键是你得知道去哪儿回放。5.1 systemd-analyze官方版“秒表计时器”systemd自带一个工具可以精确统计每个阶段耗时# 查看总启动时间与固件、内核、用户态耗时 systemd-analyze # 查看每个unit的启动耗时排行 systemd-analyze blame # 分析依赖链找关键路径上的耗时单元 systemd-analyze critical-chain实测输出大概长这样Startup finished in 3.072s (firmware) 7.874s (loader) 2.227s (kernel) 9.325s (userspace) 22.498s graphical.target reached after 9.325s in userspace如果你发现blame里排第一的是某个等待网络超时的服务比如NetworkManager-wait-online.service那就要重点检查网络配置了。很多时候启动慢不是硬件差而是服务在傻等一个永远等不到的“网络就绪”信号。5.2 查看内核启动日志dmesg与journalctl内核启动阶段的日志用journalctl -k或dmesg来查看。比如想确认磁盘驱动是否正常加载可以journalctl -k | grep -i sda\|nvme\|failed这个命令会在内核日志里搜索磁盘设备名和“failed”关键字快速定位硬件层面的错误。如果你在启动过程中看到花屏或黑屏但系统又在继续运行往往能从这些日志里找到显卡驱动的报错。5.3 修改GRUB参数观测即时变化实战中我想给大家一个立即能用的技巧如果你的系统启动缓慢且systemd-analyze blame显示某个服务耗时异常可以先试试减少不必要的自启动服务# 查看当前自启动服务列表 systemctl list-unit-files --typeservice --stateenabled # 关闭某个确定不需要的服务如内置打印服务cups systemctl disable cups systemctl stop cups这个操作不会影响系统稳定性但需要你确认该服务确实不需要。比如服务器上关闭蓝牙服务完全不心疼但如果在笔记本上关了蓝牙就用不了了。通过反复禁用、重启、跑systemd-analyze你会慢慢找到“哪一步最耽误时间”的感觉这种“测量-调整-再测量”的循环才是真正快速掌握启动过程的“捷径”。6. 常见问题与排查技巧实录我在帮同事和客户排查启动问题时遇到过不少有意思的坑这里挑几个最有代表性的整理成速查表希望能帮你少走弯路。现象可能原因快速排查方法解决办法开机卡在GRUB菜单进不了系统GRUB配置文件错误或内核文件缺失重启后在GRUB菜单按e查看linux行是否包含有效root进入救援模式重新安装或修复内核执行grub2-mkconfig启动过程中出现“Failed to mount /sysroot”根文件系统设备名错误或驱动未加载在GRUB菜单按e检查rootUUID是否正确修改/etc/default/grub中的GRUB_CMDLINE_LINUX指定正确UUID启动极慢卡在“A start job is running for wait for network”网络服务等待超时systemd-analyze blame查耗时禁用NetworkManager-wait-online.servicesystemctl mask NetworkManager-wait-online.serviceinitramfs阶段提示缺少设备或超时initramfs里缺少对应磁盘驱动进入救援模式执行dracut -f或update-initramfs -u重建initramfs确认新驱动已加入后重建镜像并更新GRUB配置重启后GRUB菜单没有Windows选项os-prober未找到或未启用执行os-prober手动检测安装并启用os-prober重新生成grub.cfg开机直接进入紧急模式emergency mode/etc/fstab挂载项有误journalctl -xb查看报错修正fstab里的错误挂载项或注释掉出错的设备6.1 启动卡死的通用排查思路如果遇到开机卡住别慌张按下面这个顺序走能解决大部分问题看电源灯和屏幕提示如果完全黑屏没有任何字符先怀疑硬件自检失败检查内存条、显卡、电源是否正常。看GRUB是否出现如果GRUB出现但卡住不动在e编辑界面删除quiet参数后面追加nomodeset可以绕过显卡驱动加载失败的问题。看内核日志是否滚动如果内核日志滚动到一半卡住拍下最后输出的几行文字用手机拍下来放大看往往就是罪魁祸首。比如常见的BUG: soft lockup - CPU#N stuck for 22s!提示的就是某个CPU核心死锁。看是否进入initramfs或systemd阶段如果看到类似Reached target Basic System就卡住继续按CtrlAltF2切换到其他TTY终端用root登录查看日志。6.2 一个真实的排查案例曾经有个模拟项目X系统启动总是慢到让人怀疑人生每次开机等很久才出现登录界面而且毫无规律。用systemd-analyze blame查看发现NetworkManager-wait-online.service耗时高达90秒。我们刚开始以为是网络配置问题反复修改网络连接参数没用。后来我把这台机器接到独立网段上看才发现因为网卡没有插网线NetworkManager一直在尝试连接一个不存在的网络每次都等待超时。解决方案很简单把网卡连接设为“lightly优先”模式或者直接把NetworkManager-wait-online.service屏蔽掉。屏蔽之后启动时间从90秒直接掉到5秒效果立竿见影。这个案例告诉我们启动慢不一定是“性能问题”更多时候是“等待问题”。找到那个“傻等”的内鬼你就赢了。排查的时候journalctl -xb会打印出启动时的所有标记和错误还可以配合systemctl status查看具体服务的状态千万别只盯着硬件参数。6.3 修改内核启动参数让系统“看得见”Linux启动时默认情况下内核会把大量的启动日志压缩输出到屏幕上很多发行版还会用quiet参数把细节隐藏掉。如果你想看清楚每一步发生了什么在GRUB菜单按e把quiet和rhgbRed Hat Graphical Boot删掉保留或加上rd.shell再加break参数就能在initramfs阶段掉进一个调试shell让你亲手操作“空中加油”的过程。举个例子# 在GRUB菜单按e之后在linux行末尾加入这些参数 systemd.log_leveldebug rd.shell启动后会进入一个带有dracut提示符的调试环境你可以手动执行ls /dev/sd*、mount /dev/sda1 /sysroot等命令验证驱动是否加载、分区能不能挂载。这是排查启动问题的终极手段比看日志更直接因为你能亲手摸到系统“跑到一半”时的那口气。7. 写在最后把启动流程变成你的排查地图我个人在实际操作中的体会是学启动过程最忌讳死记硬背流程图而是要在脑子里建立一张“检查地图”哪一步卡住了应该优先看哪个日志、查哪个服务、改哪个参数。按下电源键的那一刻是整个系统最脆弱也是最诚实的一刻所有配置错误、硬件故障、依赖缺失都会在这一刻毫无保留地暴露出来。如果你能亲手把一台机器的启动时间从90秒调优到5秒或者靠GRUB编辑模式救回一台起不来的服务器你对Linux的理解会有一个质的提升。下次再遇到问题别急着重装系统先在GRUB菜单停一停进journalctl -xb里翻一翻静下心看一遍这场接力赛你大概率能找到那条断掉的“接力棒”。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑