一、为什么要理解启动流程
嵌入式 Linux 出问题时,经常不是应用代码的问题,而是系统还没正常启动。比如串口没有输出、内核卡住、根文件系统挂载失败、应用没有自启动。
理解启动流程可以帮助你定位问题发生在哪一层:
1 | BootROM -> SPL -> U-Boot -> Kernel -> RootFS -> Init -> App |
不同芯片细节不同,但大方向类似。
二、BootROM
BootROM 是芯片内部固化代码,上电后最先执行。
它通常负责:
- 初始化最小硬件。
- 判断启动介质。
- 从 Flash、SD、eMMC、USB 等位置加载下一阶段。
BootROM 通常不可修改。开发者能配置的是启动脚、烧录方式和启动介质布局。
三、SPL
SPL 是 Secondary Program Loader,常用于资源受限的早期启动阶段。
它通常负责:
- 初始化 DDR。
- 初始化时钟。
- 加载完整 U-Boot。
为什么需要 SPL?
因为完整 U-Boot 较大,BootROM 可能无法直接加载或运行,需要先用小程序完成内存初始化。
四、U-Boot
U-Boot 是常见嵌入式 bootloader。
它负责:
- 初始化板级硬件。
- 加载 Linux Kernel。
- 加载 dtb。
- 设置启动参数。
- 从存储或网络启动。
常见命令:
1 | printenv |
常见启动参数:
1 | console=ttyS0,115200 |
五、Kernel
Linux Kernel 启动后会:
- 解压内核。
- 初始化内存管理。
- 初始化调度器。
- 解析设备树。
- 初始化驱动。
- 挂载根文件系统。
- 启动第一个用户态进程。
内核日志非常关键:
1 | dmesg |
如果系统没进用户态,串口启动日志是最重要的线索。
六、RootFS
RootFS 是根文件系统,包含:
1 | /bin |
如果根文件系统挂载失败,常见报错:
1 | Kernel panic - not syncing: VFS: Unable to mount root fs |
排查方向:
root=参数是否正确。- 存储分区是否存在。
- 文件系统格式是否支持。
- 内核是否启用了对应驱动。
- rootfs 是否完整。
七、init
内核启动的第一个用户态进程通常是:
1 | /sbin/init |
也可能是:
1 | /init |
常见 init 系统:
- BusyBox init。
- systemd。
- SysV init。
应用自启动通常在这一层配置。
八、应用启动
应用可以通过不同方式启动:
- init 脚本。
- systemd service。
- rc.local。
- 自定义启动脚本。
嵌入式设备里,应用启动失败要检查:
- 可执行文件是否存在。
- 动态库是否存在。
- 配置路径是否正确。
- 权限是否正确。
- 环境变量是否正确。
- 依赖设备节点是否已经创建。
九、常见启动问题
9.1 串口无输出
检查:
- 串口线是否接对。
- 波特率是否正确。
- TX/RX 是否接反。
- GND 是否共地。
- U-Boot 是否启用 console。
9.2 U-Boot 能进,内核不启动
检查:
- kernel 镜像地址。
- dtb 地址。
- bootm/booti 命令是否正确。
- 内核格式是否正确。
9.3 内核启动,rootfs 挂载失败
检查:
- bootargs。
- 分区。
- 文件系统驱动。
- rootfs 内容。
9.4 系统起来了,应用没启动
检查:
- init 配置。
- systemd service。
- 应用路径。
- 日志。
- 动态库。
十、总结
嵌入式 Linux 启动问题要分层排查。不要看到系统没起来就直接怀疑内核。
推荐顺序:
1 | 串口输出 -> U-Boot 环境变量 -> kernel 日志 -> rootfs 挂载 -> init -> app 日志 |
把启动链路拆清楚,很多问题会变得非常具体。
- 本文链接: https://blog.hansong.icu/2026/06/21/Embedded_Linux_Boot_Process/
- 版权声明: 本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。