UBOOT学习笔记(二):SoC启动BootROM阶段

BootROM(引导只读存储器)是SoC芯片启动时最先执行的固化代码,由芯片厂商预先烧录,不可修改。它的核心任务是完成最基础的硬件初始化,并加载下一阶段引导程序(如SPL/U-Boot)。以下是其工作流程:

上电复位
  │
  ├─ 锁存Boot Mode引脚
  │
  ├─ 初始化时钟/PLL
  │
  ├─ 初始化SRAM/内存控制器
  │
  ├─ 检测启动设备(SD/eMMC/NAND)
  │
  ├─ 加载SPL/U-Boot到SRAM或DDR
  │
  └─ 跳转到SPL/U-Boot

1、 SoC上电复位(Power-On Reset, POR)

  • 触发条件:芯片通电或复位信号(Reset Pin)触发。
  • 硬件行为
    • CPU从固定地址(如ARMv7的0x00000000)取第一条指令,执行BootROM代码。
    • 所有寄存器和内存被重置为默认状态。
  • 关键任务
    • 锁存Boot Mode引脚(决定从哪种存储设备启动,如SD卡、eMMC、NOR Flash等)。

2、 BootROM执行阶段

(1)最小硬件初始化
  • 时钟初始化
    • 配置PLL(锁相环),生成CPU、总线和外设的时钟信号。
    • 例如,i.MX6ULL的BootROM会初始化ARM内核时钟至396MHz。
  • 内存控制器初始化
    • 初始化片内SRAM(如OCRAM),作为临时运行空间。
    • 若支持XIP(Execute In Place),则映射NOR Flash到内存地址空间。
  • 基础外设使能
    • 初始化调试串口(UART),用于输出启动日志(可选)。
    • 关闭MMU和Cache,确保直接访问物理内存。
为什么需要执行最小硬件初始化?

(1)SoC上电时硬件处于未知状态:

CPU、外设、存储控制器等硬件模块的寄存器值不确定,必须初始化后才能使用。例如,CPU需要正确的时钟信号才能运行,内存控制器(如DDR)必须配置时序参数才能访问RAM。

(2)依赖严格的初始化顺序:

某些硬件模块必须按特定顺序初始化,例如:

  • 先配置PLL(锁相环),生成稳定的CPU和总线时钟。
  • 再初始化内存控制器,否则CPU无法访问RAM。
  • 最后使能Cache和MMU,提高执行效率。

如果没有这一步:CPU可能运行在错误的时钟频率,内存无法访问,导致死机或无法加载后续代码。


(2)检测启动设备
  • 读取Boot Mode引脚
    • 根据硬件引脚电平(如BOOT_CFG[1:0])确定启动介质(SD卡、eMMC、NAND Flash等)。
  • 初始化存储控制器
    • 例如,从SD卡启动时,需初始化MMC控制器;从SPI Flash启动时,需配置SPI接口。
为什么需要检测启动设备

(1)BootROM代码存储在芯片内部ROM,后续程序(如U-Boot)通常存放在外部存储

  • 片上ROM空间有限,无法存放完整的Bootloader(如U-Boot可能几百KB)。
  • SoC通常支持多种启动方式(如SD卡、eMMC、NAND Flash),具体由硬件引脚(Boot Mode)决定。
  • BootROM需要检测这些引脚,并初始化对应的存储控制器(如MMC/SD控制器、SPI控制器)。

(3)加载下一阶段代码(SPL/U-Boot)
  • 从存储设备读取数据
    • 从SD卡、eMMC等设备的固定偏移量(如SD卡的第1个扇区)读取SPL或U-Boot镜像。
  • 校验完整性(可选)
    • 若启用安全启动(Secure Boot),校验镜像的数字签名。
  • 加载到运行地址
    • SPL通常被加载到片内SRAM(如i.MX6ULL的0x00900000)。
    • U-Boot主阶段需加载到DDR(如0x87800000),但需先初始化DDR。
为什么需要加载下一阶段代码(SPL/U-Boot)

BootROM通常只做最基本的硬件初始化,而完整的Bootloader(如U-Boot)需要:

  • 初始化更多外设(网卡、USB、显示等)。
  • 加载操作系统内核(如Linux)。
  • 提供交互式命令行(如U-Boot的bootcmd

IMX6ULL的BOOTROM程序会根据解析出来的链接起始地址在一开始就把整个Uboot源码读取到DDR中去,也就是说Uboot的第一行代码就运行在DDR中,这是不同于三星的传统Uboot的,传统Uboot的第一句代码是运行在片内SRAM上的。

引用:imx6ull uboot启动流程 - 流水灯 - 博客园

(4)跳转到下一阶段
  • 通过汇编指令直接跳转到SPL/U-Boot的入口地址
### MT8678 SOC启动流程 MT8678 是一款由 MediaTek 开发的系统级芯片(SoC),广泛应用于嵌入式设备和物联网领域。其启动流程通常遵循一个标准化的引导加载程序(Bootloader)结构,具体包括以下几个关键阶段[^1]: #### 1. 第一阶段:ROM Boot 在芯片上电后,内置的 ROM 代码会首先执行。这一阶段的主要任务是初始化硬件环境,例如时钟、电源管理模块(PMIC)、存储控制器等。此外,ROM 阶段还会验证外部存储器中的第阶段引导程序(通常是 BootROM 或 Preloader)。此验证过程可能涉及加密算法以确保固件的安全性[^2]。 #### 2. 第阶段:Preloader Preloader 是从外部存储器(如 eMMC 或 SPI Flash)加载的第一段可执行代码。它的主要功能包括: - 初始化 DDR 内存控制器。 - 设置基本外设(如 UART、SPI、I2C 等)。 - 加载主 Bootloader(如 U-Boot 或 Android 的 Fastboot)到 DDR 中并跳转执行[^3]。 ```c // 示例代码:Preloader初始化DDR内存控制器 void init_ddr_controller() { // 配置DDR控制器寄存器 write_register(DDR_CTRL_BASE, DDR_INIT_SEQ); wait_for_completion(); } ``` #### 3. 第三阶段:Main Bootloader 主 Bootloader 通常是一个更复杂的软件组件,负责加载操作系统内核。对于基于 Linux 的系统,U-Boot 是一个常见的选择。在此阶段,以下任务会被执行: - 初始化剩余的硬件资源。 - 解析设备树(Device Tree)以描述硬件配置。 - 加载内核镜像和根文件系统到内存中。 - 将控制权传递给操作系统内核[^4]。 ```bash # 示例命令:U-Boot加载Linux内核 => fatload mmc 0:1 $kernel_addr_r zImage => bootz $kernel_addr_r - $fdt_addr_r ``` #### 4. 第四阶段:Kernel Initialization 一旦 Bootloader 完成任务,Linux 内核将接管系统控制。内核初始化阶段包括: - 设置中断向量表。 - 检测和初始化所有硬件设备。 - 启动用户空间初始化进程(如 systemd 或 init)[^5]。 --- ### 注意事项 - 启动过程中可能需要特定的加密密钥来验证固件完整性,确保系统安全性。 - 不同的应用场景可能导致某些阶段被省略或替换,例如在调试模式下可以直接从 JTAG 接口加载代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值