前言

(由于之前的blog已经关闭了,所以将此文章迁移至这里,并非转载)

本文内容主要翻译自osdev.org,因为当年再此学习了很多东西但是发现在国内很少有中文资料,于是下定决心为国家富强奋斗终身。要是感兴趣也可以看原文“http://wiki.osdev.org/APIC”。要是有一些疑问也可以e-mail,xuezhe.liu@hotmail.com。

APIC全称是”Advanced Programmable Interrupt Controller”(高级可编程中断控制器),是intel对过去PIC(可编程中断控制器)的一个升级版本。它用于多处理系统启动并且是先带Intel(或兼容)处理器中不可分割的一部分,APIC用于将中断重定向,并且用于发送处理器间中断消息(IPI消息)。这些事情在过去的PIC中标准都无法完成。

检测是否支持APIC

查看CPUID.01h:EDX[bit 9]标志位,就可以知道本地的CPU是否有内置的Local APIC了。

Local APIC和IOAPIC

在一个基于APIC的系统中,每一个核心都有一个Local APIC(这个问题由于当年年资料有限,Intel手册里面也没看太懂,争吵了好久。意思是说,有一个4个CPU且每个CPU都开启HT技术的情况下,有8个LocalAPIC,每个核心一个,并且完全独立。)。Local APIC负责处理CPU中特定的中断配置。还有其他事情,它包含了“Local Vector Table(LVT)”负责配置事件中断(例如定时器什么的,定时器就是传说中的APIC Timer)。

具体有关APIC的更多信息,可以参考Intel开发手册。

此外,还有一个CPU外面的IO APIC(例如Intel82093AA)的芯片组,并且提供基于多处理器的中断管理,在多个处理器之间,实现静态或动态的中断触发路由(可以理解为他是一个中断的调度器,他可以决定一个外部中断给不给上面,并且是给哪个CPU)。IO APIC中可以配置外部的每一个中断发送给的CPU以及用什么类型发送过去。

每一个中断针都能指定为边缘触发或电平触发。每个中断也都能制定特定的中断向量以及中断转向信息。通过将IOAPIC的IO空间映射到内存上来访问并操作IOAPIC。为了提高系统的灵活性,一般在分配映射内存时,内存分配的地址是可以变的,但是一般默认都分配到了0xFEC00000上。

Intel有关APIC的手册可以从Intel的网站上下载到。分类名是”Multiprocessor Specification”。或者是直接点这个链接下载(我不保证若干年之内还有效)。

处理器间中断(IPI)

Inter-Processor Interrupts(IPIs)是一种由Local APIC触发的中断,一般可以用于多CPU间调度之类的使用(简单的说就是一个CPU触发另外的或本身的或所有的CPU进入一个中断),CPU的启动引导序列也要用到这个(就是传说中的INIT-SIPI-SIPI)。还有其他功能,etc。

Local APIC配置方法

Local APIC在启动的时候开启(他是什么说,但是我发现我引导CPU后,APIC默认是不时能的,一定要自己开开一下,否则APICTImer不好用的。)并且如果要是想给禁用的话,配置IA32_APIC_BASE的MSR(Model Specific Register)。然后CPU接受中断,直接采用8259的兼容PIC模式。Intel手册中说明,但凡你给关了,你就不能给开开了,只能靠重置CPU。

想要开启Local APIC接收中断,则需要设置Spurious Interrupt Vector Register的第8位即可。

IO APIC可以被设置成兼容模式(就像是模拟8259一样)。

Local APIC的寄存器被映射到物理内存上,一般是0xFEE00XXX这种。其实这个地址可以被修改,在MSR中指定了实际的APIC基址。我们可以通过这一机制去移动他的基址。(网上说你不能移动到任何地方,例如大于4GB的地方。)

下面的代码用于访问APIC。

#define IA32_APIC_BASE_MSR 0x1B
#define IA32_APIC_BASE_MSR_ENABLE 0x800/** returns a 'true' value if the CPU supports APIC*  and if the local APIC hasn't been disabled in MSRs*  note that this requires CPUID to be supported.*/
bool cpuHasAPIC()
{uint32_t eax, edx;cpuid(1, &eax, &edx);
   return edx & CPUID_FLAG_APIC;
}/* Set the physical address for local APIC registers */
void cpuSetAPICBase(uintptr_t apic)
{uint32_t edx = 0;uint32_t eax = (apic & 0xfffff000) | IA32_APIC_BASE_MSR_ENABLE;#ifdef __PHYSICAL_MEMORY_EXTENSION__edx = (apic >> 32) & 0x0f;
#endifcpuSetMSR(IA32_APIC_BASE_MSR, eax, edx);
}/*** Get the physical address of the APIC registers page* make sure you map it to virtual memory ;)*/
uintptr_t cpuGetAPICBase()
{uint32_t eax, edx;cpuGetMSR(IA32_APIC_BASE_MSR, &eax, &edx);#ifdef __PHYSICAL_MEMORY_EXTENSION__
   return (eax & 0xfffff000) | ((edx & 0x0f) << 32);
#else
   return (eax & 0xfffff000);
#endif
}void enableAPIC()
{/* Hardware enable the Local APIC if it wasn't enabled */cpuSetAPICBase(cpuGetAPICBase());/* Set the Spourious Interrupt Vector Register bit 8 to start receiving interrupts */WriteRegister(0xF0, ReadRegister(0xF0) | 0x100);
}

IO APIC配置方法

