4. 开发环境搭建实战

Jacinto 平台的开发环境不是“装一个 IDE”就能完成的,它由四层能力叠加而成:SDK 与源码获取、构建系统(Yocto 或 Android)、交叉编译工具链、板端调试与启动通道。这四层缺一层,后面的驱动修改、内核裁剪、应用部署都会卡住。本节按实际工程顺序展开,并给出可直接参考的示例参数。

一、SDK 获取:先分清“预编译包”和“源码仓库”

TI 对 Jacinto(如 TDA4VM、DRA829、J721E 系列)通常提供两类交付物:一类是 Processor SDK Linux / RTOS 预编译包,内含已构建好的 bootloader、内核、根文件系统、示例镜像和工具链;另一类是 Yocto 源码层(meta-ti、meta-arago、oe-layersetup),用于从源码重建。工程上建议先跑通预编译包,确认板子能启动、串口能进系统,再切到源码构建,否则一旦启动失败,无法判断是硬件、镜像还是构建配置的问题。

获取时注意三点:版本对齐(SDK 版本、内核版本、U-Boot 版本必须与硬件 EVM 版本匹配)、下载完整性(校验 md5/sha256)、目录规划(源码、构建输出、工具链分开放,避免路径过长导致 Yocto 报错)。示例目录结构如下:

~/jacinto/
├── sdk/            # 预编译 SDK 安装目录
├── yocto/          # oe-layersetup + meta 层
│   ├── build/      # bitbake 构建输出
│   └── sources/    # 各 meta 层源码
├── toolchain/      # 交叉编译工具链
└── images/         # 最终烧录镜像

二、Yocto 与 Android 构建系统:两条路线怎么选

Jacinto 的 Linux 侧以 Yocto/OpenEmbedded 为主,Android 侧则基于 AOSP 加 TI 的 BSP 层。选择依据是产品形态:仪表、域控制器、Linux 应用为主的座舱,优先 Yocto;需要完整 Android 应用生态、HMI 框架的,走 Android。两者共同点是都依赖 repo 管理多仓库、分层(layer)组织、交叉编译,区别在于构建命令和产物格式。

Yocto 的典型流程是:用 oe-layersetup 拉取指定 release 的 layer 配置,执行 bitbake 构建目标镜像。关键配置在 conf/local.conf 与 bblayers.conf,机器名(MACHINE)必须与板型一致,例如 j721e-evm。Android 侧则用 repo init -u ... -b <tag> 同步,再用 lunch 选择目标,最后 make 出镜像。无论哪条路线,首次构建都建议预留 200GB 以上磁盘和 16GB 以上内存,并开启足够 swap,否则 bitbake 或 soong 容易因内存不足中断。

构建前先确认主机环境:Ubuntu 20.04/22.04 LTS、Python 版本、chrpath、diffstat、gawk 等依赖包齐全。Yocto 对主机工具版本敏感,缺包往往在构建中途才报错。

三、交叉编译工具链:让 x86 主机产出 ARM 程序

Jacinto 的 A72/A53 核运行 64 位 ARM 代码,主机是 x86_64,因此必须用交叉工具链。SDK 自带工具链通常位于 linux-devkit 下,通过 environment-setup 脚本注入环境变量。核心变量包括 CC、CXX、AR、SYSROOT,其中 SYSROOT 指向目标根文件系统的头文件和库,是链接阶段最容易出错的地方。

source ~/jacinto/sdk/linux-devkit/environment-setup-aarch64-oe-linux
echo $CC
# aarch64-oe-linux-gcc -mcpu=cortex-a72 ...
$CC hello.c -o hello
file hello
# ELF 64-bit LSB executable, ARM aarch64

判断工具链是否可用,看三点:file 输出为 ARM aarch64、readelf -h 的 Machine 为 AArch64、程序能通过 NFS 或 scp 放到板端运行。若链接时报 cannot find -lxxx,优先检查 SYSROOT 是否指向了正确的目标 sysroot,而不是主机库。

四、调试串口与网络启动配置

串口是 Jacinto 板子“最后的救命通道”。典型连接是 USB 转 TTL 接 EVM 的 MAIN UART,参数为 115200-8-N-1,无流控。主机侧用 minicom、picocom 或 screen 打开,例如 picocom -b 115200 /dev/ttyUSB0。上电后应能看到 U-Boot 的 U-Boot SPL 与 U-Boot 202x.xx 打印,按任意键进入 U-Boot 命令行,这是判断板子是否正常启动的第一依据。

网络启动(TFTP + NFS)是开发阶段最高效的方式:内核和 DTB 通过 TFTP 加载,根文件系统通过 NFS 挂载,改代码后无需重新烧写 eMMC。U-Boot 中需设置 serverip、ipaddr、bootcmd,并确保主机 TFTP 根目录和 NFS 导出配置正确。示例:

setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10
setenv bootargs console=ttyS2,115200n8 root=/dev/nfs rw \
  nfsroot=192.168.1.10:/nfs/rootfs,v3,tcp ip=dhcp
tftp 0x82000000 Image
tftp 0x83000000 k3-j721e-evm.dtb
booti 0x82000000 - 0x83000000

判断网络启动是否成功,看串口是否出现内核解压、驱动探测、最后进入登录提示;若卡在 VFS: Unable to mount root fs,多半是 NFS 路径、协议版本或防火墙问题,而不是内核问题。

Jacinto 开发环境四层结构与数据通路 主机(x86_64 Ubuntu) SDK / 源码仓库(repo、oe-layersetup) Yocto bitbake / Android make 交叉工具链 aarch64-oe-linux-gcc 构建产物 tiboot3.bin / tispl.bin u-boot.img Image + DTB + rootfs Jacinto EVM 板端 U-Boot(串口 115200-8-N-1) Linux Kernel + 设备树 NFS 根文件系统 / eMMC 构建 烧录/加载 开发阶段两条启动通路 网络启动(TFTP + NFS) TFTP 服务器 Image / DTB NFS rootfs 改代码 → 重新编译 → 重启板子即可,无需烧写 量产/固化启动(eMMC / SD) 镜像打包 烧录工具 eMMC/SD 版本固化、现场部署,启动不依赖主机 串口终端观察启动日志

五、把环境串起来的检查顺序

实际排障时,建议按“串口 → U-Boot → 网络 → 内核 → 根文件系统 → 应用”的顺序逐层确认。串口无输出,先查线序、波特率和供电;U-Boot 能进但 TFTP 超时,查主机 IP、防火墙和 TFTP 根目录权限;内核启动但挂载根文件系统失败,查 NFS 导出与 bootargs;系统起来后应用跑不起来,再回到交叉编译工具链和 SYSROOT 检查动态库依赖。这个顺序能把“环境问题”和“代码问题”快速分开,避免在错误的方向上反复烧写镜像。

不要跳过预编译 SDK 直接上源码构建。先用官方镜像确认板子、串口、网络都正常,再替换成自己构建的镜像,才能把变量控制在构建系统这一层。

完成本节后,你应当能够独立完成:获取并校验 SDK、选择 Yocto 或 Android 路线、配置交叉编译环境、通过串口进入 U-Boot、用 TFTP+NFS 启动自定义内核与根文件系统,并根据串口日志判断失败发生在哪一层。这套环境一旦跑通,后续的内核裁剪、驱动移植和应用部署才有稳定的落脚点。