QEMU Raspi3 AARCH64多核启用指导:除核心0外其他核心挂起问题
在QEMU模拟树莓派3b时启用多核功能
问题背景
在QEMU RISC-V环境中成功启用过多核,但模拟Raspi3b时,使用-smp 4参数启动后,仅核心0能正常运行,其他核心均卡在WFE循环中无法进入内核逻辑。
当前配置信息
QEMU启动命令
qemu-system-aarch64 \ -M raspi3b \ -m 1024M \ -smp 4 \ -S -s \ -kernel kernel8.img \ -serial stdio
初始启动代码
_start: //single core: only hart 0 jump to kernel mrs x0, mpidr_el1 and x0, x0, #0b11 cbz x0, _core_0 //cbz x0, 1f other_cores: wfe b other_cores _core_0: mrs x0, CurrentEL and x0, x0, #0b1100 cmp x0, #0b1000 ......
GDB调试输出
(gdb) info threads Id Target Id Frame 1 Thread 1.1 (CPU#0 [running]) main () at main.c:44 2 Thread 1.2 (CPU#1 [running]) 0x000000000000030c in ?? () 3 Thread 1.3 (CPU#2 [running]) 0x000000000000030c in ?? () 4 Thread 1.4 (CPU#3 [running]) 0x000000000000030c in ?? ()
QEMU版本
QEMU emulator version 6.2.0
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
问题原因
AArch64架构下,树莓派3的非0核心启动后会自动进入WFE(等待事件)状态,需要核心0主动发送SEV(发送事件)信号唤醒它们;同时原有代码未给非0核心分配独立栈空间和执行初始化逻辑,导致它们被唤醒后无法正常运行。
解决步骤
1. 为每个核心分配独立栈空间
在汇编代码或链接脚本中定义每个核心的专属栈,避免栈冲突:
.section .bss.stack // 存储每个核心的栈顶地址 stack_top_array: .quad stack_core0_top .quad stack_core1_top .quad stack_core2_top .quad stack_core3_top // 核心0栈(16KB) stack_core0: .space 16384 stack_core0_top: // 核心1栈(16KB) stack_core1: .space 16384 stack_core1_top: // 核心2栈(16KB) stack_core2: .space 16384 stack_core2_top: // 核心3栈(16KB) stack_core3: .space 16384 stack_core3_top:
2. 修改启动代码,支持多核唤醒与初始化
更新启动汇编,让非0核心在被唤醒后执行通用初始化,再进入内核主函数:
_start: // 读取当前核心ID mrs x0, mpidr_el1 and x0, x0, #0b11 // 提取低2位作为核心编号(0-3) // 为当前核心设置栈指针 adr x1, stack_top_array ldr x2, [x1, x0, lsl #3] // 每个栈顶地址占8字节,左移3位等价于乘8 mov sp, x2 // 核心0进入专属初始化流程 cbz x0, _core_0_init // 非0核心等待唤醒 other_cores_wait: wfe b _core_common_init // 核心0执行基础初始化(MMU、GIC、时钟等) _core_0_init: mrs x0, CurrentEL and x0, x0, #0b1100 cmp x0, #0b1000 // ... 保留原有核心0的初始化逻辑 ... // 初始化完成后,发送事件唤醒所有等待的核心 sev // 所有核心通用初始化流程 _core_common_init: // 执行通用初始化:设置异常向量表、启用FPU、配置中断等 // ... 添加你的通用初始化代码 ... // 跳转到内核主函数 b main
3. 验证效果
重新编译内核并启动QEMU,使用GDB调试时执行info threads,所有核心应都进入main()或通用初始化流程,不再卡在WFE循环地址。
内容的提问来源于stack exchange,提问作者Michaelbuzz
相关产品推荐
相关产品推荐

