看得见 SPL,看不见 U-Boot:i.MX8MP 新板卡启动循环复盘的踩坑
问题描述: 在nxp的 x8mp 平台,进行新板卡的boot启动时,无法正常启动
故障日志
点击查看代码
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
Normal Boot
Trying to boot from BOOTROM
image offset 0x8000, pagesize 0x200, ivt offset 0x0
U-Boot SPL 2020.04-g61d6ac2b (Oct 19 2026 - 18:27:14 -0700)
DDRINFO: start DRAM init
DDRINFO: DRAM rate 4000MTS
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
Normal Boot
Trying to boot from BOOTROM
image offset 0x8000, pagesize 0x200, ivt offset 0x0
U-Boot SPL 2020.04-g61d6ac2b (Oct 19 2026 - 18:27:14 -0700)
DDRINFO: start DRAM init
DDRINFO: DRAM rate 4000MTS
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
Normal Boot
Trying to boot from BOOTROM
image offset 0x8000, pagesize 0x200, ivt offset 0x0
U-Boot SPL 2020.04-g61d6ac2b (Oct 19 2026 - 18:27:14 -0700)
DDRINFO: start DRAM init
DDRINFO: DRAM rate 4000MTS
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
Normal Boot
Trying to boot from BOOTROM
image offset 0x8000, pagesize 0x200, ivt offset 0x0
原理分析:
启动原理:多级接力启动,一条地址接力链:上一级把下一级搬到它"应该在"的地址,然后跳过去。
boot 结构:
flash.bin
├─ SPL image
│ ├─ IVT 32 字节,BootROM 读的第一件东西
│ ├─ Boot Data 这坨数据搬到内存哪里、多长
│ ├─ DCD(可选) DDR 初始化寄存器序列
│ ├─ u-boot-spl-ddr.bin = u-boot-spl.bin + DDR PHY 训练固件
│ └─ CSF(仅安全启动) HAB 签名与证书
└─ FIT image(u-boot.itb)
├─ IVT + CSF
├─ u-boot-nodtb.bin U-Boot 可执行体
├─ u-boot.dtb U-Boot 自己的设备树
├─ bl31.bin ATF
├─ tee.bin OP-TEE(可选)
└─ kernel + dtb 可选,Falcon 快速启动才塞
| 介质偏移(SD 卡) | 内容 |
|---|---|
| 0x0000 – 0x83FF(前 33 KiB) | 空闲,BootROM 约定不占用 |
| 0x8400(33 KiB)起不同平台此地址不一!!! | flash.bin 本体 |
| 文件内偏移 | 内容 |
|---|---|
| 0x0000 | IVT(32 字节),后填充到 0x40 |
| 0x0040 | SPL 段:DDR 固件 + u-boot-spl.bin |
| 约 0x58000 – 0x60000 | 第二级容器:IVT + CSF + u-boot.itb |
介质偏移地址,决定在制作sd启动卡或在emmc进行内存格式化时,需要将介质的分区大小及地址按照要求进行制作,否则boot会加载失败.
本例的故障原因为fdisk在制作sd启动卡时,boot分区大小不足,导致boot文件残缺;此外在内核烧录时,烧录地址指定错误,导致覆盖了前面的boot内容.
原因1:
boot 分区大小不足,导致 boot 文件残缺:fdisk 制作启动卡时,boot 分区划分容量过小:完整的 flash.bin + 内核Image + 设备树总大小通常需要 >10MB,最小不能低于1MB,若误将 boot 分区仅分了几百KB,写入文件时超出分区容量边界,flash.bin 后半段(384KB位置开始的FIT镜像段)被截断丢失前半段SPL(32KB~384KB)刚好落在分区内可以完整写入,因此SPL能正常启动,但加载第二级镜像时找不到完整FIT结构,启动失败
原因2:内核烧录地址指定错误,覆盖了boot内容,烧录内核镜像时 dd 命令的 seek 参数计算错误:内核本应写入 boot 分区内部(如 /dev/mmcblk0p1 内),但错误指定到了SD卡裸设备的绝对偏移位置写入起点落在 flash.bin 384KB~1MB区间,直接覆盖了原本存在的 FIT 镜像段,最前端32KB起始的SPL段未被覆盖,因此BootROM仍能正常加载SPL运行,但SPL读取被内核覆盖的第二级区域时校验失败,触发复位循环
在探索新的平台时,应当获取以下表格信息
| 序号 | 字节偏移起点 | 字节偏移终点 | 长度 | 属于哪个区域 | 文件系统 | 内容(具体到文件) | 谁来读取/加载 | 写入方式/命令 | 出错症状 |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0x00000 | 0x001FF | 512 B(1扇区) | 裸区(无分区) | 无 | MBR主引导记录:分区表 + boot signature 0x55AA | BootROM只读IVT,不依赖分区表;Linux内核读分区表 | fdisk/sfdisk 自动生成 | fdisk分区表损坏,Linux识别不出后续分区,但boot本身能起 |
| 1 | 0x00200 | 0x07FFF | ~31.5 KB | 裸区(无分区) | 无 | BootROM保留区:空,禁止写入任何内容 | BootROM约定此处不占 | dd 写flash.bin时跳过,不写 | 这里写入任何内容都会破坏分区表,但不影响BootROM读SPL |
| 2 | 0x08000(32 KB) | 0x5FFFF | 352 KB | 裸区(无分区) | 无 | flash.bin第一级容器:SPL段内部结构:IVT(32B) → BootData → DCD → DDR PHY训练固件 → u-boot-spl.bin | BootROM从0x8000读IVT,加载整段到OCRAM并跳转 | dd if=flash.bin of=/dev/sdX bs=1k seek=32 | SPL横幅打不出来,串口全黑 |
| 3 | 0x60000(384 KB) | ~0x128FFF | ~800 KB | 裸区(无分区) | 无 | flash.bin第二级容器:FIT段内部结构:二级IVT → ATF(bl31.bin) → U-Boot proper(u-boot-nodtb.bin) → U-Boot设备树(u-boot.dtb) → 可选OP-TEE(tee.bin) | SPL从相对flash.bin起点0x58000(即介质0x60000)读FIT,搬各组件到DDR对应地址并跳转ATF | 和第2段一起由dd if=flash.bin bs=1k seek=32整包写入 | 就是你遇到的故障:SPL横幅正常出,DDR初始化完成,之后静默复位循环,无BL31、无U-Boot proper横幅 |
| 4 | ~0x129000(≈1.2 MB) | 0x7FFFFF | ~7 MB | 裸区(无分区,对齐空隙) | 无 | 对齐填充区:空,按NXP Yocto规范留到8 MB,给bootloader扩展、签名、冗余留空间 | 无 | 不写 | 若此区域被分区覆盖,同样破坏第二级FIT,症状同3 |
| 5 | 0x800000(8 MB,扇区16384) | 视大小而定(典型136 MB,扇区278528) | 典型128 MB | 第1分区 /dev/sdX1(boot分区) | FAT32,卷标boot,活动分区标记 | 内核与设备树文件:- Image(Linux内核,约30~50 MB)- imx8mp-*.dtb(对应板卡设备树,每个几十KB)- boot.scr/extlinux.conf(U-Boot启动脚本,可选)- initramfs.cpio.gz(可选,临时根文件系统) | U-Boot proper启动后通过FAT驱动读取:fatload mmc 0:1 ${loadaddr} Image | mkfs.vfat -F32 -n boot格式化后mount,直接cp拷贝文件 | U-Boot横幅正常出,之后报错** Bad device specification mmc 0:1 或 reading Image ** Unable to read file Image |
| 6 | 紧随第1分区(典型136 MB/扇区278528) | 卡尾 | 卡剩余所有空间 | 第2分区 /dev/sdX2(rootfs分区) | ext4(推荐ext3兼容老U-Boot),卷标rootfs | 完整Linux根文件系统:/bin /sbin /etc /lib /dev /proc /sys /usr /home /root...含init进程、系统库、应用程序、配置文件 | Linux内核启动后根据bootargs里的root=/dev/mmcblk0p2 rootfstype=ext4挂载 | mkfs.ext4 -L rootfs格式化后mount,tar xf rootfs.tar.xz解压 | 内核启动到VFS: Cannot open root device报错,panic |
| (可选7) | (可选)紧随第2分区 | 卡尾 | 剩余空间 | 第3分区 /dev/sdX3(可选) | 通常ext4 | 用户数据分区/应用分区:出厂后存放用户数据、升级包、日志 | Linux内核挂载到/data或/app | 可选创建 | 不影响启动,仅影响运行期数据存储 |

浙公网安备 33010602011771号