前言

(由于之前的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. Appium的DesiredCapabilities参数设置
  2. hdu 5019 第k大公约数
  3. JS 数组和 Java 数组的区别
  4. UIUC CS241 系统编程中文讲义校对活动 | ApacheCN
  5. FTP测试手机软件画画教程图片,手机绘画SketchBook原创教程
  6. 华为照片在哪个文件夹_华为手机卡顿的罪魁祸首找到了!1秒关闭,手机流畅如丝,多用5年...
  7. 串口接收到的字符型数据如何转化成数字
  8. elasticsearch 7.3使用x-pack kibana登录
  9. 计算机视觉实战(四)图像形态学操作
  10. Linux系统发布ASP.NET项目
  11. godot常用的一些概念、组件(整理于官方教程)
  12. SAP 财务月结之 外币评估(TCODE:FAGL_FC_VAL,S4版本用 FAGL_FCV)<转载>
  13. ultraiso刻录linux系统盘,使用UltraISO在Windows 10下刻录Ubuntu 18.04.2 U盘的方法
  14. 解决PostgreSQL远程访问报错could not connect to server:Connection refused (0x0000274D/10061)
  15. IM互通新方案-GTalk to VoIP回拨服务
  16. 杰理AC6965E开发资料共享
  17. qsort 函数的使用
  18. PC-DMIS 2019示值误差程序MPEE
  19. 2017年总结-我的学习之路
  20. OSGi模块化的守护神,阿里P8都服了

热门文章

  1. 【专栏】国内外物联网平台初探(篇三:QQ物联·智能硬件开放平台)
  2. wlan:11a/11b/11g/11n/11ac
  3. Animated之基础篇-概述
  4. python xlsxwriter不覆盖写入_python学习-xlsxwriter模块
  5. 活动二维码怎么制作?如何将活动内容做成二维码图片?
  6. eplan 电箱布局_Eplan3D布局步骤解密
  7. 直播平台软件开发都使用了什么协议呢?
  8. 安吉通Angton居家养老系统升级项目解决方案
  9. 牛逼了,利用Python实现“天眼系统”,只要照片就能了解个人信息
  10. Resource of computer vision, pattern recognition, machine learning etc.