X86 QEMU中的本地APIC地址在哪里?

X86 QEMU中的本地APIC地址在哪里?,x86,qemu,X86,Qemu,根据英特尔的文档,FEE0 0000H到FEE0 03F0H是本地APIC的范围。但是,从QEMU控制台检查,我只能在那里找到值0: (qemu) x/128b 0xfee00000 fee00000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 fee00008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 fee00010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 fee00018

根据英特尔的文档,
FEE0 0000H
FEE0 03F0H
是本地APIC的范围。但是,从QEMU控制台检查,我只能在那里找到值0:

(qemu) x/128b 0xfee00000
fee00000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00018: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00020: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00028: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00030: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00038: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00040: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00048: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00050: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00058: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00060: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00068: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00070: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
fee00078: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
我检查了128个字节以查看是否有任何不同于0的内容。至少,
FEE0 0030H
应包含不同的值,因为它是APIC版本所在的位置

分页被禁用,因此没有虚拟内存;只是身体上:

(qemu) info mem
PG disabled
但是,
info-lapic
命令报告实际初始值:

(qemu) info lapic 
dumping local APIC state for CPU 0 

LVT0     0x00008700 active-hi level                             ExtINT (vec 0)
LVT1     0x00008400 active-hi level                             NMI   
LVTPC    0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTERR   0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTTHMR  0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTT     0x00030010 active-hi edge  masked         periodic     Fixed  (vec 16)
Timer    DCR=0x2 (divide by 8) initial_count = 4096
SPIV     0x000001ff APIC enabled, focus=off, spurious vec 255
ICR  0x000c4610 physical edge assert all
ICR2     0x00000000
ESR  0x00000000
ISR  (none)
IRR  (none)

那么,这些值在哪里呢?

模拟设备。当vCPU读取或写入这些地址时,它们由模拟APIC处理。当GDB/QEMU控制台执行此操作时,它可能不会通过该仿真器进行路由(模拟读取可以更改状态)。很可能,gdb/QEMU控制台只是被路由到QEMU的RAM表示,其中不包括APIC。

默认值为FEE0 0000H到FEE0 03F0H,但它占据了整个4KB页面。前16个字节保留给APIC ID为0的内核的MSI中断(如果它位于MSI范围内,这是必需的)。其他255个内核的MSI中断位于页面边界的开始处,每个页面1个,直到并包括FEEF F000H。LAPIC可以在每个逻辑核上进行调整,因为每个逻辑核都有一个

x
检查虚拟内存,本地APIC的寄存器映射到物理页FEE00xxx。这是一个非常简单的引导加载程序,只启用了保护模式,但禁用了分页。还没有虚拟内存。在已经给出的答案之上,您应该能够通过将
0x1b
加载到ECX并使用
rdmsr
指令,在硬件/模拟器(包括QEMU)上找到APIC内置的APIC基址。基址应该是EDX:EAX。我不知道您使用的是用户空间QEMU还是QEMU-KVM。两者都有APIC的表示形式,您可以通过一些黑客手段使控制台访问APIC。可能有点痛。更懒惰的选择是从来宾内部打印它。我使用用户空间QEMU,使用标准命令行启动q35机器和QEMU cpu。我不确定当分页被禁用时,地址基
0xfee00
是否适用,因为我的虚拟机只有256 MB的RAM。我试图用
wrmsr
指令将基址重新映射到任意随机地址,再映射到MSR寄存器
0x1b
。它确实会更改值,但当我写入新地址时。例如
0x14
是新的基址,因此写入
0x14380
应该会更改初始计时器计数。然而,即使在编写之后,我发现
info-lapic
命令的输出仍然是相同的。基址最初是0xfee00000,而不考虑分页(它是一个物理地址)。我知道现代KVM拒绝移动APIC base,但我不确定QEMU的完整用户空间行为。当我说基址是
0xfee00
时,我实际上引用了
IA32_APIC_base
MSR中的值,值
0xfee00
位于最高位(位置12-31)。该值将扩展为0xfee00000,并添加到特定APIC特征的偏移量中。我询问了
qemu讨论
列表,似乎读取模拟内存对获取正确的值没有影响。确实,从qemu和GDB读取的内存不会从本地APIC检索值。我试着写默认地址,实际上LAPIC改变了它的值。