4. Kria 启动流程与镜像构建

Kria 的启动不是“上电即进 Linux”,而是一条由多级固件逐段接力的链。理解这条链,才能明白为什么镜像里既有 boot.bin,又有 image.ub,还有 rootfs,以及为什么改错一个环节会导致板子“卡在串口无输出”或“停在 U-Boot 提示符”。本节按启动顺序拆解每一级固件的职责、生成方式和打包位置,并给出可直接参考的构建命令与验证判据。

一、启动链的六个阶段

Kria K26 的启动顺序固定为:BootROM → PMU 固件 → CSU/PL 配置(可选)→ FSBL → U-Boot → Linux 内核与根文件系统。上电后,片内 BootROM 首先运行,它只认几种启动介质(QSPI、SD、eMMC、USB),并按顺序扫描。BootROM 从介质中读取一个头部,找到 PMU 固件和 FSBL,把它们分别加载到 PMU RAM 和 OCM。PMU 固件负责电源、复位和时钟管理,是后续所有阶段的“电源管家”;FSBL 则完成 DDR 初始化、时钟树配置,并把 U-Boot 从介质搬到 DDR 中执行。U-Boot 接管后,加载内核与设备树,最后挂载根文件系统,启动用户空间。

Kria K26 启动链与镜像组成 BootROM 片内固化 PMU 固件 电源/复位/时钟 FSBL DDR/时钟初始化 U-Boot 加载内核/设备树 Linux 内核 image.ub 根文件系统 rootfs 启动介质(QSPI / SD / eMMC) boot.bin(BOOT.BIN) image.ub(内核+DTB) rootfs.ext4 / .tar.gz boot.scr / uEnv.txt(可选) 关键约束 • BootROM 只认固定头部格式,PMU 固件与 FSBL 必须按顺序放入 boot.bin • FSBL 负责 DDR 初始化,DDR 参数错误会导致 U-Boot 无法搬移 • image.ub 是 FIT 格式,内含内核、DTB 与可选 initramfs • 根文件系统可独立分区,也可打包进 FIT 作为 initramfs

二、boot.bin 的生成:PMU 固件与 FSBL 的打包

在 PetaLinux 工程中,boot.bin 由 bootgen 工具根据 BIF 文件生成。BIF 文件描述了每个分区的内容、目标处理器和加载地址。一个典型的 Kria BIF 如下:

the_ROM_image:
{
  [pmufw_image] pmufw.elf
  [destination_device = pl] system.bit
  [bootloader, destination_cpu = a53-0] fsbl.elf
  [destination_cpu = a53-0, exception_level = el-2] u-boot.elf
}

其中 pmufw.elf 由 PMU 固件源码编译得到,通常不需要修改;fsbl.elf 由 FSBL 源码编译,若使用自定义 DDR 配置,需要替换其中的 psu_init.c;u-boot.elf 是 U-Boot 的 ELF 版本,由 U-Boot 编译产物提供。执行 bootgen -image boot.bif -arch zynqmp -o boot.bin 即可生成最终镜像。生成后可用 bootgen -image boot.bif -arch zynqmp -o boot.bin -w on 覆盖已有文件,并用 bootgen -image boot.bif -arch zynqmp -o boot.bin -read 回读校验分区顺序。

三、U-Boot 与内核的衔接

U-Boot 启动后,会读取环境变量 bootcmd,通常执行 fatload 或 ext4load 把 image.ub 加载到 DDR,然后 bootm 启动。Kria 的 image.ub 是 FIT(Flattened Image Tree)格式,由 mkimage 根据 ITS 文件生成。ITS 中描述了内核、设备树和可选的 ramdisk 节点。一个简化的 ITS 片段如下:

/ {
  description = "Kria K26 Linux";
  images {
    kernel-1 { data = /incbin/("Image"); type = "kernel"; arch = "arm64"; os = "linux"; compression = "none"; load = <0x00200000>; entry = <0x00200000>; };
    fdt-kria { data = /incbin/("system.dtb"); type = "flat_dt"; arch = "arm64"; compression = "none"; };
  };
  configurations { default = "conf-1"; conf-1 { kernel = "kernel-1"; fdt = "fdt-kria"; }; };
};

执行 mkimage -f image.its image.ub 即可生成 FIT 镜像。若根文件系统采用 initramfs 方式,可在 ITS 中增加 ramdisk 节点,并在 conf-1 中引用,这样内核启动后直接解压到内存根文件系统,适合无存储或快速启动场景。

四、根文件系统的生成与打包

根文件系统通常由 Yocto 或 PetaLinux 生成,产物可能是 rootfs.tar.gz、rootfs.ext4 或 rootfs.cpio.gz。若使用 SD 卡启动,一般把 rootfs.ext4 写入第二个分区,U-Boot 通过 root=/dev/mmcblk0p2 挂载;若使用 QSPI + eMMC,则把根文件系统写入 eMMC 的对应分区。打包时需注意分区表与文件系统类型匹配:FAT32 分区放 boot.bin 和 image.ub,ext4 分区放根文件系统。一个典型的 SD 卡分区布局如下:

分区大小文件系统内容
p1512 MBFAT32boot.bin、image.ub、boot.scr
p2剩余空间ext4rootfs.ext4 解压后的根文件系统

五、构建与验证的实操闭环

在 PetaLinux 工程中,完整构建命令为 petalinux-build,打包启动镜像为 petalinux-package --boot --fsbl --fpga --u-boot --force。构建完成后,产物位于 images/linux/ 目录下,包括 boot.bin、image.ub、rootfs.ext4。验证时,先把 SD 卡分区并格式化,再依次写入:

sudo dd if=images/linux/boot.bin of=/dev/sdX1 bs=1M
sudo dd if=images/linux/image.ub of=/dev/sdX1 bs=1M
sudo dd if=images/linux/rootfs.ext4 of=/dev/sdX2 bs=1M

上电后通过串口观察启动日志。若看到 PMU Firmware 版本号、FSBL 的 DDR 初始化信息、U-Boot 的 Hit any key to stop autoboot,说明前三级正常;若内核打印 Uncompressing Linux... 并最终出现 login:,说明整条链贯通。若卡在 BootROM 无输出,优先检查启动模式拨码和 boot.bin 头部;若卡在 FSBL,检查 DDR 配置和电源时序;若卡在 U-Boot,检查 image.ub 是否可读、bootcmd 是否正确;若内核 panic 找不到根文件系统,检查分区号和 root= 参数。

构建时建议保留 images/linux/ 下的 boot.bif、image.its 和 rootfs 清单,便于后续增量修改时快速定位是 PMU、FSBL、U-Boot 还是内核层的问题。
不要直接把 u-boot.elf 当作 boot.bin 写入启动介质;boot.bin 必须由 bootgen 按 BIF 顺序打包,否则 BootROM 无法识别分区头。