3. 多核启动与CPU初始化流程
VxWorks SMP 系统的启动并不是“所有核同时跑起来”这么简单。它本质上是一条严格分阶段的控制链:BootROM 先让一个核成为引导核(boot core),由它完成最基本的硬件初始化、加载并跳转到 VxWorks 内核;内核在单核环境下完成早期初始化后,再根据 CPU 拓扑发现结果唤醒其余从核(secondary cores),最后才把系统切换到真正的 SMP 调度状态。理解这条链路,是排查“从核起不来”“SMP 没生效”“核间负载不均”等问题的前提。
一、BootROM 阶段:引导核独占运行
上电或复位后,最先执行的是固化在 ROM 中的 BootROM 代码。此时多核 CPU 通常处于两种状态之一:要么硬件约定某个核(如 PPC 的 Core 0、ARM 的 CPU0)为复位核,其余核被硬件保持在等待事件(如 spin table 或 WFE)状态;要么所有核都从复位向量开始,但 BootROM 会通过核号判断,只让引导核继续,其余核进入自旋等待。无论哪种方式,这一阶段的关键特征是只有一个核在跑代码。
BootROM 完成的工作包括:设置初始栈、初始化内存控制器与基本时钟、探测启动介质(Flash、TFTP、串口等),然后把 VxWorks 镜像(vxWorks 或 vxWorks_rom 等)搬移到 RAM 中的加载地址,最后跳转到内核入口。工程上常见的启动参数如 boot device、host ip、file name、load address 都在这一阶段被解析。需要强调的是,此时还没有任何 SMP 概念,从核仍处于硬件等待状态。
二、内核早期初始化:单核环境下的准备
进入 VxWorks 内核入口后,系统仍以单核方式运行。这一阶段依次完成:异常向量表安装、MMU/缓存初始化、内核数据结构(如任务控制块、就绪队列、内存池)建立、系统时钟与中断控制器初始化。对于 SMP 内核,还会额外初始化核间中断(IPI)机制、共享内存区域以及 SMP 相关的全局锁。
这里有一个容易混淆的点:内核已经编译为 SMP 版本,并不等于此刻已经在多核运行。在从核被唤醒之前,系统逻辑上仍是单核,只是“准备好了 SMP 所需的框架”。工程中若在此阶段打印核数,往往看到的是 1,这是正常现象。
三、CPU 拓扑发现:系统到底有几个核
内核早期初始化完成后,会执行 CPU 拓扑发现。它要回答三个问题:物理上有几个核、哪些核可用、核之间的层级关系(如 cluster、core、thread)。在 VxWorks 中,这通常通过读取硬件寄存器(如 ARM 的 MPIDR、PPC 的 PIR)或解析设备树/板级配置文件获得。
拓扑发现的结果会写入内核的 CPU 信息表,供后续从核唤醒和调度器使用。如果拓扑发现错误,典型后果是:从核数量不对、核号映射错乱、调度器把任务分配到不存在的核上。因此工程上常通过 sysCpuNumGet() 或启动日志中的 CPU 列表来核对拓扑发现结果。
四、从核唤醒:SMP 真正生效的时刻
拓扑发现完成后,引导核开始逐个唤醒从核。唤醒机制因架构而异:ARM 多核常用 spin table(从核在固定地址自旋等待引导核写入入口地址)或 IPI;PowerPC 常用 doorbell 或 IPI;x86 则通过 INIT-SIPI-SIPI 序列。VxWorks 把这些差异封装在 BSP 的 sysCpuEnable() 或类似接口中。
从核被唤醒后,会执行一段从核启动代码:设置自己的栈、初始化本地中断控制器、加入内核调度框架,然后进入空闲任务或直接参与调度。此时系统才真正进入 SMP 状态。工程上判断从核是否成功唤醒,最直接的方法是看启动日志中是否打印了每个核的启动信息,或用 sysCpuNumGet() 确认在线核数。
五、SMP 模式配置与工程启动参数
SMP 模式并不是“编译时选了 SMP 就自动全核运行”,它还需要工程配置配合。典型配置项包括:是否启用 SMP、从核数量、核间中断向量、共享内存区域、以及各核的初始任务分配策略。在 VxWorks 工程中,这些通常通过内核配置组件(如 INCLUDE_SMP、NUM_CPUS)和 BSP 参数共同决定。
启动参数方面,除了 BootROM 阶段的加载参数,SMP 相关参数还包括:从核启动地址、IPI 基地址、共享内存大小等。这些参数一旦配错,常见现象是从核无法唤醒、系统只跑单核、或核间通信异常。因此建议在工程启动脚本中显式列出这些参数,并在启动日志中逐项核对。
sysCpuNumGet() 返回值是否等于预期核数;再检查启动日志中从核唤醒记录;最后核对 BSP 中 IPI 与共享内存配置是否与硬件一致。六、典型启动日志与判断依据
以下是一段示例性的启动日志片段(参数为教学示例,非实测):
BootROM: loading vxWorks from 0x0
Kernel: early init done, cpu 0 online
CPU topology: 4 cores detected (core 0-3)
SMP: enabling secondary cores...
CPU 1 online
CPU 2 online
CPU 3 online
SMP: 4 CPUs active, scheduler started
判断依据很明确:如果只看到 “cpu 0 online” 而没有后续从核上线信息,说明从核唤醒失败;如果拓扑发现报出的核数与硬件不符,说明 MPIDR/PIR 读取或设备树解析有问题;如果日志显示 “SMP: 1 CPU active”,则说明 SMP 配置未真正生效。把这些观察点与前面的启动链路对应起来,就能快速定位问题出在 BootROM、内核早期、拓扑发现还是从核唤醒阶段。
整体来看,VxWorks SMP 启动是一条“先单核、后多核”的受控链路。BootROM 负责把引导核带起来,内核早期初始化搭好 SMP 框架,拓扑发现确定核资源,从核唤醒完成多核上线,最后 SMP 调度器接管任务分配。工程启动参数贯穿始终,既是配置入口,也是排查依据。理解这条链路,后续的核间同步、负载均衡与实时性调优才有稳定的基础。