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

Marvell 芯片平台的 Bring-up 工作,第一步不是写代码,而是把“能编译、能下载、能看日志、能单步”这四件事打通。本节围绕交叉编译工具链、SDK 获取与目录结构、串口/JTAG 调试器连接、主机环境配置与版本管理四条主线展开,目标是搭建一套可复现、可回滚、可多人共享的宿主机开发环境。

一、交叉编译工具链:为什么不能直接用 gcc

Marvell 的 ARM64 SoC(如 OCTEON、ARMADA 系列)运行的是 AArch64 Linux,而开发主机通常是 x86_64。宿主机上的 gcc 生成的是 x86_64 指令,无法在目标板上执行。因此必须使用交叉编译工具链:在 x86_64 主机上运行,但生成 AArch64 目标代码。

工具链的核心组件包括:aarch64-linux-gnu-gcc(编译器)、aarch64-linux-gnu-ld(链接器)、aarch64-linux-gnu-objcopy(格式转换)、aarch64-linux-gnu-gdb(调试器),以及配套的 sysroot(目标根文件系统头文件与库)。Marvell SDK 通常自带预编译工具链,位于 tools/toolchain/ 下,命名类似 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu。建议优先使用 SDK 自带版本,避免与内核、U-Boot 的 ABI 不匹配。

验证工具链是否可用,执行:

export PATH=$SDK/tools/toolchain/bin:$PATH
aarch64-none-linux-gnu-gcc -v
aarch64-none-linux-gnu-gcc -dumpmachine
# 期望输出:aarch64-none-linux-gnu

若 -dumpmachine 返回 aarch64-none-linux-gnu,说明工具链前缀正确。编译一个最小测试程序并检查 ELF 架构:

echo 'int main(){return 0;}' > t.c
aarch64-none-linux-gnu-gcc t.c -o t
file t
# 期望:ELF 64-bit LSB executable, ARM aarch64

如果 file 显示 x86-64,说明 PATH 中混入了宿主机 gcc,需检查环境变量顺序。

二、SDK 获取与目录结构

Marvell SDK 一般通过官方支持渠道或合作伙伴获取,常见形式为 .tar.gz 或 .bin 自解压包。解压后典型目录结构如下:

目录内容
tools/toolchain/交叉编译工具链
u-boot/Bootloader 源码与配置
linux/内核源码、设备树、defconfig
build/构建脚本、环境初始化脚本
rootfs/根文件系统、busybox、库
docs/芯片手册、板级说明、Release Notes

进入 SDK 根目录后,通常需要先执行环境初始化脚本,例如 source build/envsetup.sh 或 source setup.sh,它会自动设置 CROSS_COMPILE、ARCH、PATH 等变量。执行后可用 echo $CROSS_COMPILE 确认前缀,用 echo $ARCH 确认是否为 arm64。

三、串口与 JTAG 调试器连接

串口是 Bring-up 阶段最可靠的观察通道。Marvell 开发板通常提供 UART 接口,参数为 115200 8N1,无流控。连接方式:USB 转 TTL 模块的 TX 接板端 RX,RX 接板端 TX,GND 共地。在 Linux 主机上设备节点一般为 /dev/ttyUSB0。

sudo minicom -D /dev/ttyUSB0 -b 115200
# 或使用 picocom
sudo picocom -b 115200 /dev/ttyUSB0

上电后应能看到 U-Boot 启动日志。若乱码,检查波特率与地线;若无输出,检查 TX/RX 是否交叉、板端是否已上电。

JTAG 用于在 Bootloader 尚未跑起来时进行硬件级调试。Marvell 平台常用 Lauterbach TRACE32 或 OpenOCD + FTDI 方案。连接时需确认 JTAG 链上的 TAP 顺序、IR/DR 长度,以及目标电压(通常 1.8V 或 3.3V)。OpenOCD 配置示例:

openocd -f interface/ftdi/ftdi.cfg \
        -f target/marvell_octeon.cfg

连接成功后,可用 scan_chain 查看 TAP 列表,用 halt 暂停 CPU,用 reg pc 读取程序计数器。若 scan_chain 返回全 0 或全 1,通常是 TCK/TMS 接反或目标未供电。

四、主机环境配置与版本管理

推荐使用 Ubuntu 20.04/22.04 LTS,安装必要依赖:

sudo apt install build-essential git bc bison flex \
  libssl-dev libncurses-dev device-tree-compiler \
  python3 python3-pip minicom picocom openocd

版本管理是多人协作的关键。建议将 SDK 纳入 Git 管理,但工具链和大型二进制可放入 .gitignore,通过 repo 或 git submodule 管理。每次 Bring-up 前记录以下信息:SDK 版本号、工具链版本、内核 commit、U-Boot commit、设备树文件、板卡序列号。可用一个 env.md 或 build-info.txt 固化:

SDK: Marvell SDK 12.0.0
Toolchain: gcc-arm-10.3-2021.07
Kernel: linux-5.10.100 (commit a1b2c3d)
U-Boot: u-boot-2021.10 (commit e4f5g6h)
Board: CN9130-DB, SN: 2024-001

这样在出现“昨天还能编译,今天不行”时,可以快速定位是环境变量、工具链还是代码变更导致。

Marvell 平台开发环境搭建关系图 主机环境 (x86_64 Ubuntu) • build-essential / git / bc • libssl-dev / libncurses-dev • device-tree-compiler • minicom / picocom / openocd • python3 / pip3 交叉编译工具链 • aarch64-none-linux-gnu-gcc • ld / objcopy / gdb • sysroot 头文件与库 • 验证: -dumpmachine • 验证: file t → ARM aarch64 Marvell SDK • tools/toolchain/ • u-boot/ linux/ build/ • rootfs/ docs/ • source build/envsetup.sh • $CROSS_COMPILE / $ARCH 调试连接 串口 UART 115200 8N1 JTAG OpenOCD / TRACE32 • TX↔RX 交叉, GND 共地 • /dev/ttyUSB0 • scan_chain / halt / reg pc 版本管理 build-info.txt 固化记录 SDK / Toolchain / Kernel / U-Boot / Board SN • Git 管理 SDK 源码 • .gitignore 排除工具链二进制 • repo / submodule 管理多仓库 目标:编译通过 → 下载成功 → 串口有日志 → JTAG 可暂停 → 版本可追溯
建议在首次 Bring-up 前,用一张检查表逐项确认:工具链 -dumpmachine 输出、SDK 环境变量、串口设备节点、JTAG scan_chain 结果、build-info.txt 是否已填写。任何一项未通过,都不要急于上电烧录。
不要混用不同来源的工具链与 SDK。例如用 A 版本 SDK 的内核配合 B 版本工具链,可能出现 unrecognized command line option 或运行时 GLIBC 版本不匹配。若必须混用,先在 file 和 readelf -A 层面确认 ABI 一致。

完成以上四步后,宿主机应具备:能编译出 AArch64 ELF、能通过串口看到 U-Boot 日志、能通过 JTAG 暂停 CPU、能记录并复现当前环境。这是后续内核启动、驱动加载、文件系统挂载等 Bring-up 工作的基础。