4. 开发环境搭建与交叉编译
NVIDIA DRIVE 平台的开发与普通 x86 服务器开发有一个根本差异:代码在主机(Host,通常是 x86_64 Ubuntu 工作站)上编写和编译,但最终运行在目标板卡(Target,DRIVE AGX 上的 ARM64 SoC,如 Orin 系列)上。因此整个环境搭建的核心,是建立一条从主机到目标板的可靠通路,并让编译产物、系统镜像、调试手段都能在这条通路上正确流动。本节围绕主机环境、目标板连接、交叉编译工具链、DriveOS 刷写与启动流程四件事展开。
主机开发环境配置
主机推荐使用 Ubuntu 20.04 或 22.04 LTS,内核版本与 NVIDIA SDK Manager 要求保持一致。基础依赖包括构建工具、设备访问工具和镜像处理工具:
sudo apt update
sudo apt install -y build-essential git cmake ninja-build \
python3 python3-pip device-tree-compiler \
libusb-1.0-0-dev usbutils picocom minicom \
qemu-user-static binfmt-support
# 安装 NVIDIA SDK Manager(用于刷写与组件管理)
sudo apt install -y ./sdkmanager_*.deb
sdkmanager --version
SDK Manager 负责下载 DriveOS 组件、生成刷写镜像并驱动刷写流程。首次运行需要 NVIDIA 开发者账号登录,登录后它会拉取与目标板卡型号匹配的 BSP(Board Support Package)。主机磁盘建议预留 100 GB 以上,因为 DriveOS 的完整 BSP 与交叉工具链体积较大。此外,主机需要能通过 USB 与目标板通信,因此要确认当前用户属于 plugdev 组,否则刷写阶段会出现权限拒绝。
目标板卡连接与访问方式
DRIVE AGX 开发套件通常提供多种连接通道,用途各不相同:
- USB Type-C / Micro-USB 调试口:连接后主机出现
/dev/ttyUSB*或/dev/ttyACM*,用于串口控制台,可观察 UEFI、内核和启动日志。 - 以太网口:刷写完成后通过 SSH 登录系统,进行应用部署与调试。
- DisplayPort / HDMI:用于查看图形界面与推理可视化结果。
- 电源与散热:DRIVE 板卡功耗较高,需使用配套电源并保证散热,否则高负载推理时会触发降频。
串口控制台是排障的第一入口。连接示例:
# 查看串口设备
ls /dev/ttyUSB*
# 以 115200 波特率打开控制台
sudo picocom -b 115200 /dev/ttyUSB0
刷写完成后,目标板默认 IP 常为 192.168.1.100 一类地址,主机需配置同网段静态 IP,例如主机设为 192.168.1.10/24,然后 ssh nvidia@192.168.1.100 登录。若无法登录,应先用串口确认系统是否真正启动到用户态。
交叉编译工具链
交叉编译的关键是让主机上的编译器生成 ARM64 可执行文件。NVIDIA 在 DriveOS BSP 中提供了配套的 aarch64 工具链,通常位于 toolchains/ 目录下。使用前先设置环境变量:
export CROSS_COMPILE=/opt/nvidia/toolchains/aarch64--glibc--stable/bin/aarch64-linux-gnu-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export SYSROOT=/opt/nvidia/toolchains/aarch64--glibc--stable/aarch64-linux-gnu/sysroot
# 验证
${CC} --version
${CC} -dumpmachine # 应输出 aarch64-linux-gnu
编译时通过 --sysroot 指向目标板根文件系统,确保链接到的是目标板的库而非主机的库。以 CMake 工程为例,可编写工具链文件:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_SYSROOT /opt/nvidia/toolchains/aarch64--glibc--stable/aarch64-linux-gnu/sysroot)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
配置时使用 cmake -DCMAKE_TOOLCHAIN_FILE=aarch64.cmake ..。编译完成后用 file 命令确认产物架构:
file ./infer_demo
# 期望输出:ELF 64-bit LSB executable, ARM aarch64 ...
如果输出仍是 x86-64,说明工具链未生效,应检查 CMake 缓存是否残留了主机编译器路径,必要时删除 CMakeCache.txt 重新配置。对于依赖 CUDA、TensorRT 的推理程序,交叉编译时还需把目标板的 CUDA/TensorRT 头文件与库路径加入 sysroot,否则链接阶段会报找不到 libnvinfer.so。
DriveOS 刷写与系统启动流程
刷写是把 DriveOS 镜像写入目标板存储的过程。典型流程是:主机通过 SDK Manager 选择目标板型号与 DriveOS 版本,下载并生成镜像;将目标板置于恢复模式(Recovery Mode),通常需要按住恢复按键再上电;主机识别到 USB 设备后开始刷写。刷写完成后板卡自动重启,进入启动流程。
启动过程大致分为几个阶段:BootROM 加载引导程序,UEFI 初始化硬件并选择启动设备,随后加载内核与设备树,挂载根文件系统,最后启动用户态服务。串口日志是判断启动是否正常的主要依据。常见异常与判断方式如下:
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| 串口无任何输出 | 未进入恢复模式或串口参数错误 | 检查按键时序、波特率 115200 |
| 卡在 UEFI 阶段 | 启动设备或镜像损坏 | 重新刷写,确认镜像版本匹配 |
| 内核 panic | 设备树或根文件系统不匹配 | 核对 BSP 与板卡型号 |
| 启动后无法 SSH | 网络未配置或服务未起 | 串口登录后检查网络配置 |
刷写与启动的完整链路可以用下面的图来理解,它把主机侧操作、目标板状态变化和观察点对应起来:
判断环境是否真正搭好,可以按三个观察点确认:串口能看到完整启动日志并进入登录提示;file 检查交叉编译产物为 ARM aarch64;SSH 能登录目标板并执行部署的程序。三者同时满足,说明主机、工具链、板卡和系统镜像已经形成闭环,可以进入后续的推理部署与性能优化阶段。
env.sh 统一导出 CROSS_COMPILE、SYSROOT 和 TARGET_IP,团队协作时可直接复用。