Zephyr native_sim 交叉编译实战:在 x86_64 主机上构建并运行 ARM 目标可执行文件
2026/9/19 6:08:09 网站建设 项目流程

Zephyr native_sim 交叉编译实战:在 x86_64 主机上构建并运行 ARM 目标可执行文件

【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr

导读

本指南围绕 Zephyr RTOS 中native_sim板卡(基于 POSIX 架构的原生模拟目标)的交叉编译能力展开:当你在 x86_64 开发机上完成代码调试后,若需将同一份应用构建为可在其他处理器架构(如 32/64 位 ARM)机器上直接运行的可执行文件,就需要掌握这套交叉编译流程。阅读本文后,你将学会如何准备 Ubuntu 交叉编译工具链、正确传递ZEPHYR_TOOLCHAIN_VARIANTNATIVE_TARGET_HOSTCROSS_COMPILE三个关键 CMake 参数,并借助 QEMU 用户态模拟在开发机上快速验证产物。本文依据 boards/native/native_sim/doc/cross_compile.rst 编写,并结合仓库内 POSIX 架构与交叉编译工具链源码进行深化。

为什么需要对 native_sim 做交叉编译

native_sim是 Zephyr 的 POSIX 架构板卡:Zephyr 应用与内核、库一起编译,最终产出一个普通 Linux 可执行文件zephyr.exe)。它的主要用途是在工作站上调试、插桩和测试应用代码,并不模拟任何具体硬件,而是借助宿主机的 PTY/TTY、TAP 网络、SDL 显示等资源提供少量外设支持。

在这种开发模式下,常规用法是“本机构建、本机运行”。但在某些场景下,你需要在一台机器上构建、在另一台机器上执行——当两台机器处理器架构不同时(例如 x86_64 开发机与 ARM 目标机),就必须交叉编译。

⚠️安全警告(来自原文档)

native_sim是面向开发与调试的辅助手段,设计目标是可复现、便于插桩和访问执行状态。出于安全原因,绝不应将运行在native_sim上的生产代码作为最终产品交付。交叉编译出的可执行文件同样仅适用于开发、测试与验证。

准备你的构建主机

原文档以Ubuntu 24.04 x86_64开发机为例,演示如何交叉编译 32 位(arm/armhf)与 64 位(aarch64)ARM 目标。需要注意:交叉编译环境的搭建方式不止一种,你的主机与目标架构可能不同,因此请将本节视为思路参考而非唯一方案。

安装交叉编译工具链

第一步是在开发机上安装交叉编译工具链。在 Ubuntu 24.04 x86_64 上:

  • 64 位 ARM(aarch64)构建:安装gcc-aarch64-linux-gnu包。该包将工具链二进制安装为/usr/bin/aarch64-linux-gnu-*,库与头文件位于/usr/aarch64-linux-gnu/
  • 32 位 ARM(armhf)构建:安装gcc-arm-linux-gnueabihf包。该包将工具链二进制安装为/usr/bin/arm-linux-gnueabihf-*,库与头文件位于/usr/arm-linux-gnueabihf/
$ sudo apt-get install gcc-aarch64-linux-gnu # 64 位 ARM $ sudo apt-get install gcc-arm-linux-gnueabihf # 32 位 ARM(armhf)

关于 gcc-multilib 的冲突说明

原文档特别提醒:在 Ubuntu 24.04 中,gcc-multilib包与gcc-aarch64-linux-gnu存在冲突。而为了让 x86_64 主机支持 32 位构建,很多教程会引导你安装gcc-multilib

这并非严格的问题——gcc-multilib本质上是一个元包(meta-package),x86_64 上做 32 位构建真正需要的是它的依赖。因此:

  • 可以在安装gcc-multilibg++-multilib后将其卸载,同时保留其依赖;
  • 也可以直接安装这些依赖;
  • 关键是:安装后不要再移除这些依赖,否则 32 位构建会失败。

三个核心构建参数

交叉编译native_sim时,需要向 CMake 传递以下选项:

参数含义本示例取值
ZEPHYR_TOOLCHAIN_VARIANT=cross-compile选择 Zephyr 的“交叉编译”通用工具链变体cross-compile
NATIVE_TARGET_HOST指定目标机器架构64 位 ARM 用aarch64;32 位 ARM 用arm
CROSS_COMPILE交叉编译工具链前缀(含路径)/usr/bin/aarch64-linux-gnu-/usr/bin/arm-linux-gnueabihf-

此外,视编译器而定,可能还需要设置SYSROOT_DIR指向编译器的 sysroot 路径。

参数背后的源码机制

理解这三个参数如何被消费,有助于你在非标准环境下正确排错:

  1. NATIVE_TARGET_HOSTTARGET_HOST:在 arch/posix/CMakeLists.txt 中,如果定义了NATIVE_TARGET_HOST,会将其直接作为TARGET_HOST;否则根据宿主机处理器自动推断(arm*arm*86*x86_64)。随后 CMake 会尝试包含${CMAKE_CURRENT_LIST_DIR}/${TARGET_HOST}.cmake(即 arch/posix/arm.cmake 或 arch/posix/aarch64.cmake)来应用该目标架构特有的编译/链接选项;若文件不存在且显式指定了NATIVE_TARGET_HOST,会打印警告并继续。

  2. 架构一致性校验:arch/posix/aarch64.cmake 会调用scripts/build/user_wordsize.py检查用户态字长:当CONFIG_64BIT与宿主机用户态字长不符时直接FATAL_ERROR(并提示改选native_sim/native/64或修正CONFIG_64BIT)。arch/posix/arm.cmake 则直接拒绝CONFIG_64BIT=y的 32 位 ARM 目标组合。

  3. CROSS_COMPILE前缀:在 cmake/toolchain/cross-compile/generic.cmake 中,CROSS_COMPILE是传统 KBuild 机制的外置工具链前缀(可通过环境变量或 CMake 变量设置),并支持按板卡覆盖(CROSS_COMPILE_${NORMALIZED_BOARD_TARGET})。该文件还会在CROSS_COMPILE_TOOLCHAIN_PATH下探测_newlib_version.hpicolibc.h,据此自动决定工具链是否支持 newlib / Picolibc。

