2、R-Car启动流程与Bootloader:启动模式、IPL/SPL、ATF、U-Boot移植与配置
做嵌入式开发,尤其是车规级SoC,第一关就是搞懂芯片怎么「醒过来」的。R-Car的启动流程,说实话,比普通MCU复杂不少。它不是一个简单的Bootloader,而是一套多级引导链。我刚开始接触R-Car时,也被这堆缩写搞得头大——IPL、SPL、ATF、U-Boot……今天咱们就把这条链子从头捋一遍。
2.1 启动模式与硬件决定
R-Car上电后,首先看的是硬件管脚电平。这些管脚组合决定了芯片从哪儿加载第一段代码。
| 启动模式 | 典型场景 | 我碰到的坑 |
|---|---|---|
| HyperFlash / QSPI | 量产板,稳定可靠 | 曾经把QSPI时钟配快了,死活起不来 |
| eMMC / SD卡 | 开发调试阶段 | 分区表写错,IPL找不到SPL |
| 串行Flash (RPC) | 低成本方案 | 引脚复用冲突,RPC没初始化成功 |
| USB / 以太网 | 工厂烧录或紧急恢复 | 很少用,但关键时刻能救命 |
2.2 多级引导链:从IPL到U-Boot
R-Car的引导链,说白了就是「小马拉大车」。芯片内部SRAM很小,装不下完整的Bootloader,所以必须分阶段加载。
- IPL (Initial Program Loader) —— 芯片固化的ROM代码,只做一件事:从启动介质里把SPL读到内部SRAM。
- SPL (Secondary Program Loader) —— 初始化DDR、时钟、电源管理芯片(PMIC),然后把ATF和U-Boot加载到DDR里。
- ATF (ARM Trusted Firmware) —— 负责安全启动、PSCI(电源管理)、异常等级切换。跑在EL3。
- U-Boot —— 真正的Bootloader,加载内核、设备树、ramdisk。跑在EL2。
你想想看,这个流程就像接力赛。每一棒只干自己该干的事,干完就交棒。
2.3 IPL与SPL:第一口饭怎么吃
IPL是芯片出厂固化的,你改不了。但它会检查启动介质头部是否有合法的「启动描述符」。这个描述符里包含了SPL的加载地址、大小、校验和。
SPL的代码量一般控制在几十KB以内。为什么?因为内部SRAM通常只有128KB~256KB,你还要留一部分给ATF的BL2。我个人习惯,SPL里只做三件事:
- 初始化DDR控制器(PFC、DDR PHY调校)
- 初始化时钟(PLL、CPG)
- 初始化PMIC(I2C通信,设置核心电压)
嗯,这里要注意。DDR初始化是SPL里最容易出问题的地方。我曾经在一块新板子上,DDR时序参数没配好,SPL加载ATF时直接卡死。后来用示波器量DQS信号才发现,走线等长没做好。
2.4 ATF:安全启动与异常等级
ATF是ARM生态里的标准组件。R-Car用的是Trusted Firmware-A。它负责把系统从EL3(安全监控模式)切换到EL2(虚拟机监控模式),最后交给U-Boot。
ATF在R-Car上主要干这几件事:
- BL2 —— 验证U-Boot的签名(如果使能了安全启动)。
- BL31 —— 提供PSCI接口,用于CPU开关、系统挂起/恢复。
- BL32 —— 可选,跑一个安全OS(如OP-TEE)。
2.5 U-Boot移植与配置
U-Boot是大家最熟悉的部分。但R-Car的U-Boot移植,有几个特殊之处。
2.5.1 设备树配置
R-Car的U-Boot使用设备树(DTB)来描述硬件。你需要确保以下节点配置正确:
- CPG —— 时钟生成器,必须匹配板级晶振频率。
- PFC —— 引脚功能控制器,复用关系不能错。
- MMC/SD —— eMMC和SD卡控制器,时钟和电压要配好。
- SCIF —— 串口,调试输出全靠它。
2.5.2 关键配置项
在U-Boot的defconfig里,有几个选项是必选的:
CONFIG_TARGET_RCAR_GEN3=y # 或GEN4,取决于芯片
CONFIG_RCAR_IPMMU=y # IOMMU,不配可能DMA异常
CONFIG_RCAR_DMA=y # DMA控制器
CONFIG_RPC_HYPERFLASH=y # 如果使用HyperFlash
CONFIG_MMC_SDHI=y # eMMC/SD卡驱动
CONFIG_SCIF_CONSOLE=y # 串口控制台
2.5.3 编译与烧录
编译命令大致如下:
# 编译ATF
make -C trusted-firmware-a PLAT=rcar_gen3 bl2 bl31
# 编译U-Boot
make rcar_gen3_defconfig
make
# 生成启动镜像
tools/mkimage -T rcar_image -a 0x0 -e 0x0 -d u-boot.bin u-boot-rcar.img
烧录时,注意启动介质的偏移地址。QSPI Flash一般从0x0开始放SPL,0x1C000放ATF,0x20000放U-Boot。具体偏移看芯片手册。
2.6 避坑指南
最后,分享几个我实际项目中遇到的坑:
- PMIC初始化顺序 —— 必须先给核心供电,再给DDR供电。顺序反了,DDR初始化必失败。
- 时钟树配置 —— R-Car的PLL关系复杂。我曾经把CSI2(摄像头)的时钟配错了,导致整个系统时钟域混乱,U-Boot里网络都跑不起来。
- 启动介质选择 —— 如果同时接了QSPI和eMMC,IPL会按优先级尝试。调试时建议只留一个介质,避免干扰。
- 串口电平 —— R-Car的调试串口是1.8V电平,直接连USB转串口(3.3V)可能烧坏管脚。加个电平转换吧。
总结一下:R-Car的启动流程,核心就是「IPL→SPL→ATF→U-Boot」这条链。每一级都有明确的职责和约束。移植时,先从SPL和DDR初始化入手,再逐步加上ATF和U-Boot。别想着一步到位,分段验证最稳妥。