计算机Boot启动流程解析:从BIOS/UEFI到GRUB与内核加载

发布时间:2026/10/11 19:57:50
计算机Boot启动流程解析:从BIOS/UEFI到GRUB与内核加载
1. 项目概述1.1 Boot是什么为什么值得关注先直接说结论Boot就是计算机从按下电源键到操作系统完全可用之间的那一整套流程。中文通常叫启动或引导这个词在英语里既有靴子的意思也有启动的含义——系统引导的过程被形象地比喻成自己提着鞋带把自己拉起来因为早期计算机没有操作系统时必须用一小段手工加载的代码去把完整的操作系统读入内存这段代码就是引导程序。我最早接触Boot这个概念时以为是开机之后那个转圈的加载动画或者在Windows下看到的Windows Logo。后来做了几年Linux运维和开发才意识到Boot远不只是等一会儿就好这么简单。它是操作系统生命周期中最关键、也最容易出问题的一个环节内核怎么被找到根文件系统怎么挂载服务按什么顺序启动哪一个环节卡住了会导致系统起不来——这些都属于Boot的范畴。这篇内容我会把Boot涉及的核心知识点拆开讲清楚包括主流引导方式Legacy BIOS和UEFI、Bootloader的作用、内核启动参数、initramfs以及常见的启动故障排查思路。同时会加入一些我在实际环境里踩过的坑比如启动参数写错导致磁盘找不到、GRUB配置被覆盖、系统更新后突然进不去桌面等场景。如果你正在准备运维面试、想自己折腾双系统或Linux发行版或者工作中经常处理服务器起不来的问题这篇文章应该能帮你把Boot这条链路彻底打通。1.2 一条完整的启动链路长什么样先给一个整体视图后面会逐个环节展开。按下电源键 → CPU执行固化在ROM里的启动代码固件 → 固件完成硬件自检POST → 固件按启动顺序查找可引导设备 → 从设备上读取Bootloader引导程序 → Bootloader加载操作系统内核 → 内核初始化硬件、挂载根文件系统 → 启动第一个用户态进程init或systemd → 系统服务按依赖关系启动 → 登录界面出现这个链路里固件BIOS/UEFI负责找到引导程序引导程序负责加载内核内核负责初始化系统。三者分工明确任何一层出问题都会导致启动失败。很多人看到Boot失败的报错就慌其实只要弄明白卡在哪一层排查思路自然就有了。2. 启动流程核心原理解析2.1 固件层的两代方案Legacy BIOS与UEFI2.1.1 Legacy BIOS引导老而弥坚在UEFI普及之前计算机用的都是传统BIOS基本输入输出系统。BIOS本身是一个固化在主板ROM芯片里的固件程序负责在开机时初始化硬件然后去找第一个可引导设备。Legacy BIOS的引导逻辑可以概括为BIOS执行POST自检检测CPU、内存、显卡、硬盘等关键硬件。按CMOS配置里的启动顺序软驱、光驱、硬盘、USB等逐个设备检查。对每个设备BIOS读取该设备第一个扇区传统MBR磁盘的第0扇区512字节。检查这个扇区最后两个字节是否是0x55AA启动标记是的话就跳到该扇区代码执行。这里有个关键点BIOS时代没有文件系统的概念它只是机械地把磁盘第一扇区读进内存然后把控制权交出去。第一扇区里的代码MBR中的Bootloader第一阶段需要自己知道去哪找内核所以各种引导程序都有自己的布局方式。Legacy BIOS的局限性很明显MBR分区表只能管理2TB以下的磁盘实际上2TB已经是理论极限。主分区最多4个扩展分区绕来绕去很麻烦。引导程序装在MBR里任何重装Windows或误操作都可能覆盖它。BIOS自身代码太古老对现代高速设备NVMe SSD支持不佳。2.1.2 UEFI引导现代标准UEFI统一可扩展固件接口是Intel在2000年代推动的BIOS替代方案2010年代之后逐步成为主流。它有以下几个关键特点第一个特点是支持GPT分区表。GPT用64位逻辑块地址LBA支持几乎无限的分区数量单盘容量上限达到了理论上的9.4ZB1ZB1024EB日常场景里根本不用担心上限问题。第二个特点是EFI System PartitionESP。UEFI不再从固定扇区加载引导程序而是把引导程序作为普通文件存放在一块专门的分区上。这个分区通常是FAT32格式挂载点统一约定为/boot/efi。引导程序文件如\EFI\GRUB\grubx64.efi直接放在这个分区里UEFI固件按NVRAM变量记录的顺序去加载它们。第三个特点是安全启动Secure Boot。这是防止引导链被恶意篡改的机制。UEFI只允许加载签名有效的引导程序密钥存储在主板的NVRAM里。这带来一个经典问题自己编译的内核或未签名的Bootloader比如某些Linux发行版的GRUB需要手动关闭Secure Boot或者自己导入签名。用个生活化的类比Legacy BIOS类似保姆帮你在固定抽屉里拿固定位置的钥匙UEFI更像是给你一份钥匙清单你按清单去钥匙柜里取特定编号的钥匙甚至还能通过安全启动机制验证钥匙的真伪。2.1.3 两大模式的兼容与切换现在的主板几乎都默认支持UEFI但为了照顾老系统通常会提供CSM兼容性支持模块选项开启后可以模拟Legacy BIOS引导。很多人在装Linux的时候会遇到一个尴尬场景磁盘是MBR分区但主板固件设置为UEFI Only模式结果怎么都引导不起来。或者磁盘是GPT分区但固件设置为Legacy模式同样找不到启动项。我的建议是新装系统一律用UEFI GPT组合除非你有特殊的兼容性需求。原因很简单现代操作系统Windows 10/11、主流Linux发行版对UEFI支持都非常完善而且UEFI模式下的启动项管理更清晰不容易被覆盖。2.2 Bootloader承上启下的关键枢纽2.2.1 BIOS时代的LILO与GRUB LegacyLinux早期用的引导程序叫LILOLinux Loader它把内核位置直接写死在MBR或分区引导扇区里。每次更换内核后必须重新安装LILO让改动生效。后来的GRUB LegacyGRUB 1.x是Linux世界最主流的引导程序之一支持菜单选择、启动参数传递但它的配置和现代Linux发行版默认带的GRUB 2并不一样。如果你在系统里看到/boot/grub/menu.lst那就是GRUB Legacy看到/boot/grub/grub.cfg则是新版GRUB 2。GRUB Legacy时代有个经典痛点MBR空间只有512字节GRUB第一阶段代码放不下所有功能于是它把第二阶段拆成多个片段放在MBR之后的扇区里。一旦这些扇区被其他数据覆盖引导就挂了。这也是很多人抱怨装一次Windows把Linux引导弄没了的根本原因。2.2.2 GRUB 2现代Linux的事实标准目前几乎所有主流Linux发行版Ubuntu、Debian、RHEL系、openSUSE等默认使用的都是GRUB 2。它把引导能力整体提升了一个量级支持UEFI安全启动。支持从LVM、RAID、加密磁盘启动。支持主题、字体、图形化菜单。配置由脚本生成管理起来更规范。GRUB 2的工作流程大致如下主板固件加载GRUB → GRUB读取配置文件 /boot/grub/grub.cfg → 解析菜单项内核路径、initramfs路径、启动参数 → 按用户选择加载内核和initramfs到内存 → 跳转到内核入口grub.cfg的核心是menuentry块每个menuentry对应一个可启动的内核版本或系统menuentry Ubuntu --class ubuntu { load_video set gfxpayloadkeep insmod gzio insmod part_gpt insmod ext2 set roothd0,gpt2 linux /vmlinuz-5.15.0-91-generic root/dev/sda2 ro initrd /initrd.img-5.15.0-91-generic }set root指定的是GRUB自己的分区通常就是/boot所在分区linux行指定内核文件路径和启动参数initrd行指向initramfs镜像。理解这几行你就能手动添加自定义启动项了。2.2.3 其他Bootloader一览除了GRUB还有几个Bootloader在特定场景很常见systemd-boot原名gummiboot极简风格专注UEFI环境配置是明文INI文件没有GRUB那么复杂。Arch Linux和某些极简发行版喜欢用它。rEFIndmacOS和Linux双系统场景最好用的图形化Bootloader能自动扫描分区里的内核文件还能启动EFI Shell。Windows Boot Manager微软自己的引导管理器用于Windows的启动。它不能直接引导Linux内核所以双系统场景一般是GRUB在菜单里链式加载Windows Boot Manager。U-Boot嵌入式LinuxARM开发板、路由器、IoT设备的事实标准。它运行在硬件初始化到内核加载之间支持网络引导TFTP/NFS非常适合开发调试。2.2.4 如何选择Bootloader普通Linux桌面/服务器直接用发行版默认的GRUB省心文档多反正大多数人不需要换。极简系统Arch/自建Linuxsystemd-boot够用配置简单启动速度快。双系统/macOS LinuxrEFInd的自动扫描能力最方便。嵌入式开发U-Boot是绕不开的几乎全行业都在用它。2.3 内核加载与initramfs2.3.1 内核到底做了什么Bootloader把内核镜像通常是vmlinuz-*加载进内存后CPU跳转到内核代码执行。内核的第一阶段是解压压缩过的内核自解压代码然后进入真正的初始化流程初始化CPU、内存管理、中断描述符表。检测并注册硬件驱动磁盘控制、显卡、网卡等。解析启动参数中的root指定根文件系统位置。挂载根文件系统。启动第一个用户态进程并交给它控制。这里有个不得不提的问题内核体积一直在增大驱动越来越丰富如果所有驱动都编入内核内核文件会非常臃肿加载也慢。所以Linux采用了尽可能把驱动编译成模块的策略模块存放在/lib/modules/$(uname -r)/目录中按需加载。问题来了如果根文件系统所在的磁盘驱动比如NVMe驱动、SCSI驱动是模块化的内核自身根本读不了根文件系统那还怎么加载模块2.3.2 initramfs临时根文件系统解决办法就是initramfs初始RAM文件系统。Bootloader除了加载内核之外还会加载一个initrd.img-*或initramfs-*镜像进去。这是一个小型的临时根文件系统里面预先存放了最基本的设备驱动程序和启动脚本。内核会先把initramfs挂载为根执行里面的/init脚本这个脚本会加载存储控制器驱动NVMe、SATA、SCSI等。组装磁盘设备节点。处理LVM、RAID、加密卷等复杂存储布局。重新挂载真正的根文件系统。所以如果你改了存储布局比如从普通分区换成LVM或者启用磁盘加密但忘了重新生成initramfs开机大概率会卡在Waiting for /dev/...之类的地方。这个坑我踩过不止一次后面会专门讲。用个类比initramfs就像是先锋小队带着基础装备先进入系统接管硬件把路探明白之后再把大部队真正的根系统接进来。3. 启动参数深入解析3.1 常见启动参数与作用内核启动参数是在GRUB菜单的linux行后面加上的一串键值是启动阶段唯一能注入配置的手段。常用的有参数作用root/dev/sda2指定根文件系统所在设备rootUUIDxxxx用UUID指定根文件系统更可靠ro根文件系统先以只读方式挂载通常是默认值rw根文件系统以读写方式挂载quiet减少启动日志输出splash显示开机画面splash screensingle/S进入单用户模式用于紧急修复systemd.unitrescue.target直接进入救援目标systemd系统nomodeset不加载KMS视频驱动用于显卡驱动导致黑屏时acpioff关闭ACPI用于ACPI引起的启动卡死3.2 如何传启动参数在GRUB菜单出现时选中菜单项按e键进入编辑模式找到linux那一行在行尾追加参数按CtrlX启动。这个修改只对本次启动生效不会写入配置文件。如果需要持久修改编辑/etc/default/grub中的GRUB_CMDLINE_LINUX_DEFAULT然后重新生成grub.cfg# 修改前 GRUB_CMDLINE_LINUX_DEFAULTquiet splash # 修改后 GRUB_CMDLINE_LINUX_DEFAULTquiet splash nomodeset # 更新配置 sudo update-grub不过我不想让系统自动分配设备名比如/dev/sda*在不同机器上可能变成/dev/sdb*这种情况下rootUUID...是更稳妥的。用UUID的唯一好处是稳定它不随启动顺序变化。实操经验每次修改启动参数后都要注意看启动日志journalctl -b是当前启动的日志观察新增参数是否生效、是否引入了新的报错。特别是nomodeset这种参数开了之后虽然能进桌面但分辨率可能不对要记得在确认问题后恢复。3.3 启动参数排查案例有一次我遇到一台机器开机后屏幕黑着没有任何报错风扇在转。远程SSH也连不上去因为系统还没到能建立网络服务的阶段。我在GRUB菜单里编辑加了一个参数systemd.unitemergency.target这时系统才会进入紧急模式shell允许我挂载根文件系统、分析日志。这个参数很实用建议记在脑子里。同样的systemd.unitrescue.target是进入单用户维护模式不会启动任何网络服务适合修复系统配置。再比如某个Linux发行版升级之后开机直接变黑屏我第一反应是显卡驱动问题加了nomodeset后系统能进桌面。这是很典型的排查思路先用一个保守参数让系统能起来再去深究驱动的问题。4. 实操双系统与启动项管理4.1 双系统安装的引导注意点装双系统Windows Linux时引导这一环最容易出乱子。我的建议是在装Windows之前先规划分区和引导方式统一用UEFI模式安装Windows和Linux。Windows安装时自动创建ESP分区通常是FAT32、大小100MB到500MB。Linux安装时把ESP分区选为引导分区挂载到/boot/efi不要再创建第二个ESP。如果Linux和Windows用不同磁盘确保两块硬盘都是GPT并设置了同一个ESP分区在启动项里。安装完成之后通常是GRUB接管引导菜单里会出现Windows Boot Manager选项。如果GRUB没识别到Windows可以在Linux里执行sudo os-prober sudo update-grubos-prober会扫描其他操作系统把Windows加入GRUB菜单。常见坑如果之前已经装好了Windows再装Linux时没有选中Windows的ESP分区作为引导分区Linux可能把GRUB装到了一个新创建的独立小分区上导致启动时主板找不到Linux的引导项。这时候要么进BIOS手动把含GRUB的分区设为第一启动项要么用efibootmgr -v查看当前启动项并修整最省事的做法是重新执行引导安装命令。4.2 多系统引导顺序修改GRUB的默认启动项由/etc/default/grub中的GRUB_DEFAULT控制GRUB_DEFAULT0这个数字表示grub.cfg里第一个menuentry是默认启动项。如果Windows在第三个位置改成GRUB_DEFAULT2即可。也可以指定菜单标题GRUB_DEFAULTWindows Boot Manager (on /dev/sda1)修改后记得重新update-grub。还有一个隐藏的小技巧GRUB支持saved方式让系统记住你上次选择的是哪个系统GRUB_DEFAULTsaved GRUB_SAVEDEFAULTtrue这个在双系统用户里非常实用不用每次开机都盯着一两秒的菜单抢键盘。4.3 单系统Linux的引导修复单系统Linux最怕的是误删引导文件或覆盖MBR/ESP。修复方式概括起来就两种方法一Live USB chroot修复用Live USB启动系统挂载原系统的根分区和boot分区然后chroot进去重新安装GRUB# 假设原系统根分区是/dev/sda2boot分区在ESP是/dev/sda1 sudo mount /dev/sda2 /mnt sudo mount /dev/sda1 /mnt/boot/efi # 把关键虚拟文件系统绑定过去 sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys # chroot sudo chroot /mnt /bin/bash # 重新安装GRUB grub-install /dev/sda update-grub注意ESP分区挂载要在哪里。UEFI模式下grub-install的目标是挂载点/mnt/boot/efi而不是某个设备节点这点和Legacy BIOS完全不同。方法二使用系统自带救援模式CentOS/RHEL/Fedora这类发行版安装介质里有Rescue a system选项可以自动挂载系统到/mnt/sysimage然后chroot进去执行同样的修复命令。提示无论如何修复引导都必须在chroot之后确认/etc/fstab里的挂载项没有错误否则即使引导修好了下次重启也可能因为某个挂载失败被踢进紧急模式。4.4 备份与急救技巧这里的经验我个人非常推荐备份grub.cfg修改引导配置前先复制一份已确认可以启动的版本。备份ESP分区dd或cp整个ESP里的文件到安全位置。记录当前启动项efibootmgr -v的输出保存到文件将来能知道主板固件里记录了哪些引导文件路径。准备一个Live USB发生恶性引导问题时这就是你的又一条命。5. 启动故障排查实战指南5.1 从卡住的位置判断问题源头启动故障首先看现象现象能告诉你卡在哪个阶段现象问题大概率所在开机黑屏且无任何BIOS自检信息风扇转但屏幕无显示硬件级故障参考硬件排查BIOS自检通过但屏幕停在某个Logo界面按快捷键也不进菜单ESP分区损坏/固件启动项丢失屏幕显示no bootable device系统找不到Bootloader可能引导文件丢失或启动顺序错误GRUB菜单出现但选择启动项后卡在Loading Linux等字样之后内核/initramfs加载失败启动过程提示root找不到设备根文件系统设备标识错误启动到一半进emergency mode/etc/fstab挂载项问题或某个服务挂载失败进桌面后一切正常只是偶尔卡在grub界面GRUB配置或某个启动脚本超时5.2 修复场景一GRUB菜单消失什么是GRUB菜单消失可能是开机直接进入Windows或者开机直接黑屏进入系统然后再也起不来的情况。排查步骤开机按Del/ESC/F2/F12等快捷键进BIOS设置。检查启动顺序里是否有Linux引导项如Ubuntu或grubx64.efi。如果没有或顺序不对手动调整启动顺序或添加启动项。实在找不到用Live USB修复参考4.3。需要注意很多主板的固件更新会重置NVRAM里的启动项导致Linux引导项消失。这不是系统问题放心只需要重新添加一次引导项就行。5.3 修复场景二You need to load the kernel firstGRUB菜单里显示error: you need to load the kernel first这意味着GRUB不认识vmlinuz-*文件的路径很可能的原因是/boot分区未正确挂载比如拆了哪个分区。GRUB配置文件里指定的分区不对set root和实际分区不一致。/boot/grub/grub.cfg被覆盖或损坏。进入GRUB命令行菜单界面按c键手动指认内核启动grub insmod ext2 grub set root(hd0,gpt2) grub linux /vmlinuz-5.15.0-91-generic root/dev/sda2 ro grub initrd /initrd.img-5.15.0-91-generic grub boot能启动的话再进系统修复GRUB配置。5.4 修复场景三根文件系统挂载失败错误信息常见如下ALERT! UUIDxxxx does not exist. Dropping to a shell!这一般是内核启动参数里的root指定设备不存在。常见原因数据盘没有插好物理层。存储设备驱动没加载进去参考initramfs部分。UUID写错手动编辑GRUB时容易犯。系统从SATA盘迁移到NVMe盘之后UUID变了但启动参数还指向旧设备。解法在emergency shell里blkid查看实际设备UUID对比启动参数并修正。5.5 修复场景四升级内核后无法启动系统更新后出现内核无法引导多数情况是新内核和旧硬件驱动不兼容。新内核initramfs生成不全。GRUB配置里默认启动项指向了有问题的新内核。解法重启后在GRUB菜单选择Advanced options选旧内核启动。登录后把新内核删掉或者重新生成initramfs等稳定后再做内核升级。5.6 值得收藏的排查命令Ubuntu/Debian系# 查看当前启动日志 journalctl -b -e journalctl -b -p err # 重新生成initramfs sudo update-initramfs -u -k all # 更新GRUB配置 sudo grub-mkconfig -o /boot/grub/grub.cfgRHEL/CentOS系# 重新生成initramfs sudo dracut -f # 查看启动日志 journalctl -b -e # 重新生成GRUB配置 sudo grub2-mkconfig -o /etc/grub2.cfg5.7 启动故障排查口诀我总结了一个简易排查口诀基本能覆盖90%的启动问题先看画面卡在哪一层硬件Logo → 固件界面 → GRUB菜单 → 内核日志 → 服务启动 → 登录界面。能进GRUB就手动选旧内核能进就好说进不去就Live USB。日志是救命稻草启动界面按Esc或F2可隐藏启动动画看实时日志进系统后journalctl -b告诉你哪里出错。改动前先备份改grub.cfg、改fstab备份永远不嫌多。确认存储布局变化后要重建initramfs新加了RAID、LVM、加密卷别忘记同步更新initramfs。6. 实际项目复盘一次典型的系统更新后无法启动6.1 问题描述一台在用的桌面Linux之前一直很稳定某天升级了系统版本和一批软件包包括内核。重启之后发现卡在了GRUB菜单选择之后的阶段屏幕停在黑屏只有光标在左上角闪烁没有任何日志输出。这台机器的分区情况一块SSDGPT分区表ESP分区作为EFI引导根分区是ext4。6.2 排查过程我当时判断固件阶段正常能看到GRUB菜单GRUB引导阶段异常选了启动项后卡住。可能原因有几个新内核加载时显卡驱动出问题黑屏卡死。initramfs生成有问题加载根文件系统时卡住。BIOS/固件设置被复位但GRUB菜单能看到固件应该有显示。我做的第一步是在启动时按e编辑启动项在linux行末尾加上nomodeset然后启动。结果系统直接进桌面了答案水落石出新内核装载的显卡驱动模块KMS和当前显卡硬件不兼容导致初始化画面卡死虽然屏幕黑但系统其实还在后台跑。后续做法在/etc/default/grub的GRUB_CMDLINE_LINUX_DEFAULT里加上nomodeset重新update-grub然后等待内核更新修复。同时顺手把旧内核保留不删万一新内核后续还有问题还能回退。6.3 这次排障学到的经验黑屏不一定是死机很可能是显示驱动在初始化阶段出问题系统仍然在运行。nomodeset是这类问题的通用急救参数。系统更新后要留意内核和驱动版本变化尤其是显卡、无线网卡这类硬件相关更新。想直接看更多内核启动日志可以在GRUB编辑时删掉quiet和splash参数系统会滚动显示内核日志信息密度大很多。7. 总结与实用建议7.1 我个人的实操体会做了多年Linux相关的系统维护之后我越来越觉得启动流程就像门口的第一道锁平时不起眼什么时候钥匙断了或者锁芯换了才知道它有多重要。我对Boot的最终建议就三句话新系统一律UEFIGPT省心且现代。启动参数和引导配置文件改动前必须备份并记录变更点。系统更新后不要急着删旧内核和旧initramfs多保留一个版本做回退。另外我在实践中发现很多启动不了其实不是组件损坏而是固件设置被重置或者启动顺序被改变。先检查固件里的启动项和启动顺序比你花半天在系统里修配置文件效率高得多。7.2 如果只能记住三件事启动链路固件→Bootloader→内核→init/systemd出问题先定位卡在哪个环节这就是排查思路的一半。initramfs是临时根文件系统存储布局改动后必须重新生成否则内核找不到根。GRUB菜单按e编辑启动项是非常强大的现场调试手段很多黑屏、死机问题都能靠追加一个参数来解决。如果看完这篇文章你觉得Boot不再是开机转圈那么模糊而是能按图索骥一步步排查那这篇内容就没白写。后续如果遇到具体的启动报错欢迎在评论区贴日志和分区信息我见到会尽量回。