搞懂:U-Boot 在“可能多核同时进来”的场景下,如何把主核/从核分流;以及在 LS1028 + TF-A(PSCI)体系下,Linux 的多核拉起真正依赖什么
多核启动的核心误区是混淆「U-Boot 内部分流」和「Linux 多核拉起」,先明确三层边界:
👉 结论:start.S 的主从核分流只解决第 1 件事;Linux 只识别 1 核,90% 是第 3 件事出问题。
分流代码位置:arch/arm/cpu/armv8/start.S(lowlevel_init 后、跳_main 前)核心逻辑不是 “默认生效”,而是由编译宏控制:

arch/arm/include/asm/macro.hCONFIG_ARMV8_MULTIENTRY:读取 mpidr_el1 寄存器,判定全 0 affinity 的核为主核;master_label 标签。arch/arm/cpu/armv8/spin_table_v8.S
wfe(低功耗休眠)→ 读取 spin_table_cpu_release_addr → 地址非 0 则执行 br(跳转)。
主核需完成两步操作:① 写入从核执行的入口地址;② 发送 sev/SGI 触发 wfe 退出(而非仅依赖中断),从核才会检查地址并执行。
生效条件:仅开启 CONFIG_ARMV8_MULTIENTRY 时生效核心代码:arch/arm/cpu/armv8/start.S
从核采用「wfe 低功耗休眠 + 轮询可配置地址」机制:
wfe 降低功耗;CPU_RELEASE_ADDR 指向的地址;CPU_RELEASE_ADDR 是可配置宏(而非代码写死的物理地址),可适配不同平台的内存布局,灵活性显著提升。
在 lowlevel_init 初始化流程中:从核执行 armv8_switch_to_el2/el1(EL 等级切换)逻辑,仅在 CONFIG_ARMV8_MULTIENTRY 开启时生效。
include/configs/ls1028a_common.h
CPU_RELEASE_ADDRsecondary_boot_func 符号(平台自定义从核入口钩子);arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S。对 mydjls1028_tfa_defconfig,真实链路是:U-Boot 启用 PSCI 支持 → Linux DTB 配置 psci → TF-A/BL31 提供 PSCI 接口 → Linux 通过 SMC 唤醒从核。
检查设备树路径:arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi#L20-L56关键配置:
✅ 验证指令:cat /proc/device-tree/cpus/cpu@1/enable-method → 输出必须是 psci。
ENABLE_PSCI=1 PSCI_VERSION=1.0;CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y CONFIG_ARMV8_PSCI_FW=y。必须保留的配置:
CONFIG_SMP=y // 多核核心开关CONFIG_ARM64_PSCI=y // PSCI核心支持CONFIG_ARM64_PSCI_1_0=y // 匹配TF-A的PSCI 1.0CONFIG_ARM_SMC=y // SMC指令(调用PSCI的基础)
✅ 验证指令:zcat /proc/config.gz | grep -E "SMP|PSCI|SMC" → 均为 y。
👉 反常识结论:
U-Boot 的 CONFIG_ARMV8_MULTIENTRY/SPIN_TABLE,多数情况下不直接决定 Linux SMP。
问题:内核开了 SMP,但启动后只识别到 1 个核心,最可能先查什么?答案(优先级从高到低):