一、启动流程总览
嵌入式Linux开机是一环扣一环的,前一个程序负责简单初始化硬件、加载下一个更复杂的程序,一步步把完整系统跑起来,核心流程一句话概括:
开机上电 → 芯片内置BootROM → U-Boot精简版SPL → 完整U-Boot → 加载内核+设备树 → 内核启动 → 挂载根文件系统 → 跑init进程 → 启动系统服务和业务程序 |
二、通俗版分阶段拆解
1. BootROM:芯片自带的“开机引导员”
BootROM是芯片出厂时就固化在内部的代码,删改不了,是设备上电后CPU最先运行的代码,相当于系统开机的“第一棒”。
主要做这3件事
•极简硬件初始化:只调基础时钟、初始化存储接口(SD卡、Flash、eMMC这些),够加载下一个程序就行,不做多余操作。
•加载U-Boot精简版:根据芯片启动引脚设置,从存储设备里找到U-Boot的精简版SPL,放到芯片内部小内存SRAM里(SRAM容量太小,装不下完整U-Boot)。
•交权给SPL:SPL加载完,就把控制权交出去,BootROM的任务就结束了。
2. U-Boot:系统启动的“总指挥”
U-Boot是嵌入式Linux最常用的引导程序,因为内存限制分两步跑,先靠SPL开大容量内存,再跑完整U-Boot,专门负责把内核“叫醒”。
2.1 第一步:U-Boot SPL(精简版)
SPL就是个“内存开荒者”,功能很单一,就干两件关键事:
•初始化DDR内存:这是核心任务,把设备的大容量运行内存打开,给后续内核和程序腾空间。
•加载完整U-Boot:DDR内存准备好,就把完整U-Boot放到DDR里,再把控制权交给完整U-Boot。
2.2 第二步:完整U-Boot
这才是真正的启动“总指挥”,负责给内核铺路,做好所有启动准备:
•初始化外设:把串口、网口、存储设备这些常用硬件调好,方便调试和加载文件。
•设内核启动参数:告诉内核控制台用哪个串口、根文件系统在哪、文件格式是什么,让内核能顺利运行。
•加载内核和设备树:从存储或网络,把Linux内核镜像和设备树文件读到内存里(设备树就是硬件“说明书”,内核靠它识别硬件)。
•启动内核:执行启动命令,把控制权交给Linux内核,正式开启内核运行。
3. Linux内核:系统的“核心大脑”
内核接手后,真正的Linux系统开始运转,主要完成底层初始化,为上层应用打基础:
•内核自解压:内核镜像一般是压缩的,先在内存里解压开。
•识别硬件:读设备树这份“硬件说明书”,初始化所有硬件驱动。
•挂载根文件系统:找到存放系统文件、应用的根分区,把它挂载好(开发时常用网络文件系统,方便调试;量产就存到Flash/eMMC里)。
•启动init进程:创建第一个用户进程PID=1的init程序,内核的初始化工作到此结束,后续交给用户空间管理。
4. Init进程与用户空间:系统“上岗”收尾
init是所有用户程序的“父进程”,负责把系统调到可用状态,启动各类服务和业务程序。
常用init类型
•BusyBox init:嵌入式设备最常用,体积小、占资源少,适配小容量设备。
•SystemV init:传统老款init,兼容性好,配置简单。
•systemd:现代Linux常用,启动快、功能全,但体积大,一般用在高端嵌入式设备。
核心收尾工作
•挂载系统必需的虚拟文件,保障系统正常运行;
•配置网络、时区等基础参数,做好系统基础设置;
•启动日志、远程连接等后台服务,方便运维调试;
•运行产品专属业务程序,整套嵌入式Linux系统就完全启动了。
三、速记口诀
上电开机 → 芯片BootROM → U-Boot精简版 → 完整U-Boot → 内核+设备树 → 挂载根文件 → init进程 → 业务程序运行