news 2026/6/9 19:55:21

Linux 启动流程全链路解析:从上电复位到 login 提示符,这一篇就够了!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 启动流程全链路解析:从上电复位到 login 提示符,这一篇就够了!

📢 引言:按下电源键的那一刻,发生了什么?

你好,我是你们的底层技术探路者。

每天我们都在与 Linux 打交道,无论你是做嵌入式开发、服务器运维还是 Android ROM 定制。当你按下电源键,屏幕亮起,直到出现登录提示符,这短短几秒钟内,CPU 执行了数以亿计的指令。

这段旅程被称为Boot Process。它是计算机科学中最精妙的接力赛:

  1. ROM Code:点燃火炬。
  2. Bootloader:冲刺跑,初始化硬件。
  3. Kernel:接管世界,构建秩序。
  4. User Space:繁荣的文明建立。

今天,我将扒开 Linux 的外衣,深入源码(基于 ARM64 架构),带你彻底搞懂这条“全链路”。

本文硬核指数 ⭐⭐⭐⭐⭐,建议先收藏,再细品!


🏁 第一阶段:史前时代 —— 硬件上电与 ROM Code

在 Linux 内核介入之前,必须先有“立足之地”。

1.1 上电复位 (Power-on Reset)

当电压稳定后,SoC 内部的时序控制逻辑会产生复位信号。此时,CPU 的所有寄存器被重置,PC 指针 (Program Counter)指向一个固定的物理地址(通常是0xFFFF00000x00000000)。

1.2 BROM (Boot ROM)

这个地址映射的是 SoC 内部的一小块只读存储器(iROM)。这里的代码是芯片出厂时固化的,不可修改。
它的任务非常简单且关键

  1. 初始化最基本的时钟。
  2. 检测启动介质(拨码开关决定是从 SD 卡、eMMC 还是 NAND Flash 启动)。
  3. 将 Bootloader 的第一阶段代码加载到片内 SRAM 中。

为什么是 SRAM?因为此时 DDR(内存)还没初始化,根本没法用!SRAM 虽然贵且小(通常只有几十 KB),但它不需要初始化就能直接读写。


🏃 第二阶段:短跑运动员 —— Bootloader (U-Boot)

Bootloader 的王者无疑是U-Boot。由于 BROM 只能加载很小的代码,U-Boot 通常设计为两级架构:SPL + U-Boot Proper

2.1 SPL (Secondary Program Loader)

SPL 是 U-Boot 的“先遣队”,体积极小,运行在 SRAM 中。
核心任务

  • 初始化 DDR 控制器:这是最重要的一步,让巨大的外部内存可用。
  • 将完整的 U-Boot (u-boot.bin) 搬运到 DDR 中。
  • 跳转到 DDR 执行。

2.2 U-Boot Proper (完全体)

此时我们已经运行在宽敞的 DDR 里了。U-Boot 开始大展拳脚:

  1. board_init_f(Frontend):初始化串口(为了打印 Log)、定时器、分配堆栈。
  2. board_init_r(Rear):初始化网卡、Flash、USB 等外设。
  3. 加载内核:读取uImageImage到内存。
  4. 加载设备树 (DTB):读取.dtb文件到内存。

2.3 关键时刻:移交控制权

在 U-Boot 的最后,会执行bootm命令。它做了一件极具仪式感的事情——设置寄存器,然后通过汇编指令跳转。

对于 ARM64:

  • x0寄存器:存放设备树(DTB)在内存中的物理地址。
  • x1,x2,x3:通常保留为 0。
  • Jump:直接跳转到内核的入口地址。

Load SPL to SRAM

Init DDR & Load U-Boot

Load Kernel & DTB

Power On

BROM / ROM Code

U-Boot SPL

U-Boot Proper in RAM

Kernel Entry


🧠 第三阶段:内核觉醒 —— 汇编入口 (head.S)

从这里开始,我们进入 Linux Kernel 的源码世界。
入口文件通常位于arch/arm64/kernel/head.S。此时,MMU(内存管理单元)是关闭的,CPU 看到的还是物理地址。

3.1 核心动作

  1. 关闭中断:在世界秩序建立之前,不接受任何干扰。
  2. 校验 CPU ID:确认当前运行在哪个核上(Boot CPU 还是 Secondary CPU)。
  3. 校验 DTB:确认 U-Boot 传来的设备树地址是合法的。
  4. 创建临时页表:这是为了开启 MMU 做准备。Linux 内核使用的是虚拟地址(如0xffff...),必须建立物理地址到虚拟地址的映射。
  5. 开启 MMUsctlr_el1寄存器写入,开启分页机制。
  • 瞬间变化:这一行汇编执行前,PC 指针是0x40080000(物理);执行后,PC 变成了0xffff8000...(虚拟)。

3.2 跳转到 C 语言

汇编的使命结束,代码跳转到start_kernel()


🏗️ 第四阶段:大构建师 —— start_kernel()

这是 Linux 内核中最大的函数,位于init/main.c。它是整个操作系统的“构造函数”。

由于内容太多,我将其整理为一张 Mermaid 时序图:

rest_initsched_initmm_initsetup_archstart_kernelhead.Srest_initsched_initmm_initsetup_archstart_kernelhead.S0号进程 (Swapper) 诞生创建 1号进程 (Init) 和 2号进程 (Kthreadd)Jump to C code1. 解析 DTB, 确定内存布局return2. trap_init (初始化异常向量表)3. 内存管理初始化 (伙伴系统/Slub)return4. 调度器初始化 (CFS)return5. time_init (初始化系统时钟)6. 剩下的初始化

