8_系统启动深度解析:从 BIOS 到 systemd 的全过程
系统启动深度解析:从 BIOS 到 systemd 的全过程
每次按下 Linux 电脑的开机键,屏幕从黑到亮、最终出现登录界面,背后藏着一整套 “精密流程”—— 从硬件自检到服务启动,任何一个环节出问题,都可能导致 “开机黑屏”“启动项丢失”。今天这篇文章,带你逐层拆解 Linux 启动的 4 大核心环节(UEFI 引导→GRUB 配置→内核初始化→服务启动),再通过实战解决 GRUB 故障,最后玩转 systemd 单元文件,让你不仅 “会用 Linux”,更 “懂 Linux 怎么启动”。
一、先搞懂:Linux 启动的 4 步核心流程(从硬件到软件)
Linux 启动就像 “公司上班流程”:先过门禁(硬件自检),再看导航(引导程序),启动发动机(内核),最后员工到岗(服务启动)。用一张表看懂完整流程:
| 启动阶段 | 类比场景 | 核心组件 | 核心作用 |
|---|---|---|---|
| 1. UEFI/BIOS 自检 | 公司门禁安检 | UEFI/BIOS(硬件固件) | 检查 CPU、内存、硬盘等硬件是否正常,确保硬件能工作 |
| 2. GRUB 引导配置 | 导航仪选路线 | GRUB(引导程序) | 显示启动菜单(比如双系统选 Linux/Windows),加载内核文件 |
| 3. 内核初始化 | 公司发动机启动 | Linux 内核 | 初始化硬件驱动(显卡、网卡、硬盘),创建进程管理、内存管理等核心功能 |
| 4. systemd 服务启动 | 员工到岗开工 | systemd(初始化系统) | 启动 Nginx、SSH、防火墙等服务,最终加载登录界面 |
1. 第一步:UEFI/BIOS 自检 —— 硬件 “开机体检”
电脑开机后,首先由UEFI 或 BIOS(硬件自带的固件程序,存于主板芯片中)接管,相当于 “硬件自检医生”。
-
BIOS 与 UEFI 的区别:
BIOS 是传统固件(2015 年前电脑常用),仅支持 MBR 分区表,启动速度慢;UEFI 是新一代固件(现在主流),支持 GPT 分区表,启动快、支持大硬盘(>2TB),本文以 UEFI 为例讲解。
-
自检流程:
-
开机后 UEFI 自动检查 CPU、内存、硬盘、显卡是否正常(比如内存是否插紧、硬盘是否识别);
-
若硬件故障(比如硬盘没接好),会发出蜂鸣警报或在屏幕显示错误(如 “Hard Disk Not Found”);
-
自检通过后,UEFI 会查找 “启动设备”(按 BIOS 里设置的启动顺序,比如优先从硬盘启动),找到硬盘后,读取硬盘的 “ESP 分区”(EFI 系统分区,存放引导程序 GRUB)。
2. 第二步:GRUB 引导配置 ——“选路” 加载内核
UEFI 找到 ESP 分区后,会启动GRUB(Grand Unified Bootloader) ——Linux 的 “启动导航仪”,核心作用是 “让你选启动哪个系统,再加载对应内核”。
- GRUB 的核心工作:
-
显示启动菜单(比如双系统会显示 “Ubuntu 24.04”“Windows 11”“高级选项”);
-
若选择 Linux,GRUB 会从
/boot分区加载两个关键文件:
-
内核文件(如
vmlinuz-5.15.0-78-generic):Linux 内核的可执行文件; -
初始内存盘(如
initrd.img-5.15.0-78-generic):临时加载硬件驱动的镜像,帮助内核识别硬盘等设备;
- 加载完成后,GRUB 把控制权交给内核。
-
GRUB 配置文件位置:
UEFI 系统中,GRUB 的核心配置文件在
/boot/grub/grub.cfg(自动生成,不建议直接编辑),自定义启动项需改/etc/default/grub(后续实战会讲)。
3. 第三步:内核初始化 —— 启动 “系统发动机”
内核(vmlinuz文件)接管后,开始 “初始化系统核心功能”,相当于 “启动公司的发动机”。
- 内核初始化流程:
-
加载硬件驱动:通过初始内存盘(initrd)加载硬盘、网卡、显卡的驱动,让内核能识别并控制硬件;
-
创建核心进程:启动
pid=1的进程(现在是systemd,传统系统是init),这是 Linux 所有进程的 “祖进程”(后续所有进程都由它衍生); -
挂载根文件系统:内核找到
/(根分区),并挂载(相当于 “打开系统的根目录”),此时内核能访问/etc、/bin等系统目录; -
把控制权交给
systemd:内核初始化完成后,不再直接操作,而是让systemd负责后续的服务启动。
4. 第四步:systemd 服务启动 ——“员工到岗”
systemd(pid=1)接管后,开始 “启动系统服务”,相当于 “通知各部门员工到岗开工”。
- systemd 的核心工作:
-
读取服务配置:
systemd会读取/lib/systemd/system/或/etc/systemd/system/下的 “单元文件”(.service、.target 等),这些文件定义了要启动的服务(如 Nginx、SSH); -
按依赖启动服务:比如先启动 “网络服务(network.service)”,再启动 “SSH 服务(sshd.service)”,避免服务因依赖缺失启动失败;
-
加载登录界面:最后启动 “显示管理器(如 gdm.service,Ubuntu 的图形登录界面)”,或 “终端登录(getty.service)”,此时用户能输入账号密码登录系统。
-
验证 systemd 启动结果:
登录后输
ps -ef | grep init,会显示1 ? 00:00:02 systemd,说明systemd是pid=1的祖进程,启动正常。
二、实战:解决 2 个高频启动问题(GRUB 修复 + 启动项设置)
启动流程中最容易出问题的是 “GRUB 引导”—— 比如双系统丢失 Linux 启动项、GRUB 损坏导致开机黑屏,下面分步演示解决方法。
实战 1:修复 GRUB 引导故障(双系统丢失 Linux 启动项)
场景:装了 Ubuntu+Windows 双系统,某次 Windows 更新后,开机直接进 Windows,看不到 Linux 启动项(GRUB 菜单被覆盖)。
解决步骤(用 Ubuntu 安装盘修复):
-
制作 Ubuntu 启动 U 盘:
下载 Ubuntu 24.04 镜像,用 Rufus 工具制作启动 U 盘(注意选 “GPT 分区表” 和 “UEFI 启动”)。
-
从 U 盘启动电脑:
开机按快捷键(F2/F10/F12,不同主板不同,开机时屏幕会提示)进入 UEFI 启动菜单,选 “U 盘启动”,进入 Ubuntu 安装界面,选 “Try Ubuntu without installing”(不安装,进入试用模式)。
-
安装并运行 boot-repair 工具(自动修复 GRUB):
打开终端,依次输入以下命令:
\# 添加boot-repair软件源
sudo add-apt-repository ppa:yannubuntu/boot-repair
\# 更新缓存
sudo apt update
\# 安装boot-repair
sudo apt install boot-repair -y
\# 启动boot-repair
boot-repair
-
执行自动修复:
启动后,boot-repair 会提示 “Recommended repair”(推荐修复),点击后工具会自动检测硬盘分区、重建 GRUB 引导、添加 Linux 和 Windows 启动项,耐心等待修复完成(约 1-2 分钟)。
-
重启验证:
拔掉 U 盘,重启电脑,此时会显示 GRUB 菜单,能看到 “Ubuntu 24.04” 和 “Windows Boot Manager”,选 Ubuntu 即可正常启动。
实战 2:设置 GRUB 默认启动项(比如默认进 Windows)
场景:双系统中,GRUB 默认启动 Ubuntu,想改成默认启动 Windows,避免每次开机手动选。
解决步骤(编辑 GRUB 配置):
-
查看 GRUB 启动项列表:
先知道 Windows 启动项在 GRUB 中的 “序号”(GRUB 启动项从 0 开始计数),输入命令:
grep menuentry /boot/grub/grub.cfg
输出示例(不同系统可能不同):
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os \$menuentry\_id\_option 'gnulinux-simple-abc123...' { ... }
menuentry 'Advanced options for Ubuntu' { ... }
menuentry 'Windows Boot Manager (on /dev/sda1)' --class windows --class os \$menuentry\_id\_option 'osprober-efi-DEF4-1234' { ... }
这里 Windows 启动项是第 2 个(序号为 2,因为 Ubuntu 是 0,Advanced 是 1)。
-
编辑 /etc/default/grub 文件:
不要直接改
/boot/grub/grub.cfg(会被自动覆盖),改/etc/default/grub:
sudo vim /etc/default/grub
找到以下两行,修改对应值:
GRUB\_DEFAULT=2 # 改成Windows启动项的序号(这里是2)
GRUB\_TIMEOUT=5 # 启动菜单显示时间(秒),0表示不显示,建议设5秒
保存退出(vim 中按Esc,输:wq)。
-
更新 GRUB 配置:
修改
/etc/default/grub后,需执行命令让配置生效:
sudo update-grub
输出 “Generating grub configuration file ... done”,说明更新成功。
-
重启验证:
重启电脑,GRUB 菜单会默认选中 “Windows Boot Manager”,等待 5 秒后自动进 Windows(若想手动改,也能在 5 秒内选其他启动项)。
三、新特性:systemd 单元文件编写(以 Nginx 服务为例)
传统 Linux 用init脚本(/etc/init.d/下)管理服务,现在systemd用 “单元文件”(.service)替代,更简洁、功能更强。下面以 “自定义 Nginx 服务” 为例,教你编写和使用单元文件。
1. 先懂 systemd 单元文件的核心结构
一个.service单元文件分 3 个核心区块:[Unit](定义依赖和描述)、[Service](定义服务启动逻辑)、[Install](定义开机启动配置),每个区块有固定字段。
2. 实战:编写 Nginx 的 systemd 单元文件
假设我们从源码编译安装了 Nginx(路径/usr/local/nginx/),默认没有systemd单元文件,需要手动编写,让systemd能管理 Nginx(启动、停止、开机自启)。
步骤 1:创建单元文件
新建nginx.service文件,路径为/etc/systemd/system/nginx.service(用户自定义服务建议放这里,系统默认服务在/lib/systemd/system/):
sudo vim /etc/systemd/system/nginx.service
步骤 2:写入单元文件内容
粘贴以下内容,每段都有注释解释含义:
\[Unit]
\# 服务描述(执行systemctl status nginx时显示)
Description=Nginx Web Server
\# 启动依赖:网络服务启动后再启动Nginx(避免Nginx因没网启动失败)
After=network.target remote-fs.target nss-lookup.target
\[Service]
\# 服务类型:simple表示启动脚本是前台运行(Nginx默认前台启动,若用daemon off则需改)
Type=forking
\# Nginx启动命令(源码安装的启动脚本路径)
ExecStart=/usr/local/nginx/sbin/nginx
\# Nginx停止命令(发送QUIT信号,优雅停止,保存配置)
ExecStop=/usr/local/nginx/sbin/nginx -s quit
\# Nginx重启命令(先停止再启动)
ExecReload=/usr/local/nginx/sbin/nginx -s reload
\# 服务启动后,保存主进程PID到文件(方便systemd管理)
PIDFile=/usr/local/nginx/logs/nginx.pid
\# 服务停止后,是否自动重启(on-failure表示仅在失败时重启,比如崩溃时)
Restart=on-failure
\# 重启间隔(失败后10秒再重启,避免频繁重启)
RestartSec=10
\[Install]
\# 开机启动时,关联到“多用户.target”(表示系统进入多用户模式时启动Nginx)
WantedBy=multi-user.target
步骤 3:重载 systemd 配置
编写完单元文件后,systemd需要重新加载配置才能识别:
sudo systemctl daemon-reload
3. 用 systemd 管理 Nginx 服务(验证单元文件)
通过systemctl命令操作 Nginx,验证单元文件是否生效:
| 需求 | 命令 | 说明 |
|---|---|---|
| 启动 Nginx | sudo systemctl start nginx |
启动服务,无输出表示启动成功 |
| 查看 Nginx 状态 | sudo systemctl status nginx |
显示服务是否运行、PID、最近日志 |
| 停止 Nginx | sudo systemctl stop nginx |
停止服务 |
| 重启 Nginx | sudo systemctl restart nginx |
停止后重新启动,适合改配置后 |
| 重新加载 Nginx 配置 | sudo systemctl reload nginx |
不停止服务,仅加载新配置(推荐用) |
| 设置 Nginx 开机自启 | sudo systemctl enable nginx |
下次开机时自动启动 Nginx |
| 取消 Nginx 开机自启 | sudo systemctl disable nginx |
取消开机自启 |
验证开机自启:
设置开机自启后,输sudo systemctl is-enabled nginx,输出 “enabled” 表示成功;重启电脑后,输sudo systemctl status nginx,显示 “active (running)”,说明 Nginx 已自动启动。
四、新手避坑:启动流程中的 3 个常见误区
-
误区 1:直接编辑 /boot/grub/grub.cfg 改启动项
错因:
grub.cfg是update-grub命令自动生成的,直接修改会被覆盖;正确做法:改
/etc/default/grub,再执行sudo update-grub,让配置生效。 -
误区 2:systemd 单元文件放错路径,导致服务无法识别
错因:用户自定义服务放
/lib/systemd/system/(系统默认路径),会被系统更新覆盖;正确做法:自定义服务放
/etc/systemd/system/,这个路径优先级更高,且不会被系统更新修改。 -
误区 3:修复 GRUB 时,没区分 UEFI 和 BIOS 系统
错因:UEFI 系统的 GRUB 在 ESP 分区,BIOS 系统在 MBR 分区,修复工具和步骤不同;
正确做法:先判断系统类型(输
ls /sys/firmware/efi,若有该目录是 UEFI,否则是 BIOS),再选对应修复方法。
总结:Linux 启动的 “核心逻辑链”
-
硬件到软件:UEFI 自检(硬件)→GRUB 引导(过渡)→内核初始化(核心)→systemd 服务(应用);
-
故障解决:GRUB 丢失用 boot-repair 自动修复,自定义启动项改
/etc/default/grub; -
服务管理:systemd 单元文件分 [Unit]、[Service]、[Install],编写后用
systemctl管理,比传统 init 脚本更高效。
理解启动流程后,遇到 “开机黑屏”“启动项丢失”“服务启动失败” 等问题,你就能按 “从硬件到软件” 的顺序排查 —— 先看 UEFI 自检是否报错,再查 GRUB 是否正常,最后看 systemd 服务状态,逐步定位问题根源,不再盲目百度。

浙公网安备 33010602011771号