对称多处理器和处理器间中断是什么我这里就不解释了,网络上这部分内容比较多,随便一百度就有很多中文资料,我们来看一下他们是怎么实现的。
另外本文假定你已经具有了Local APIC的基础知识,至少要知道怎么写APIC的寄存器吧.
中断命令寄存器
要启动"主"处理器之外的任何一个处理器(事实上,处理器没有主次之分,除了启动之外),或者要发送一个处理器间中断,离不开的一个Local Apic寄存器就是中断命令寄存器(Interrupt Command Register,ICR).
这就是ICR的结构图,地址是0x310(高32位),0x300(低32位),比较重要的是最高8位存放的是LocalApicID,INIT,StartUp,NMI,最低8位存放的Vector
(有时候不是这样的,这里指的是本文用到的模式.)
获取处理器的个数和每个处理器的LocalApicID
如何获取一共有几个CPU和每个CPU的LocalApicID?这显然是要启动一个"次"CPU首先要面对的问题.
这个问题我们要用到ACPI(不是APIC,高级配置和电源管理接口)
寻找ACPI可以这样写:
int initACPI(void)
{
u8 *start = (u8 *)0xe0000;
u8 * const end = (u8 *)0xfffff;
while(start < end){
u64 signature = *(u64 *)start;
if(signature == *(const u64 *)"RSD PTR ")
{
if(parseRSDP(start) == 0)
{
return 0;
}
}
start += 0x10;
}
u8 *ebda = (u8 *)(pointer)((*((u16 *)0x40E))*0x10);
if(ebda != (u8 *)0x9FC00)
return -1;
u8 * const ebdaEnd = ebda + 0x3FF;
while(ebda < ebdaEnd){
u64 signature = *(u64 *)ebda;
if(signature == *(const u64 *)"RSD PTR ")
{
if(parseRSDP(ebda) == 0)
{
return 0;
}
}
}
printkInColor(0xff,0x00,0x00,"Can't fi