我在QEMU 6.2.0上仿真了4核ARMv8A (Cortex-A53)。主代码(CPU#0)正在运行,我可以使用GDB调试它。我想提出其他核心。为此,我使用了以下GDB命令。从不同的实验中,我的结论是只有CPU#0在运行,其他所有CPU都没有启动。
(gdb) thread 3
(gdb) info thread
Id Target Id Frame
1 Thread 1.1 (CPU#0 [running]) 0x0000000040000008 in ?? ()
2 Thread 1.2 (CPU#1 [halted ]) 0x0000000040000000 in ?? ()
* 3 Thread 1.3 (CPU#2 [halted ]) 0x0000000040000000 in ?? ()
4 Thread 1.4 (CPU#3 [halted ]) 0x0000000040000000 in ?? ()
(gdb) where
#0 0x0000000040000000 in ?? ()
进一步开发,遇到了这个关于使用PSCI打开CPU的线程。在QEMU上启动第二个PSCI核心
也遇到了与此相关的SMC调用约定。我已经看了SMCCC和PSCI的文件。
我正在实现一个最小的管理程序。来宾系统是Linux,并且正在启动。Linux引导日志显示
[ 0.072225] psci: failed to boot CPU1 (-22)
...
进一步调试代码显示,Linux正在向管理程序抛出一个同步异常,并根据规范使用"hvc"抛出必要的参数。指令。
如果我的理解是正确的,PSCI实现是特定于供应商的——也就是说,运行在EL2/EL3上的代码必须使用一些供应商提供的机制来打开CPU(核心)。这是正确的吗?在没有EL3的系统上,运行在EL2的代码如何打开CPU?
我的QEMU命令行如下
$qemu-system-aarch64 -machine virt,gic-version=2,virtualization=on -cpu cortex-a53 -nographic -smp 4 -m 4096 -kernel hypvisor.elf -device loader,file=linux-5.10.155/arch/arm64/boot/Image,addr=0x80200000 -device loader,file=1gb_4core.dtb,addr=0x88000000
任何提示都非常感谢。
当客户机不在EL3引导时,QEMUvirt
机器实现自己的内部PSCI仿真。在传递给客户机的DTB文件中描述了这一点,并且说明PSCI调用应该通过SMC
指令(如果客户机从EL2开始)或HVC
指令(如果客户机从EL1开始)来完成。实际上,QEMU正在为您模拟一个EL3固件。
(如果客户机确实在EL3启动,那么QEMU假设EL3客户机代码将实现PSCI;在这种情况下,它提供了一些简单的仿真硬件来进行开/关电源操作,并且EL3客户机的PSCI实现将作为其CPU_ON和CPU_OFF调用实现的一部分来操作这些硬件。但这不是你的情况
如果您在EL2的客户端运行一个虚拟机管理程序,那么您的虚拟机管理程序的工作就是为EL1客户端实现PSCI(例如,您不太可能希望允许EL1客户端能够直接关闭管理程序下的CPU)。因此,您希望传递给EL1客户机一个不同的DTB,该DTB描述了EL1客户机对其仿真硬件的视图,并表示"PSCI via hvc"。那么您的管理程序的HVC处理应该模拟PSCI。另外,您的管理程序的启动代码应该使用真正的pci -via- smc来启动辅助cpu,作为其启动序列的一部分。