【问题标题】:Local APIC registers mapped in memory contain just 1's映射到内存中的本地 APIC 寄存器只包含 1
【发布时间】:2017-11-13 10:37:29
【问题描述】:

我正在尝试为可以在 x86 上读取和写入本地 APIC 的 Linux 内核模块编写一些代码。我正在使用下面的代码 sn-p 从中断命令寄存器中读取:

printk(KERN_ERR "APIC %p %d", (int32_t *)(APIC_BASE + 0x300), 
                              *(volatile int32_t *)(APIC_BASE + 0x300));

这是输出,永远不会改变:

APIC ffffffffff5f5300 -1

由于我要打印一个带符号的 32 位整数,-1 表示我读取的 32 位都是 1。这是出乎意料的,因为(据我所知)第 11 位(目标模式位)需要为 0,然后我才能写入本地 APIC 以发送 IPI。

我做错了什么吗?我需要采取任何初始化步骤吗?

【问题讨论】:

  • 需要检查的几件事:APIC_BASE 是否正确? APIC 区域是否已映射?是否启用了 x2APIC ? (IA32_APIC_BASE 的第 10 位应为 0)。请注意,目标模式位(ICR 的第 11 位)不是待处理 IPI(第 12 位,交付状态)的指示符。
  • @MargaretBloom 嗨,玛格丽特 - 非常感谢您的评论。实际上,计算机似乎确实具有 x2APIC,因此我正在研究编写 APIC 代码以使用 MSR 而不是内存映射寄存器。完成后我会发布更新。谢谢!

标签: c linux linux-kernel x86


【解决方案1】:

事实证明,我的计算机配备了更新的 x2APIC,而不是 xAPIC。 x2APIC 使用 MSR 发送 IPI,而不是 xAPIC 使用的内存映射寄存器。因此,我在APIC_BASE 读取的内存并不代表本地 APIC 的状态。

我将重写我的代码以使用 MSR,但我能够通过将我的 x2APIC 设置为使用 xAPIC 的接口(即改用内存映射寄存器)来测试我现有的代码。这可以通过设置nox2apic 内核参数来完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    相关资源
    最近更新 更多