对称多处理器和处理器间中断是什么我这里就不解释了,网络上这部分内容比较多,随便一百度就有很多中文资料,我们来看一下他们是怎么实现的。
另外本文假定你已经具有了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; /*BIOS read-only area.*/
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; /*Maybe EBDA doesn't exist.*/
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 find ACPI.\n");
return -1;
}找到RSDP就调用parseRSDP分析.
ACPI的RS

本文详细介绍了对称多处理器系统中处理器启动和处理器间中断的实现过程,涉及中断命令寄存器(ICR)、Local APIC、ACPI的使用,以及启动CPU和发送处理器间中断的具体步骤。通过设置ICR的参数,如Delivery Mode、Trigger Mode和Destination Field,可以实现对其他CPU的初始化和启动,并发送StartUp指令进入指定物理地址执行。
最低0.47元/天 解锁文章
839

被折叠的 条评论
为什么被折叠?