注意:POSIX 架构仅支持 Linux(见 arch/posix/CMakeLists.txt 顶部的FATAL_ERROR判断)。Windows 或 macOS 用户应考虑使用虚拟机运行 Linux 客户机。

完整构建命令示例

为 64 位 ARM(aarch64)构建 hello_world

使用west build(等价于原文档中的 cmake 构建命令):

$ west build -b native_sim//64 -p always samples/hello_world \ -DNATIVE_TARGET_HOST=aarch64 \ -DZEPHYR_TOOLCHAIN_VARIANT=cross-compile \ -DCROSS_COMPILE=/usr/bin/aarch64-linux-gnu-

其中native_sim//64native_sim/native/64目标的 west 板卡写法(64 位版本面向 LP64 ABI,指针与 long 为 64 位)。

为 32 位 ARM(armhf)构建 hello_world

$ west build -b native_sim -p always samples/hello_world \ -DNATIVE_TARGET_HOST=arm \ -DZEPHYR_TOOLCHAIN_VARIANT=cross-compile \ -DCROSS_COMPILE=/usr/bin/arm-linux-gnueabihf-

这里使用默认的native_sim目标(32 位版本,面向 ILP32 ABI,指针与 long 为 32 位,更贴近大多数嵌入式目标的 ABI,也更适合暴露指针/长整型宽度相关的缺陷,详见 boards/native/native_sim/doc/index.rst 中“32 and 64bit versions”一节)。

构建完成后,你会得到一个可执行文件zephyr/zephyr.exe(位于build目录下),可以将其拷贝到目标机器上运行。板卡元数据(boards/native/native_sim/native_sim.yaml)显示native_simarchposixtypenative,工具链支持hostllvm——交叉编译时则通过上述参数切换到cross-compile变体。

快速验证:在开发机上运行交叉编译产物

交叉编译出的可执行文件也可以在开发机上直接运行,前提是安装 QEMU 的用户态模拟器(User space emulator)。在 Ubuntu 24.04 上安装qemu-user包:

$ sudo apt-get install qemu-user

然后分别执行:

64 位 ARM 版本:

$ qemu-aarch64 -L /usr/aarch64-linux-gnu/ build/zephyr/zephyr.exe # Press Ctrl+C to exit

32 位 ARM 版本:

$ qemu-armhf -L /usr/arm-linux-gnueabihf/ build/zephyr/zephyr.exe # Press Ctrl+C to exit

其中-L指定交叉工具链 sysroot 路径,让 QEMU 能加载目标架构的动态库与系统文件。Zephyr 内核在应用结束后并不会真正退出,而是永远进入空闲循环,因此需要手动Ctrl+C终止。

交叉编译与原生构建的差异要点

  1. C 库选择native_sim默认使用宿主 C 库(CONFIG_EXTERNAL_LIBC),也可选择CONFIG_MINIMAL_LIBCCONFIG_PICOLIBC。交叉编译时 C 库由工具链携带(cross-compile工具链是否支持 newlib/Picolibc 取决于安装内容,构建系统会按上文所述的探测逻辑自动判定)。若选用与宿主 C 库不兼容的特性,系统会默认回退到 Picolibc(见 boards/native/native_sim/doc/index.rst)。

  2. 受限外设:部分驱动与后端对 C 库兼容性有限制——例如蓝牙 Userchan 仅支持宿主与 Picolibc,USB native posix 仅支持宿主 C 库。交叉编译到目标机时,这些依赖宿主资源的驱动行为需要结合目标环境重新评估。

  3. 时间模型native_sim的模拟时间默认与真实主机时间解耦(全速运行),只有时钟/定时器模型才把两者关联起来。交叉编译产物运行在目标机时,--rt/--no-rt--rt-ratio/--rt-drift等命令行选项依然有效,可用于将模拟时间锁到真实时间或调整速率。

总结

  • 交叉编译native_sim只需三个参数:ZEPHYR_TOOLCHAIN_VARIANT=cross-compileNATIVE_TARGET_HOST=<目标架构>CROSS_COMPILE=<工具链前缀>,必要时补充SYSROOT_DIR
  • 64 位 ARM 使用native_sim//64板卡与aarch64目标;32 位 ARM(armhf)使用默认native_sim板卡与arm目标。
  • 产物zephyr.exe可通过qemu-aarch64/qemu-armhf-L指定 sysroot 在开发机上先行验证。
  • 生产代码严禁运行于native_sim,本流程仅服务于开发、测试与调试场景。

如需进一步阅读:构建系统对NATIVE_TARGET_HOST的消费逻辑见 arch/posix/CMakeLists.txt,cross-compile工具链变体见 cmake/toolchain/cross-compile/generic.cmake,native_sim板卡整体文档见 boards/native/native_sim/doc/index.rst。

【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询