2. 开发环境搭建
Layerscape 平台(如 LS1046A、LS1028A、LX2160A)运行的是 AArch64 Linux,而开发主机通常是 x86_64,因此“在主机上编译、在目标板上运行”的交叉开发模式是整条开发链的起点。本节把环境搭建拆成四条相互依赖的通道:工具链、发行版构建系统、启动加载通道、调试通道。四者缺一,后续驱动移植、网络加速(DPAA/DPDK)验证都无从谈起。
一、交叉编译工具链:先确定 ABI,再选来源
工具链的核心不是“能编译”,而是与目标 rootfs 的 ABI 一致。Layerscape 常见组合是 aarch64-linux-gnu(glibc)或 aarch64-linux-musl(musl,OpenWrt 常用)。判断依据有三点:目标 rootfs 的 libc 类型、内核头文件版本、以及是否使用硬件浮点与 CRC 扩展。LS1046A 的 Cortex-A72 支持 ARMv8-A + CRC + Crypto,工具链应至少以 -march=armv8-a+crc+crypto 编译关键库,否则 DPAA 的校验和卸载会退化为软件计算。
工具链来源通常有三种:NXP 官方 LSDK 自带的 GCC、Yocto 构建时生成的 SDK、以及 Linaro/发行版提供的通用工具链。推荐做法是让工具链与 rootfs 同源——用 Yocto 生成的 SDK 安装包(*.sh)安装,环境变量由 environment-setup-aarch64-poky-linux 统一注入,避免手工拼 PATH 导致的 sysroot 错配。验证方式很直接:
$ source /opt/fsl-imx-xwayland/.../environment-setup-aarch64-poky-linux
$ $CC -dumpmachine
aarch64-poky-linux
$ echo 'int main(){return 0;}' > t.c && $CC t.c -o t
$ file t
t: ELF 64-bit LSB executable, ARM aarch64, dynamically linked
若 file 显示 x86-64,说明 CC 未生效;若链接报 cannot find -lc,多半是 sysroot 指向了主机库。这两条是最常见的“工具链装好了却编不过”的根因。
二、Yocto / OpenWrt / LSDK:按“要不要改发行版”来选
三者不是并列替代品,而是覆盖不同自由度。LSDK 是 NXP 的参考发行版,预集成 U-Boot、内核、DPAA、TSN、安全引擎,适合快速点亮与验证硬件;Yocto 是构建框架,LSDK 本身也基于 Yocto,适合需要裁剪、增删 recipe、做产品化 BSP 的场景;OpenWrt 面向网络设备,包管理与网络栈更轻量,适合做网关、CPE 类产品,但对 DPAA 加速的现成支持不如 LSDK 完整。
选择逻辑可以概括为:先问“是否需要长期维护自己的发行版”。若只是评估板卡、跑通网络转发,直接用 LSDK 预编译镜像最快;若要交付产品并控制 rootfs 体积与升级策略,用 Yocto 建自己的 distro;若产品形态接近路由器且团队熟悉 OpenWrt 生态,再考虑 OpenWrt。三者都依赖同一套交叉工具链思路,切换成本主要在 BSP 层而非工具链层。
三、TFTP + NFS:把“烧写”变成“加载”
开发阶段频繁改内核和 rootfs,若每次都写 SD 卡或 QSPI 会极大拖慢节奏。TFTP 负责把 Image、fsl-ls1046a-rdb.dtb 从主机拉到 DDR,NFS 负责把主机目录直接当根文件系统挂载。这样改一个驱动只需重新编译、重启板子,几秒即可验证。
主机侧先准备 TFTP 根目录与 NFS 导出:
# /etc/default/tftpd-hpa
TFTP_DIRECTORY="/srv/tftp"
TFTP_OPTIONS="--secure --create"
# /etc/exports
/srv/nfs/rootfs 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
$ sudo systemctl restart tftpd-hpa nfs-kernel-server
U-Boot 侧设置启动参数,注意 ip 与 serverip 必须与主机同网段:
=> setenv ipaddr 192.168.1.100
=> setenv serverip 192.168.1.10
=> setenv bootargs 'console=ttyS0,115200 root=/dev/nfs rw
nfsroot=192.168.1.10:/srv/nfs/rootfs,v3,tcp
ip=192.168.1.100:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off'
=> tftp 0x80000000 Image
=> tftp 0x90000000 fsl-ls1046a-rdb.dtb
=> booti 0x80000000 - 0x90000000
判断是否成功,看内核日志末尾是否出现 VFS: Mounted root (nfs filesystem),以及能否进入 shell。若卡在 IP-Config: no response,通常是网线接错口(Layerscape 有多路 MAC,需确认 U-Boot 的 ethact 指向正确接口);若挂载超时,检查 NFS 版本与 no_root_squash 是否生效。
四、串口与网络调试通道:先能看见,再能改
串口是“最后一道防线”。即使网络全挂,只要串口能进 U-Boot,就能改环境变量、重新 TFTP。主机侧用 minicom 或 picocom:
$ sudo picocom -b 115200 /dev/ttyUSB0
# 退出:Ctrl-A Ctrl-X
网络调试通道则依赖 SSH。首次启动 NFS rootfs 后,确认 sshd 已运行、板子能 ping 通主机,再用 scp 推送测试程序。此时应形成闭环:主机编译 → TFTP 加载内核 → NFS 挂载 rootfs → SSH 登录 → 运行程序 → 串口看内核日志。任何一环断裂,都能通过“串口看 U-Boot、网络看 SSH”快速定位。
saveenv 前先确认 bootargs 与 bootcmd 正确,否则一次误存会导致板子无法自动启动,只能靠串口手动恢复。/etc/fstab 中不要重复挂载根目录;同时确保主机防火墙放行 111、2049 端口,否则会出现“能 ping 通但挂载失败”的典型现象。