3. Layerscape启动流程与U-Boot移植

Layerscape系列处理器的启动过程与常见的ARM SoC有相似之处,也有其独特的多级镜像结构。理解从芯片上电到U-Boot命令行出现的完整链路,是进行U-Boot移植、RCW定制和镜像烧录的前提。本节以LS1046A为例,梳理BootROM、RCW、PBL、U-Boot各阶段的分工与衔接关系,并给出移植与烧录的关键操作。

一、启动链路总览

Layerscape上电后,首先运行固化在芯片内部的BootROM。BootROM会按照复位配置字(RCW)中定义的启动介质顺序,从NOR、NAND、SD/eMMC、QSPI或串口等接口读取PBL(Pre-Boot Loader)镜像。PBL是RCW与U-Boot之间的桥梁,它负责初始化DDR控制器、SerDes、时钟等关键硬件,然后把完整的U-Boot镜像搬运到DDR中执行。整个链路可以概括为:BootROM → RCW → PBL → U-Boot SPL/Proper → 操作系统。

Layerscape LS1046A 启动链路 BootROM 芯片内部固化 RCW 复位配置字 PBL 预引导加载器 U-Boot Proper / SPL 启动介质选择(由RCW的BOOT_LOCATION字段决定) NOR Flash | NAND | SD/eMMC | QSPI | 串口下载 PBL 内部执行序列 1. 时钟初始化 PLL / 系统时钟 2. DDR初始化 DDR控制器 + PHY 3. SerDes配置 Lane / 协议选择 4. 加载U-Boot 搬运至DDR执行 异常路径:DDR训练失败 → 串口输出错误码 → 回退至备用启动介质(若RCW使能) 常见错误:DDR4时序不匹配、SerDes参考时钟缺失、RCW字段与硬件不符

二、RCW与PBL的关系

RCW是一段128字节的二进制配置数据,通常以.rcw文件形式存在,编译后嵌入PBL镜像头部。它定义了DDR时钟频率、SerDes协议、启动介质顺序、引脚复用等关键参数。RCW不是可执行代码,而是BootROM和PBL读取的“硬件配置表”。如果RCW中的DDR参数与实际板卡的内存颗粒不匹配,PBL在DDR初始化阶段就会失败,表现为串口无输出或输出乱码。

PBL镜像通常由NXP提供的rcw工具和byte_swap工具生成,最终得到一个.bin文件。以LS1046ARDB为例,其PBL镜像名为rcw_1600_qspiboot.bin,其中1600表示DDR频率为1600MT/s,qspiboot表示从QSPI启动。这个命名规则本身就是一份有用的信息:频率、启动介质、SerDes配置都体现在文件名中。

三、U-Boot启动阶段

Layerscape的U-Boot分为两个阶段:SPL(Secondary Program Loader)和Proper(完整U-Boot)。SPL体积小,负责在DDR尚未完全可用时完成最基础的初始化,然后把Proper搬运到DDR。Proper阶段则完成外设驱动加载、环境变量读取、启动脚本执行,最终引导内核。

在Layerscape平台上,SPL和Proper的边界与PBL有重叠。实际上,PBL已经完成了DDR初始化,因此U-Boot SPL在Layerscape上通常只做少量补充初始化,甚至可以直接跳过SPL,由PBL直接加载Proper。这取决于具体的启动配置和U-Boot版本。对于LS1046A,常见的做法是PBL直接加载u-boot.bin(Proper),SPL仅用于特殊场景。

四、DDR初始化与SerDes配置

DDR初始化是启动过程中最关键的环节。PBL中的DDR驱动会执行以下步骤:配置DDR控制器寄存器、设置时序参数(tRCD、tRP、tRAS、CL等)、执行写电平训练和读门训练、校准DQS与DQ的相位关系。这些参数来自RCW和PBL内部的DDR配置文件。如果训练失败,PBL会通过串口输出错误码,常见的如0x1表示DDR控制器初始化失败,0x2表示写电平训练失败。

SerDes配置决定了高速接口(PCIe、SATA、SGMII、XFI等)的Lane分配和协议选择。LS1046A有4个SerDes模块,每个模块包含4个Lane。RCW中的SRDS_PRTCL字段定义了每个Lane的协议。例如,SRDS_PRTCL=0x1133表示SerDes1的Lane0-1为PCIe,Lane2-3为SGMII。如果SerDes参考时钟缺失或协议配置错误,对应的接口将无法识别设备。

五、U-Boot移植要点

U-Boot移植的核心工作是适配板级硬件。对于Layerscape,主要修改以下文件:

  • board/freescale/ls1046ardb/:板级初始化代码,包括DDR、SerDes、引脚复用。
  • include/configs/ls1046ardb.h:板级配置头文件,定义环境变量、启动命令、外设使能。
  • arch/arm/dts/fsl-ls1046a-rdb.dts:设备树,描述硬件资源。
  • configs/ls1046ardb_qspi_defconfig:默认配置,选择启动介质和驱动。

移植时,首先确认DDR参数与板卡一致。如果使用自定义板卡,需要根据内存颗粒手册修改board/freescale/ls1046ardb/ddr.c中的时序参数。其次,检查SerDes配置是否与原理图匹配。最后,配置环境变量中的bootcmd和bootargs,确保内核和根文件系统能正确加载。

六、烧录与验证

烧录通常通过CodeWarrior的Flash编程器或U-Boot的sf命令完成。以QSPI启动为例,烧录步骤如下:

# 在U-Boot命令行中擦除QSPI
sf probe 0:0
sf erase 0x0 0x100000

# 通过TFTP加载PBL和U-Boot镜像
tftp 0x82000000 rcw_1600_qspiboot.bin
tftp 0x83000000 u-boot.bin

# 烧录PBL到QSPI偏移0x0
sf write 0x82000000 0x0 0x10000

# 烧录U-Boot到QSPI偏移0x100000
sf write 0x83000000 0x100000 0x100000

# 复位验证
reset

复位后,串口应输出BootROM版本、RCW信息、DDR训练结果,最终进入U-Boot命令行。如果卡在DDR训练阶段,需要检查RCW中的DDR频率和时序参数;如果U-Boot无法启动,检查PBL和U-Boot的烧录偏移是否正确。LS1046A的QSPI启动偏移通常为:PBL在0x0,U-Boot在0x100000,环境变量在0x300000。这些偏移由RCW中的BOOT_LOCATION和PBL头部定义,不能随意更改。

调试建议:在PBL阶段打开串口调试输出,可以观察到DDR训练的具体步骤和错误码。如果串口无任何输出,优先检查RCW的启动介质字段和时钟配置,而不是怀疑U-Boot代码。

完成烧录后,建议先验证DDR容量和SerDes链路状态。在U-Boot命令行执行bdinfo查看内存信息,执行pci enum或mdio list检查PCIe和网络接口是否正常识别。这些检查能快速定位是DDR问题还是SerDes问题,避免在后续内核启动阶段反复排查。