当前位置: 首页 > news >正文

嵌入式 Linux 启动流程详解 (以 ARM + U-Boot 为例)

嵌入式 Linux 启动流程详解 (以 ARM + U-Boot 为例)

对于嵌入式开发者而言,深入理解系统的启动流程至关重要。这不仅有助于进行底层驱动开发和系统移植,还能在遇到启动失败等问题时,快速定位和解决。本文将详细分解基于 ARM 架构的嵌入式 Linux 系统最常见的启动流程:BootROM -> U-Boot -> Kernel -> RootFS。过段时间仔细研究一下Uboot,看看能不能给手上这块3506移植个Uboot试试。


在这里插入图片描述

启动流程总览

嵌入式设备的启动过程是一个环环相扣的链条,前一级加载器负责初始化基础硬件,并加载下一级更复杂的程序,直到最终启动完整的 Linux 操作系统。

graph TDsubgraph SoC 内部芯片A[电源开启] --> B(BootROM);endsubgraph 引导加载程序 (Bootloader)B --> |从 Flash/SD卡 加载| C[U-Boot SPL];C --> |初始化DDR| D[U-Boot 主体];endsubgraph 内核与用户空间D --> |执行 bootcmd| E[加载 Linux 内核 (zImage)];D --> |执行 bootcmd| F[加载设备树 (DTB)];E & F --> G{启动内核};G --> H[内核初始化硬件];H --> I[挂载根文件系统 (RootFS)];I --> J[执行第一个用户进程 /sbin/init];J --> K[启动系统服务与应用];end

1. BootROM - 芯片内的第一行代码

BootROM 是整个启动链的起点。

  • 是什么:一段固化在 SoC (System on Chip) 芯片内部的只读存储器 (ROM) 中的程序。它由芯片制造商编写,用户无法修改,是上电后 CPU 执行的第一段代码
  • 核心职责
    1. 最小化硬件初始化:进行最基础的硬件设置,如配置内部时钟、初始化用于加载下一阶段代码的存储接口(如 SD 卡控制器、eMMC、SPI Flash 等)。
    2. 加载外部引导程序:根据预设的启动介质顺序(通常由一组 BOOT_MODE 引脚的电平状态决定),从外部存储设备(Flash, eMMC, SD Card)中查找并加载第二阶段的引导加载程序(通常是 U-Boot 的一个小型版本 SPL)到芯片内部的 SRAM 中。
    3. 移交控制权:加载完成后,将 CPU 的执行权限交给这段刚刚加载进来的代码。

BootROM 的工作非常单一,就是为更强大的 Bootloader 搭建一个最小化的运行环境。


2. U-Boot - 通用引导加载程序

U-Boot (Universal Boot Loader) 是嵌入式领域应用最广泛的开源引导加载程序。它功能强大,通常分两个阶段执行,以适应嵌入式系统 SRAM 较小的限制。

2.1 第一阶段: U-Boot SPL (Secondary Program Loader)

  • SPL 是什么:一个精简版的 U-Boot,主要目的是初始化 DDR 内存。由于 BootROM 加载 SPL 时使用的是芯片内部的 SRAM,而 SRAM 通常很小(几十到几百 KB),无法容纳完整的 U-Boot。
  • 核心职责
    1. 初始化 DDR 控制器:这是 SPL 最重要的任务。DDR 内存是运行 Linux 内核和应用程序所必需的大容量内存空间。
    2. 加载 U-Boot 主体:DDR 初始化完成后,SPL 会从外部存储设备中将完整的 U-Boot 镜像 (u-boot.img) 加载到 DDR 内存中。
    3. 跳转执行:将控制权移交给位于 DDR 中的 U-Boot 主体。

2.2 第二阶段: U-Boot 主体

这是我们通常所说的 U-Boot,它功能完善,为启动 Linux 内核提供了所有必要的准备。

  • 核心职责
    1. 全面的硬件初始化:初始化系统所需的各种外设,如串口(用于打印启动日志和提供命令行交互)、网络接口(用于网络启动和调试)、存储设备(eMMC, NAND)等。
    2. 设置内核启动参数 (bootargs):这是 U-Boot 的一个关键功能。它会设置一个名为 bootargs 的环境变量,然后将其传递给 Linux 内核。这个参数字符串告诉内核一些重要的初始配置,例如:
      • console=ttyS0,115200:指定内核使用哪个串口作为控制台,以及波特率。
      • root=/dev/mmcblk0p2 rootwait:指定根文件系统的位置(例如在 SD 卡的第 2 个分区),并让内核等待设备就绪。
      • rootfstype=ext4:指定根文件系统的类型。
    3. 加载内核和设备树:根据 bootcmd 环境变量中定义的命令(或手动输入),从存储介质(或通过网络 TFTP)中将 Linux 内核镜像 (zImage) 和设备树文件 (.dtb) 加载到 DDR 内存的指定地址。
    4. 启动内核:执行 bootzbootm 命令,将设备树文件的内存地址传递给内核,然后跳转到内核的入口点,正式开始 Linux 系统的启动。

