闡述Linux內(nèi)核里面的APIC編程
微軟操作系統(tǒng)的火熱,你是在應(yīng)用Linux操作系統(tǒng)么?如果你是Linux操作系統(tǒng)的老用戶。 這里為你講解的問題會對Linux內(nèi)核里面的APIC編程有所幫助。Linux內(nèi)核的名字也是“Linux”。APIC就是高級PIC咯,高級可編程中斷控制器?,F(xiàn)在的多核系統(tǒng)上面每個cpu對應(yīng)一個localapic,就是用來管理中斷的,包括外部中斷和cpu內(nèi)部中斷等。
1、apic的具體原理和規(guī)范,可以看“Intel?64andIA-32ArchitecturesSoftwareDeveloper'sManualVolume3A:SystemProgrammingGuide”上的第十章“TheAdvancedProgrammableInterruptController(APIC)“
2、關(guān)于APIC在BIOS里面的初始化,大概是BIOS會初始化好APIC,然后提供一張APIC表cpu表給要啟動的系統(tǒng)使用吧。在ntel?64andIA-32ArchitecturesSoftwareDeveloper'sManualVolume3A:SystemProgrammingGuide的第8章“MULTIPLE-PROCESSORMANAGEMENT”第9章“PROCESSORMANAGEMENTANDINITIALIZATION”有詳細(xì)介紹“”。也可以繼續(xù)看標(biāo)準(zhǔn)文檔“ACPIspec40”“IntelMultiprocessorSpecification”上面關(guān)于那個表的描述。
3、網(wǎng)上國人寫個這篇文章也非常不錯,他整理了上面的文檔和Linux相關(guān)的代碼。我也只是發(fā)現(xiàn)APIC的這個文檔而已,和APIC相關(guān)的文檔還是比較少吧。
“InterruptinLinux(硬件篇)——細(xì)節(jié)、實現(xiàn),與疑問Author:ZX_WING(xing5820@163.com)”
4、內(nèi)核代碼
http://lxr.linux.no/#linux+v2.6.30.5/arch/x86/kernel/apic/apic.c
http://lxr.linux.no/#linux+v2.6.30.5/arch/x86/kernel/mpparse.c
等都是相關(guān)的,可以結(jié)合上面說的那個文檔和系統(tǒng)啟動時的輸出看一下,啟動時輸出的ACPI,apicid,processor那些的都是系統(tǒng)初始化apic的時候打印輸出的。
在內(nèi)核參數(shù)加上apic=debug可能看到更詳細(xì)的輸出。
5、自己的驅(qū)動需要設(shè)置控制apic的時候,也可以使用系統(tǒng)里面定義的那些函數(shù)咯。在這里有很多函數(shù)聲明,也可以去看一下具體是怎么作的
http://lxr.linux.no/#linux+v2.6.30.5/arch/x86/include/asm/apic.h
這里有很多宏的定義,都是和apic的配置有關(guān)的,可以對應(yīng)看一下intel的文檔。
http://lxr.linux.no/#linux+v2.6.30.5/arch/x86/include/asm/apicdef.h
比如KDB就是用ipi(cpu內(nèi)部中斷)的函數(shù)來禁止其他cpu的
void(*send_IPI_allbutself)(intvector);
void(*send_IPI_all)(intvector);
void(*send_IPI_self)(intvector);
而一般的apic都是通過下面這兩個函數(shù)來進(jìn)行的
apic_wait_icr_idle();
apic_write_around(APIC_ICR2,SET_APIC_DEST_FIELD(x86_cpu_to_apicid[i]));
apic_write(APIC_ICR,icr);//寫ICR寄存器,產(chǎn)生ipi中斷
x86_cpu_to_apicid是系統(tǒng)導(dǎo)出的一個獲取物理apicid的變量,不過不同的內(nèi)核版本里面實現(xiàn)有點不同,可以看具體的代碼。apicid是區(qū)分每個apic的標(biāo)志了,也用于區(qū)分不同的processor的。
希望通過本文的介紹你能學(xué)會Linux內(nèi)核里面的APIC編程。
【編輯推薦】