2. VxWorks多核启动与镜像构建
VxWorks 多核系统的启动过程,本质上是“一个引导核先把系统跑起来,再把其余核拉入同一运行环境”的过程。SMP 与 AMP 的差别,不在于是否使用多核,而在于各核是否共享同一个内核实例、同一份系统镜像和同一套调度器。理解这一点,后续的镜像配置、核间初始化和启动参数才有统一的判断依据。
SMP 与 AMP 的启动路径差异
在 SMP 配置下,VxWorks 只加载一份内核镜像,所有 CPU 核共享同一份内核代码段、数据段和调度器。上电后由 BootROM 或 U-Boot 完成基本硬件初始化,把 VxWorks 镜像搬到内存并跳转到入口点。此时只有一个核真正执行内核初始化,通常称为引导核(boot core);其余核处于等待状态,由内核通过核间中断或平台特定的释放寄存器逐个唤醒,进入调度器参与任务执行。
AMP 则不同:每个核可以运行独立的 VxWorks 镜像,或一个核跑 VxWorks、另一个核跑裸机程序/Linux。各核有各自的入口地址、各自的内存区域和各自的中断控制器视图。启动时通常由主核先完成共享资源(DDR、时钟、外设、核间通信通道)的初始化,再通过写释放地址的方式让从核从指定入口开始执行。因此 AMP 的启动参数必须明确“哪个核、从哪个地址、用什么镜像、访问哪段内存”。
镜像配置的关键项
镜像配置决定了内核“看到”多少核、内存如何划分、启动后执行什么。在 Workbench 或命令行构建时,VIP(VxWorks Image Project)中的内核配置组件是核心入口。与多核启动直接相关的配置项包括:
- CPU 核数:SMP 下由
VX_SMP_NUM_CPUS或 BSP 中的NUM_CPUS指定,必须与实际硬件核数一致,否则会出现核未被唤醒或访问越界。 - 内存布局:SMP 共享同一份系统内存池;AMP 需要为每个核划分独立的代码段、数据段和堆栈区域,并在链接脚本中固定地址,避免相互踩踏。
- 入口地址:AMP 从核镜像的入口地址必须与主核写入释放寄存器的值一致,通常由链接脚本的
ENTRY或 BSP 中的sysAmpCoreEntry决定。 - 启动参数:包括引导核编号、从核释放方式(寄存器地址/中断号)、共享内存基址与大小、IPC 通道编号等。
一个典型的 AMP 启动参数配置片段如下,用于说明主核如何描述从核的启动信息:
/* AMP 启动参数示例(教学假设值) */
#define AMP_CORE1_ENTRY 0x00200000 /* 从核镜像入口 */
#define AMP_CORE1_STACK 0x00300000 /* 从核独立栈顶 */
#define AMP_RELEASE_REG 0x1FF80000 /* 核释放寄存器 */
#define AMP_SHARED_MEM_BASE 0x10000000 /* 共享内存基址 */
#define AMP_SHARED_MEM_SIZE 0x00100000 /* 共享内存 1MB */
#define AMP_IPC_CHANNEL 1 /* 消息队列通道号 */
这些参数不是随意填写的:入口地址必须落在从核镜像实际加载的位置,共享内存区域必须避开各核私有数据段,释放寄存器地址必须与 SoC 手册一致。配置完成后,通常通过串口日志确认每个核是否打印出自己的核编号和启动状态。
核间初始化与启动参数的实际处理
核间初始化发生在引导核完成基本内核初始化之后、从核正式参与调度之前。SMP 下,内核会自动完成从核的栈分配、每核数据区(per-CPU data)初始化和调度器挂接;开发者需要关注的是共享资源的并发保护,例如全局变量、外设寄存器和缓存一致性。AMP 下,核间初始化需要手动完成,典型顺序是:主核初始化共享内存和 IPC 通道 → 主核写释放寄存器 → 从核从入口启动 → 从核初始化自身 MMU/中断 → 从核通过 IPC 向主核报告就绪。
启动参数在这一过程中起到“契约”作用。以核间通信为例,如果主核使用共享内存基址 0x10000000、大小 1MB,从核也必须使用同一组参数,否则双方看到的消息队列控制结构不一致,表现为发送成功但接收端永远收不到。实际调试时,可以先用一个最小的“心跳”任务验证:主核每 100ms 向通道 1 发送一个递增计数,从核收到后回送确认,通过串口打印双方计数是否同步增长。若计数停滞,优先检查释放寄存器是否写对、从核入口是否指向正确镜像、共享内存是否被 MMU 映射为可缓存/非缓存一致。
VX_SMP_NUM_CPUS 是否大于 1,再检查 BSP 的核释放函数是否被正确调用。AMP 调试时,若从核没有任何输出,优先用调试器读释放寄存器地址,确认主核确实写入了预期值。配置检查清单
在镜像构建完成、下载到目标板之前,建议按以下清单逐项核对,避免把启动问题带到运行阶段:
| 检查项 | SMP 关注点 | AMP 关注点 |
|---|---|---|
| 核数配置 | 与实际核数一致 | 主/从核镜像分别对应 |
| 内存布局 | 共享系统内存池 | 各核私有段不重叠 |
| 入口地址 | 由内核统一管理 | 与释放寄存器写入值一致 |
| 共享资源 | 自旋锁/原子操作保护 | IPC 通道与共享内存参数一致 |
| 启动日志 | 各核打印核编号 | 从核报告就绪、心跳同步 |
把启动流程、镜像配置和核间初始化放在一起看,SMP 的关键是“让所有核进入同一个内核并安全共享资源”,AMP 的关键是“让每个核从正确的地址启动、用一致的参数通信”。启动参数就是这两条路径上的连接点:写错一个地址或一个基址,系统可能仍然能启动,但多核协作会在运行阶段以难以定位的方式失败。因此,构建镜像时逐项核对参数,比启动后再排查要高效得多。