第1章:硬件平台选型与准备

做双系统,说白了第一步就是选对硬件。我见过不少朋友,软件调得差不多了,结果发现硬件不支持,那叫一个难受。今天咱们就聊聊,怎么挑一块能同时跑QNX和Linux的板子。

1.1 支持双系统的SoC/开发板

我个人习惯,先看SoC再看板子。为什么?因为SoC决定了你能不能用上硬件虚拟化,这可是双系统的核心。

1.1.1 主流SoC选型

SoC型号 架构 虚拟化支持 我的评价
NXP i.MX8M Plus Cortex-A53 x4 + M7 ARMv8虚拟化扩展 稳,项目里用得最多
TI TDA4VM Cortex-A72 x2 + R5F x2 硬件虚拟化+隔离 适合车载,就是贵了点
Renesas R-Car H3 Cortex-A57 x4 + A53 x4 完整虚拟化支持 日系车厂标配
Xilinx Zynq UltraScale+ Cortex-A53 x4 + R5F x2 可编程逻辑辅助 灵活,但开发周期长

嗯,这里要注意。不是所有带A核的SoC都适合做双系统。你得确认它支持硬件虚拟化扩展。我在项目中遇到过,有人拿了个不带虚拟化的A53板子,结果QNX和Linux互相抢资源,最后只能跑一个系统。

1.1.2 开发板推荐

  • NXP i.MX8M Plus EVK:入门首选,文档全,社区活跃。我第一块双系统板子就是它。
  • TI TDA4VM EVM:适合做ADAS或工业控制,双系统隔离做得很好。
  • Renesas R-Car H3 Starter Kit:汽车级,但价格感人。预算够的话直接上。
  • Xilinx KV260:FPGA+ARM组合,适合需要自定义外设的场景。
我的小建议:新手别一上来就搞R-Car。先拿i.MX8M Plus练手,成本低,踩坑了也不心疼。

1.2 硬件资源分区

双系统最头疼的是什么?资源打架。内存、外设,谁用哪块,得提前分清楚。

1.2.1 内存分区

说白了,就是把物理内存切成两块。一块给QNX,一块给Linux。中间留个共享区,用来做核间通信。

// 典型内存布局(以4GB DDR为例)
// 地址范围         用途
// 0x80000000 - 0xBFFFFFFF  QNX (1GB)
// 0xC0000000 - 0xEFFFFFFF  Linux (1.5GB)
// 0xF0000000 - 0xFFFFFFFF  共享内存 (256MB)
// 剩余空间              保留给硬件外设

为什么会这样分?我跟你讲,QNX对实时性要求高,所以给它靠近低地址的内存,访问延迟低。Linux嘛,大块内存给它跑应用。共享区放256MB,够传数据了。

注意:共享内存的大小不是越大越好。我曾经设了512MB,结果两边系统都喊内存不够。后来改成256MB,刚刚好。

1.2.2 外设分区

外设怎么分?原则很简单:谁用谁管,互不干扰

  • QXN独占:CAN控制器、实时时钟、看门狗、GPIO中断控制器
  • Linux独占:USB主机、以太网MAC、GPU、显示控制器
  • 共享外设:UART(调试用)、I2C(传感器)、SPI(低速外设)

嗯,这里有个坑。共享外设一定要加互斥锁。我记得有一次,QNX和Linux同时读写同一个I2C设备,结果数据全乱了。后来加了硬件信号量才解决。

1.3 启动介质选择

启动介质这事儿,看着简单,其实门道不少。我见过有人用SD卡做产品,结果跑着跑着卡坏了,系统直接挂掉。

1.3.1 eMMC

首选。为什么?稳定、速度快、寿命长。我所有量产项目都用eMMC。

  • 容量:8GB起步,建议16GB
  • 接口:eMMC 5.1 HS400,读写能到400MB/s
  • 分区:QNX放一个分区,Linux放一个分区,再加一个数据分区
// eMMC分区示例
// /dev/mmcblk0p1  QNX系统 (2GB)
// /dev/mmcblk0p2  Linux系统 (4GB)
// /dev/mmcblk0p3  共享数据 (剩余空间)

1.3.2 SD卡

适合开发调试。换系统方便,拔卡一插就行。但别用在产品上,我吃过亏。

避坑指南:我曾经用SD卡做原型验证,结果连续读写三天,卡就挂了。后来换成eMMC,再没出过问题。

1.3.3 NVMe

高端玩法。如果你对IO性能要求极高,比如跑数据库或者视频处理,NVMe是王道。

  • 接口:M.2或U.2,走PCIe 3.0/4.0
  • 速度:顺序读写3GB/s以上
  • 注意:需要SoC支持PCIe,且功耗较高

不过说实话,嵌入式场景用NVMe的少。除非你做边缘服务器或者高端工控机,否则eMMC完全够用。

1.4 启动流程设计

双系统怎么启动?有两种主流方式。

1.4.1 方式一:Bootloader引导

U-Boot或TF-A先启动,然后根据配置加载QNX或Linux。适合开发阶段。

// U-Boot环境变量示例
// 启动QNX
setenv boot_qnx 'fatload mmc 0:1 0x48000000 qnx.ifs; bootm 0x48000000'
// 启动Linux
setenv boot_linux 'fatload mmc 0:2 0x48000000 Image; fatload mmc 0:2 0x48000000 dtb; booti 0x48000000 - 0x48000000'

1.4.2 方式二:Hypervisor管理

用Xen或ACRN这类虚拟机监控器,同时启动两个系统。这是产品级方案。

我个人推荐方式二。虽然配置复杂点,但隔离性好,一个系统挂了不影响另一个。我在车载项目里就是这么干的。

核心要点:启动介质选eMMC,内存分区要合理,外设分配要清晰。这三样做好了,双系统就成功了一半。

好了,硬件平台这块就聊到这儿。下一章咱们讲讲怎么搭建开发环境,把QNX和Linux的交叉编译工具链配起来。到时候见。