IO APIC使用两个寄存器完成他的所有操作。一个叫做地址寄存器地址在IOAPICBASE+0,一个叫做数据寄存器地址在IOAPICBASE+0x10(如果愿意的话也可以叫做窗口寄存器和数据寄存器)。注意,一个操作必须使用双字进行操作。地址寄存器中,使用低8位来设置选择要写哪个地方。下面是访问的一个代码示例,大家可以参考下原理并且直接复制用就行了。

uint32_t cpuReadIoApic(void *ioapicaddr, uint32_t reg)
{uint32_t volatile *ioapic = (uint32_t volatile *)ioapicaddr;ioapic[0] = (reg & 0xff);return ioapic[4];
}void cpuWriteIoApic(void *ioapicaddr, uint32_t reg, uint32_t value)
{uint32_t volatile *ioapic = (uint32_t volatile *)ioapicaddr;ioapic[0] = (reg & 0xff);ioapic[4] = value;
}

对于APIC的一些资料相关推荐

  1. 有关与windows的一些资料以及链接(一)

    编写PC操作系统的参考资料 编译器等工具 汇编语言: MASM 6.11,MASM 11(Windows):http://www.masm32.com/ FASM(跨平台):http://flatas ...

  2. 再谈中断机制(APIC)

    中断是硬件和软件交互的一种机制,可以说整个操作系统,整个架构都是由中断来驱动的.一个中断的起末会经历设备,中断控制器,CPU 三个阶段:设备产生中断信号,中断控制器翻译信号,CPU 来实际处理信号. ...

  3. APIC Timer

    前言 (由于之前的blog已经关闭了,所以将此文章迁移至这里,并非转载) 之前已经大体的写过APIC的一些内容,这次是写一些APIC定时器的内容,当然,也是翻译了一些来自OSDev的资料(不要问我为什 ...

  4. Virtualbox源码分析16 APIC虚拟化1 APIC概念和初始化

    文章目录 中断是什么 中断是如何被发送给CPU的 16.1 xAPIC and x2APIC 16.2 Local APIC Page里的寄存器和对应的重要概念 APIC ID 中断优先级类型的寄存器 ...

  5. 安装linux系统提示acpi,安装Linux系统时的ACPI和APIC问题

    安装Linux系统时的ACPI和APIC问题 在开始安装Linux系统时,经常会遇到关于ACPI和APIC的各种提示,然后安装被停止.这是由于这两项功能和Linux不太兼容. 解决办法是,在光盘刚启动 ...

  6. 客户资料查询传递数据格式

    客户资料查询传递数据格式 大家好! 客户资料查询字段JSON格式如下(附件为数据文件): [ { "colName":"CUSTTEL", "colT ...

  7. 隔年增长的题_行测资料分析:一起聊聊隔年增长

    隔年增长在行测资料分析考试中属于一种高频考点,但同时在很多考生看来也是一个难点.之所以觉得它是难点,那是因为在隔年增长考查中,很多考生觉得无论是列式还是运算相对都比较难.这样让有些甚至对于公式都不熟悉 ...

  8. GitHub:TensorFlow、PyTorch最全资料集锦

    给各位小伙伴们推出几个深度学习框架的资料集锦,统一命名为:XXX-From-Zero-To-One.下面po一幅深度学习框架发展的重要历史点: 从上图可知,TensorFlow和PyTorch是目前深 ...

  9. 【camera】自动泊车-视觉车位检测相关资料汇总(论文、数据集、源代码、相关博客、演示demo)(1)

    [camera]自动泊车-视觉车位检测相关资料汇总(论文.数据集.源代码.相关博客.演示demo)parking slot detection 论文 2020论文 2019论文 2018论文 2017 ...

最新文章

  1. 【 C 】回调函数简记
  2. 履约时间预估:如何让外卖更快送达?
  3. sqlserver操作geography方法
  4. 在伦敦逛菜市场_我在伦敦进行岗后求职的经验教训
  5. ubuntu16.04安装lua环境
  6. 聚合maven+spring-boot打包可执行jar
  7. 用MediaCreationTool做纯净版Windows 10系统U盘
  8. Heat Map在生物信息学中的应用
  9. 用python爬取链家的租房信息
  10. LabelImg 标注 yolo 数据 环境配置和预制标签 predefined_classes.txt 的使用 详解
  11. 微信公众号数据2019_全国公众号总排名2019,全国微信公众号排名
  12. RK3288方案开发,RK3288开发板方案,RK3288平板芯片参数资料
  13. check the manual that corresponds to your MySQL server version for the right syntax to use near
  14. 修改KindEditor上传图片数量和大小
  15. 【机器学习笔记7】决策树原理及应用
  16. 为何计算机科学领域的女性不多
  17. 【推荐架构day5】今日头条算法的基本原理
  18. c++:利用socket基于TPC/IP实现通信 在线聊天
  19. 疫情对经济与IT的影响
  20. Unity3d办公场景灯光布设与光影烘焙及后处理【2020】

热门文章

  1. cad文件默认打开程序改为acad程序
  2. 微信小程序文本输入<textarea/> 详解
  3. 分享量化交易接口之网格交易的选股策略
  4. maya刷权重时有个叉_为什么maya刷权重 笔刷是打叉
  5. Jenkins 更新网站静态文件
  6. 我不要你觉得交易中的十大常见问题解析
  7. 复习专栏之---设计模式(java)
  8. windows 防火墙解除或禁止ping方法
  9. (转)卡马克卷轴算法研究
  10. 关于__declspect(dllexport) 和 __declspec(dllimport)的使用