T527 主线系统启动过程
完成硬件连接、开发环境和参考镜像检查后,先了解板卡上电时各组件的运行顺序。这样看到串口日志停在某一行时,才能判断应该检查 TF-A、U-Boot、Linux 还是根文件系统。
六个启动阶段的职责
| 阶段 | 主要工作 | 第一处可见标志 | 停止后先检查 |
|---|---|---|---|
| BootROM | 从启动介质读取 SPL | 通常没有串口输出 | 启动头、写入偏移、FEL 状态 |
| SPL | 初始化时钟和 DRAM,读取后续镜像 | U-Boot SPL ... | DRAM、eMMC 控制器、FIT 镜像 |
| TF-A BL31 | 提供 EL3 运行时服务,进入非安全世界 | NOTICE: BL31... | BL31 平台代码、入口地址 |
| U-Boot proper | 初始化外设,加载 Linux 文件 | U-Boot ... | 设备树、存储、extlinux.conf |
| Linux | 初始化内核驱动并挂载根文件系统 | Starting kernel ... | DTB、命令行、MMC、根分区 |
| 用户空间 | 执行 init,启动登录与服务 | 登录提示符或服务日志 | rootfs、/sbin/init、启动脚本 |
Buildroot 不在板卡的运行时启动链中
Buildroot 运行在开发主机上,用来生成 Linux 内核、设备树、根文件系统和镜像。板卡上真正运行的是这些生成结果,而不是 Buildroot 本身。
BootROM 把 SPL 送入片内 SRAM
T527 上电后最先执行芯片内部固化的 BootROM。此时 DRAM 还不能使用,因此 BootROM 只能从约定的启动介质位置找到带有全志启动头的 SPL,并把它装入片内 SRAM。
eMMC 的约定位置
└── eGON 启动头
└── SPL → 片内 SRAM
这一阶段没有可修改的源码。如果连 U-Boot SPL 字样都看不到,应优先确认镜像写入位置、启动头和芯片是否进入 FEL,而不是先修改 Linux。
SPL 准备 DRAM 并读取 FIT
SPL 属于 U-Boot,但职责与完整的 U-Boot 不同。它必须足够小,才能在片内 SRAM 中运行;它先让 DRAM 可用,再从 eMMC 读取包含 BL31、U-Boot proper 和设备树的 FIT 镜像。
课程工程中的这些配置直接影响这一阶段:
CONFIG_SPL=y
CONFIG_MACH_SUN55I_A523=y
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_SUPPORT_EMMC_BOOT=y
SPL 依次完成四件事:
- 初始化基础时钟和引脚;
- 按板卡参数训练并启用 DRAM;
- 初始化 eMMC 控制器;
- 从 FIT 中解析并装载下一阶段。
| FIT 中的对象 | 运行角色 | 由谁生成 |
|---|---|---|
bl31.bin | TF-A BL31 | TF-A |
u-boot-nodtb.bin | U-Boot proper | U-Boot |
| U-Boot DTB | U-Boot 自己使用的硬件描述 | U-Boot |
构建完成后可用下面的命令确认 FIT 内确实包含这些对象:
dumpimage -l u-boot.itb
TF-A 把控制权交给 U-Boot
BL31 运行在 EL3,负责安全监控和 PSCI 等底层服务。它不是另一个操作系统,也不负责读取 Linux 文件;完成平台初始化后,它按照 FIT 提供的入口地址启动 BL33,也就是 U-Boot proper。
SPL 读取 FIT
├── BL31 → EL3 / PSCI
└── U-Boot proper → BL33 / 非安全世界
因此,串口已经出现 BL31 日志却没有进入 U-Boot 时,应检查 BL31 的平台适配、BL33 入口地址和 FIT 描述。
U-Boot 读取 Linux 启动文件
U-Boot proper 运行后,DRAM 和基础存储已经可用。课程采用 extlinux 启动方式,让启动文件的名称和参数留在 FAT 分区中,减少把板卡信息硬编码进 U-Boot 环境的情况。
boot.vfat
├── Image
├── sun55i-t527-avaota-a1.dtb
└── extlinux/
└── extlinux.conf
extlinux.conf 告诉 U-Boot 从哪里读取内核和设备树,并通过 append 把串口、根分区等参数传给 Linux。此处任何一个路径或文件名不一致,都会停在 U-Boot 阶段。
Linux 挂载根文件系统
Linux 接管 CPU 后,会同时使用设备树和启动参数。设备树描述“板上有什么硬件”,启动参数说明“这一次怎样启动”。
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
例如 stdout-path 决定早期控制台对应的串口,root=LABEL=rootfs 让内核按 ext4 卷标定位根文件系统。该卷标由 Buildroot 生成 rootfs 时写入;两处名称必须一致。内核成功挂载根分区后执行 /sbin/init,随后才会看到登录提示符。
看到登录界面只能说明整条链路已经走通;网口、USB、显示等外设是否可用,还要在后面的系统验收中逐项确认。
根据最后一条日志定位启动阶段
完全没有 SPL 日志
└── 启动头 / 写入偏移 / FEL
有 SPL,没有 BL31
└── DRAM / eMMC / FIT
有 BL31,没有 U-Boot
└── TF-A 平台代码 / BL33 地址
进入 U-Boot,没有 Starting kernel
└── FAT 分区 / extlinux / Image / DTB / 加载地址
出现 Starting kernel,没有登录提示
└── Linux 驱动 / root 参数 / ext4 / init
后续每完成一个组件,都应保留串口日志。日志的价值不只是证明“启动成功”,更重要的是确定控制权最后到达了哪一阶段。
下一节:主线系统构建关系