3. Linux Kernel - 操作系统的核心

内核接管控制权后,标志着真正的操作系统开始运行。

  1. 内核自解压zImage 是一个压缩的镜像,所以第一步是在内存中将自己解压出来。
  2. 解析设备树 (DTB):内核会读取 U-Boot 传递过来的 DTB 文件。DTB 描述了板级的所有硬件信息,内核根据这些信息来初始化对应的驱动程序。这使得内核代码可以与硬件解耦,一份内核源码可以适配不同的开发板。
  3. 初始化硬件:内核开始全面初始化由 DTB 描述的所有硬件设备,并建立起驱动模型、内存管理、进程调度等核心子系统。
  4. 挂载根文件系统 (RootFS):内核根据 bootargs 中的 root 参数,找到并挂载根文件系统。
    • 在开发阶段,常常使用 NFS (Network File System),方便快速修改和调试。
    • 在量产产品中,根文件系统通常存放在 eMMC 或 Flash 的一个分区上,格式为 ext4, squashfs (只读压缩), ubifs (用于 NAND Flash) 等。
  5. 启动 init 进程:根文件系统被挂载后,内核会创建并运行第一个用户空间的进程 /sbin/init(其 PID 永远为 1)。内核的初始化工作到此结束,后续的用户空间初始化全权交由 init 进程处理。

4. Init 与用户空间

init 进程是所有用户空间进程的“始祖”。它的任务是根据配置文件,将系统带入一个可用的状态。

  • 常见的 init 程序:
    • BusyBox init:在资源受限的嵌入式系统中非常流行。它解析 /etc/inittab 文件,按顺序执行其中的脚本来启动系统服务。
    • SystemV init:传统的 init 系统,同样使用 /etc/inittab 和运行级别 (Runlevel) 脚本 (/etc/rc.d/)。
    • systemd:现代 Linux 发行版的主流选择,功能强大,并行启动速度快,但在嵌入式领域有时被认为过于复杂和庞大。
  • 执行流程init 进程会运行一系列启动脚本,这些脚本会:
    • 挂载其他必要的文件系统(如 /proc, /sys, /tmp)。
    • 配置网络。
    • 启动系统日志、SSH 服务等后台守护进程。
    • 最终,启动核心的应用程序

当用户的应用程序成功运行起来后,整个嵌入式 Linux 系统的启动流程便宣告完成。

http://www.dtcms.com/a/365338.html

相关文章:

  • [Ai Agent] 打造一个真正可落地的客服智能体
  • 论文理解:Reflexion: Language Agents with Verbal Reinforcement Learning
  • 封装一个redis获取并解析数据的工具类
  • 基于web的云智教育在线平台设计与实现
  • 利用 openssl api 实现 TLS 双向认证
  • Jenkins和Fastlane的原理、优缺点、用法、如何选择
  • SpringAI Alibaba Graph 流式对话
  • python sqlalchemy模型的建立
  • 嵌入式硬件学习-2
  • Algorithms library
  • Qoder如何免费续杯,立即参与实践分享,赢 1000Credits
  • 解决windows下火狐浏览器开机会同时启动两个或多个页面
  • 为何quest3设备会强制更新,如何屏蔽更新
  • GoogleNet:更深的网络与更高的效率
  • 大模型的偏见:从训练数据到推理结果,如何检测与修正?
  • Voicemod-免费即时变声器
  • 【程序人生】有梦想就能了不起,就怕你没梦想
  • Redis 集群模式与高可用机制
  • 深度学习篇---Adam优化器
  • 计算机网络模型总概述
  • python抖音弹幕获取方案
  • 考研复习-计算机网络-第二章-物理层
  • 服务器安装vnc服务端
  • 深度学习篇---InceptionNet网络结构
  • Ecovadis评估认证准备期间对于公司员工培训有没有什么技巧?
  • 对轮询的理解
  • 手持式气象观测仪在短期监测项目的作用
  • 深度学习之第六课卷积神经网络 (CNN)如何保存和使用最优模型
  • GOFLY开源客服系统-处理gin框架下的session中间件
  • 【线段树 懒删除堆】P12372 [蓝桥杯 2022 省 Python B] 最优清零方案|普及+