4.1 关键初始化详解

  1. setup_arch():解析设备树,确定有多少内存,保留内存(Reserved Memory)在哪里。
  2. mm_init():初始化内存分配器。从此以后,kmalloc可以工作了。
  3. sched_init():初始化进程调度器。从此以后,多任务成为可能。
  4. rest_init():这是start_kernel的最后一步。它不会返回,而是创建了两个祖先进程:
  • PID 1 (init):所有用户进程的祖先。
  • PID 2 (kthreadd):所有内核线程的祖先。
  • PID 0 (idle):自己退化为 idle 进程,没事做的时候就跑它(省电)。

🌍 第五阶段:文明建立 —— 用户空间 (User Space)

此时,内核已经就绪,但系统还是个“空壳”,因为没有用户程序。
PID 1 进程(通常是/sbin/init)开始执行。

5.1 挂载根文件系统 (Rootfs)

内核通过解析 cmdline 中的root=/dev/mmcblk0p2参数,找到根文件系统所在的存储分区,并将其挂载到 VFS 的根目录/
如果这一步失败,你就会看到著名的Kernel panic - not syncing: VFS: Unable to mount root fs

5.2 Init 系统的分歧

根据 Linux 发行版的不同,Init 程序分为三类:

  1. SysVinit(老派):读取/etc/inittab,依序执行脚本。简单但慢。
  2. Systemd(现代):并行启动服务,通过 Socket 激活。复杂但快。
  3. BusyBox Init(嵌入式):轻量级,读取/etc/init.d/rcS

5.3 最终的 Shell

Init 进程会根据配置,启动getty进程监听串口或终端。
当你输入用户名密码验证通过后,gettyexec启动一个shell(如 bash 或 sh)。

屏幕上跳出:
Welcome to Linux 6.x
Login: _

恭喜你,系统启动完成!


❓ 常见启动故障排查 (Troubleshooting)

讲了这么多原理,最后送大家几个实战锦囊。

Q1: 卡在 “Starting kernel …” 不动了?

  • 原因:通常是 U-Boot 传给内核的 DTB 地址不对,或者内核崩溃在了串口驱动初始化之前(早期的汇编阶段)。
  • 解法:开启earlycon(早期控制台),在 bootargs 中加入earlycon=uart8250,mmio32,0x...,让内核在汇编阶段就能打印 Log。

Q2: 提示 “No init found”?

  • 原因:Rootfs 挂载成功了,但是找不到/sbin/init,或者该文件没有执行权限,或者架构不对(在 ARM 上跑了 x86 的程序)。
  • 解法:检查 Rootfs 制作过程,检查动态库依赖。

Q3: 内存识别不全(比如 4G 只有 2G)?

  • 原因:U-Boot 传递的内存参数不对,或者设备树里memory节点配置错误。

🎯 总结

Linux 的启动流程,是一场宏大的接力赛。

  • 硬件负责提供跑道。
  • Bootloader是第一棒,负责热身和起跑。
  • Kernel是第二棒,负责制定规则和构建环境。
  • Init是最后一棒,将应用生态带给用户。

理解了这个流程,你就不再是一个只会写代码的 Coder,而是一个拥有上帝视角的系统工程师。

🚀 下一步行动

你在调试 Linux 启动时遇到过最崩溃的问题是什么?

  • A. 卡在 U-Boot 进不去内核。
  • B. Rootfs 挂载失败,Panic。
  • C. 驱动加载时死机。

👉 欢迎在评论区留言交流!如果你想看如何手写一个简单的 Bootloader,请点赞告诉我,下期安排!


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 14:43:08

机器人租售动作齐?专人控全场

在商用机器人服务现场,任务的呈现始终源于事前约定与人力执行的结合。无论是节日庆典中的多轮登场,还是教育场馆内的一次性演示,机器人的每一次启动、每一段动作,均由服务商人员按计划触发,其行为边界严格限定于客户活…

作者头像 李华
网站建设 2026/6/5 15:39:52

HUAWEI AGC平台,使能HarmonyOS应用开发提质增效

HUAWEI AppGallery Connect (简称AGC)平台,可为HarmonyOS应用开发者提供开发、测试、运营、分析全链路服务,使能开发者高效开发,为应用质量护航并推动运营增长,实现商业成功。 围绕开发者在应用开发各阶段…

作者头像 李华
网站建设 2026/6/6 16:14:46

低值易耗品管理信息系统的设计与实现(11835)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告)远程调试控屏包运行 三、技术介绍 Java…

作者头像 李华
网站建设 2026/6/8 16:25:21

企微自动化控制台:跨语言调用与多进程管理的技术架构

QiWe开放平台 个人名片 API驱动企微自动化,让开发更高效 核心能力:为开发者提供标准化接口、快速集成工具,助力产品高效拓展功能场景 官方站点:https://www.qiweapi.com 团队定位:专注企微API生态的技术服务团队 对接…

作者头像 李华
网站建设 2026/6/8 3:00:48

RK3566 上运行 YOLOv8 Detection:INT8 性能、精度与可行性判断

为什么YOLOv8不能直接在RK3566跑起来?RK3566 与 YOLOv8 放在一起时,真正的问题是什么在很多边缘 AI 项目中,RK3566 经常被当作一颗“性价比不错、顺带能跑点 AI”的平台来使用。它的定位并不激进:功耗可控、外设齐全、算力有限但不…

作者头像 李华