1. Bootloader 概述
Bootloader 是芯片上电后执行的第一段代码,负责完成以下核心任务:
- CPU 寄存器初始化:设置 PSR、TBR、WIM、堆栈指针
- Cache 使能:开启指令和数据 Cache
- 固件加载:从 SPI Flash 或 eMMC Boot 分区加载 Firmware
- 安全验证:Parity Check 和 Checksum 校验
- 跳转执行:跳转到 RAM 中的 Firmware 入口
1.1 启动模式
BayBridge 支持多种启动模式:
| 模式 | Bootloader 位置 | Firmware 位置 | 典型场景 |
|---|---|---|---|
| ROM + SPI Flash | 芯片 ROM 固化 | SPI Flash | 省成本方案 |
| SPI Flash Only | SPI Flash Base | SPI Flash Middle | 外挂 Flash |
| eMMC Boot | ROM 或 SPI | eMMC Boot Partition | 无外挂 Flash |
| FW Download | ROM 或 SPI | 主机下载 | 工厂烧录/救砖 |
2. 汇编启动代码分析
2.1 boot.S 入口代码
1 | /* boot.S - SPARC LEON2 启动汇编 */ |
2.2 关键寄存器说明
| 寄存器 | 作用 | 初始值 |
|---|---|---|
| PSR | 处理器状态 | 0xFA0 (S=1, ET=1, PIL=15) |
| TBR | Trap 基地址 | 0x40000000 |
| WIM | 窗口无效掩码 | 0x02 |
| %fp | Frame Pointer | RAM_TOP - 1KB - 128 |
| %sp | Stack Pointer | %fp - 96 |
2.3 堆栈布局
1 | 0x40028000 (160KB RAM Top) |
3. 启动路由逻辑 (boot_route.c)
3.1 启动流程状态机
1 | void boot_route() |
3.2 固件有效性校验
采用奇偶校验 (Parity Check) 验证固件 Header:
1 | int parity_check(int parity_mode, u32 dword_addr) |
3.3 Firmware Header 结构
1 | /* |
4. 固件拷贝流程
4.1 firmware_copy 实现
1 | static void firmware_copy(u32 base, fw_sect_p fw_sect, spi_cfg_p spi_cfg) |
4.2 Fastboot 机制
Fastboot 是一种快速启动优化:
- 触发条件:热复位(非断电重启)且 Fastboot 标志有效
- 优化效果:跳过 .text 段拷贝,直接复用 RAM 中的代码
- 限制:RAM 内容必须保持不变
1 | static u32 is_reset_fastboot() |
5. 跳转到 Firmware
5.1 boot_exit 实现
1 | void boot_exit() |
5.2 Trap Table 结构
SPARC 架构的 Trap(相当于 ARM/MIPS 的异常)机制是整个系统中断和异常处理的核心。当硬件发生中断、异常或执行特定指令时,CPU 会自动跳转到 Trap Table 中对应的处理函数。
5.2.1 SPARC Trap 机制概述
SPARC V8 架构的 Trap 处理流程如下:
1 | ┌─────────────────────────────────────────────────────────────────┐ |
5.2.2 Trap Table 详细内容
Trap Table 位于 baybridge/src/system/trap/trap_table.S,定义了 256 个 Trap 向量(Trap 0x00 - 0xFF):
1 | /* trap_table.S - SPARC LEON2 Trap 表定义 */ |
5.2.3 宏定义说明
Trap Table 使用两个核心宏:
1 | /* TRAP 宏 - 用于普通 Trap 入口 */ |
两者的区别:
TRAP用于普通中断/异常处理,保存当前 PSRRTRAP用于 Reset 入口,此时 PSR 还未初始化(设为0)
5.2.4 Trap 向量分类
| Trap 编号 | 类型 | 说明 |
|---|---|---|
| 0x00 | Reset | 系统复位,跳转到 InitSystem |
| 0x01-0x0A | 异常 | 指令异常、非法指令、特权指令等 |
| 0x11-0x1F | 中断 | 外部硬件中断 IRQ1-IRQ15 |
| 0x20-0x3F | 错误 | 硬件错误、MMU 未命中、除零等 |
| 0x80-0xFF | 软件 | 软件 TRAP 指令触发 |
5.3 外部中断处理流程 (IRQ Trap)
当外部外设(如 Timer、UART、eMMC、NVMe)产生中断时,CPU 通过 Trap 0x11-0x1F 进入 IRQTrap 处理函数。
5.3.1 IRQTrap 处理流程
1 | /* trap_isr.S - IRQ 中断处理入口 */ |
5.3.2 中断分发函数 CPUDispatchIRQ
trap_isr.S 调用 C 函数的 CPUDispatchIRQ 进行中断分发:
1 | /* irq_handler.c - 中断向量表和分发 */ |
5.3.3 典型外设中断注册示例
1 | /* 定时器中断注册示例 */ |
5.4 异常处理流程
对于非中断类的异常(如非法指令、内存访问错误、除零等),Trap Table 跳转到对应的异常处理函数。这些处理函数最终都调用 unified_exception_manager 进行统一处理。
5.4.1 异常处理通用流程
1 | /* exception.S - 通用异常处理示例 */ |
5.4.2 寄存器窗口溢出/下溢处理
SPARC 的寄存器窗口机制是其特色,但也引入了窗口溢出/下溢异常:
1 | /* 窗口溢出处理 - Trap 5 */ |
5.5 TBR (Trap Base Register) 设置
Trap Table 的基地址通过 TBR 寄存器设置。在系统初始化时,固件将 TBR 设置为 RAM 起始地址:
1 | /* cpu.h - TBR 设置宏 */ |
固件在 InitSystem() 初始化阶段设置 TBR:
1 | void InitSystem(void) |
Trap 跳转地址计算:
1 | 跳转地址 = TBR[31:8] | (trap_type << 4) |
5.6 链接脚本中的 Trap Table 位置
链接脚本确保 Trap Table 位于固件的最前面(0x40000000):
1 | /* fw_sys.lds */ |
这样确保无论固件加载到 RAM 的任何位置,Trap Table 始终在 TBR 指向的基地址处。
5.7 完整中断处理流程图
1 | ┌─────────────────────────────────────────────────────────────────────┐ |
5.3 InitSystem 入口
1 | // init_sys.c |
6. 固件构建工具
6.1 bin_attach 工具
bin_attach 是一个多功能二进制处理工具,支持三种模式:
1 | /* |
6.2 fw_checksum 工具
计算 Firmware 的 XOR Checksum:
1 | // fw_checksum.c |
7. 启动时序分析
7.1 典型启动时序
1 | +-------+------------------+------------------+------------------+ |
7.2 启动时间优化技术
- Fastboot:热复位跳过 .text 拷贝
- SPI 频率优化:动态调整 SPI 时钟分频
- 并行初始化:减少串行依赖
8. 总结
BayBridge Bootloader 的设计体现了嵌入式系统启动代码的典型特征:
- 精简高效:汇编代码控制在 100 行以内
- 多路启动:支持 ROM/SPI/eMMC 多种启动介质
- 安全校验:Parity + Checksum 双重保护
- 容错机制:启动失败自动切换到 FW Download 模式
- 快速启动:Fastboot 减少热复位时间
下一篇文章将详细介绍 Firmware 主流程和 NVMe 协议栈的实现。
附录:关键宏定义
1 | // config.h |