4. 开发环境搭建与工具链

Marvell OCTEON/CN9xxx 系列 DPU 的软件开发与通用 x86 主机开发有本质区别:代码在 x86 主机上编写和编译,但最终运行在 ARM64 架构的 DPU 上,且 DPU 通常以 PCIe 加速卡或独立 SoC 板卡形态存在,需要专门的连接、加载和调试通道。本节的目标是搭建一条从主机到目标板的完整工具链,并让第一个可运行环境(基础镜像 + 最小固件)真正跑起来。

一、SDK 获取与目录结构认知

Marvell 的 DPU SDK 通常通过官方支持渠道(Marvell Extranet / Customer Portal)以压缩包或 Git 仓库形式发布,常见命名如 octeon-sdk-*.tar.gz、cnxk-sdk-*.tar.gz(CN10K 系列)。获取前需要确认三件事:目标芯片型号(如 CN9130、CN9670、CN106xx)、SDK 版本与芯片的匹配关系、以及主机侧依赖(Ubuntu 20.04/22.04 是较稳妥的选择)。

解压后典型目录结构如下,理解它比记住命令更重要:

sdk/
├── build/            # 构建脚本与顶层 Makefile
├── components/       # U-Boot、Linux kernel、ATF、EDK2 等源码
├── tools/            # 交叉编译工具链、烧录工具、镜像打包脚本
├── target/           # 目标板配置(board config、设备树)
├── rootfs/           # 基础根文件系统(busybox / buildroot 产物)
└── docs/             # 芯片手册、板级说明、Release Notes

其中 target/ 下的板级配置决定了后续编译产物是否与你的硬件匹配,务必先核对板卡型号与配置文件名一致。

二、交叉编译工具链

DPU 上的 Linux 用户态程序是 AArch64 架构,主机是 x86_64,因此必须使用交叉编译器。SDK 一般自带工具链,位于 tools/toolchain/,常见前缀为 aarch64-marvell-linux-gnu-。将其加入 PATH:

export CROSS_COMPILE=aarch64-marvell-linux-gnu-
export PATH=$PWD/tools/toolchain/bin:$PATH
aarch64-marvell-linux-gnu-gcc --version

验证工具链可用后,编译一个最小程序确认架构正确:

echo 'int main(){return 0;}' > t.c
$CROSS_COMPILE"gcc" t.c -o t
file t
# 期望输出:ELF 64-bit LSB executable, ARM aarch64

如果 file 显示 x86-64,说明 PATH 未生效或误用了主机 gcc。这一步是后续所有编译工作的前提,不要跳过。

三、目标板连接与调试接口

DPU 开发板通常提供三类物理接口,用途不同,不能混用:

  • 串口(UART):最基础的调试通道,用于查看 U-Boot 启动日志、进入 U-Boot 命令行、观察内核启动。参数一般为 115200 8N1,通过 USB 转串口连接,主机侧设备名如 /dev/ttyUSB0。
  • JTAG:用于芯片级调试,可在 U-Boot 尚未运行时加载初始化代码、单步调试、读取寄存器。需要 Marvell 提供的 JTAG 调试器与配套脚本。
  • 以太网 / PCIe:用于运行阶段的网络通信或主机侧 PCIe 枚举,属于系统跑起来之后的通道,不能替代串口做早期调试。

连接串口后,用 minicom 或 picocom 打开:

picocom -b 115200 /dev/ttyUSB0

上电后应能看到 U-Boot 打印的芯片型号、DDR 容量、启动介质等信息。如果串口无输出,优先检查波特率、TX/RX 是否接反、板卡是否真正上电,而不是怀疑固件。

四、固件加载与基础镜像烧录

DPU 的启动链通常为:BootROM → ATF(ARM Trusted Firmware)→ U-Boot → Linux Kernel → RootFS。烧录方式取决于启动介质,常见有 eMMC、SPI NOR、SD 卡三种。以 SD 卡为例,SDK 一般提供打包脚本,将各阶段镜像按偏移写入:

# 示例:将镜像写入 SD 卡(/dev/sdX 为卡设备,务必确认)
sudo dd if=atf.bin    of=/dev/sdX bs=512 seek=0    conv=fsync
sudo dd if=uboot.bin  of=/dev/sdX bs=512 seek=2048 conv=fsync
sudo dd if=kernel.itb of=/dev/sdX bs=512 seek=8192 conv=fsync

具体偏移量必须查阅 SDK 的板级文档,不同芯片和启动介质偏移不同,写错会导致 BootROM 找不到镜像。烧录完成后插入板卡上电,串口应依次出现 ATF、U-Boot、Kernel 的启动日志,最终进入登录提示符。

首次烧录建议先用 SD 卡验证,确认启动链正常后再烧写到 eMMC,避免因偏移错误反复擦写板载存储。

五、第一个可运行环境的验证

系统启动到 shell 后,按以下顺序确认环境真正可用:

  1. uname -m 应输出 aarch64,确认运行在目标架构上。
  2. cat /proc/cpuinfo 查看 CPU 核数与型号,与板卡规格对照。
  3. ip link 确认网络接口存在,配置 IP 后 ping 主机,验证网络通道。
  4. 将第二节编译的 t 程序拷贝到板卡执行,确认交叉编译产物可运行。

以上四步全部通过,说明“主机编译 → 镜像烧录 → 目标板运行”的闭环已经打通,后续的驱动开发、卸载功能调试才有可靠基础。

DPU 开发环境搭建:主机 → 目标板完整链路 x86_64 开发主机 SDK 解压:components / tools / target 交叉工具链 aarch64-marvell-linux-gnu- 编译产物:ATF / U-Boot / Kernel / RootFS 镜像烧录 dd 按偏移写入 SD / eMMC SPI NOR DPU 目标板 (AArch64) BootROM → ATF → U-Boot Linux Kernel 启动 RootFS → 登录 Shell 调试与连接接口 UART 串口 115200 8N1 /dev/ttyUSB0 JTAG 芯片级调试 寄存器 / 单步 以太网 / PCIe 运行阶段通信 主机侧枚举 验证

六、常见问题与判断依据

环境搭建阶段最容易卡住的不是命令本身,而是现象与原因的对应关系。串口无输出,先确认供电与波特率;U-Boot 能启动但 Kernel 卡住,多半是设备树或镜像偏移问题;系统启动后 uname -m 不是 aarch64,说明烧录的镜像架构错误。把“现象 → 检查点 → 判断依据”对应清楚,比反复重烧更高效。

烧录前务必用 lsblk 确认目标设备名,dd 写错设备会直接破坏主机磁盘数据,且不可恢复。

完成本节后,你应当拥有一个能稳定启动、能通过串口交互、能运行交叉编译程序的基础环境。这是后续所有 DPU 卸载功能开发、调试与性能验证的起点。