版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
中斷處(0x2A-0x2E5個(gè)系統(tǒng)預(yù)的中斷向量,0x2A:KiGetTickCount,0x2B:KiCallbaclReturn0x2C:KiRaiseAssertion,0x2D:KiDebugService,0x2E:KiSystemService)硬:最后的表項(xiàng)供驅(qū)動(dòng)程序硬件中斷使用和自定義其他軟中斷使用(0x30-0xFF)linux等其他系統(tǒng)是怎么劃分這塊號(hào)段的,不管,我們只看Windows的情況為什么釣是在這段范圍內(nèi)搜索空白表項(xiàng)了(其實(shí)我們也完全可以從0x14開始搜索) IRQ2>8259A 一個(gè)IRQ,進(jìn)而,多個(gè)設(shè)備可以分配同一個(gè)中斷號(hào)。因此,一個(gè)中斷號(hào)可以共享給多個(gè)設(shè)備同時(shí)使用。IRP_MN_QUERY_RESOURCE_REQUIREMENTS,查詢得到初步的資源需求。然后,pnp管理器會(huì)找到相應(yīng)的硬件IRP_MN_FILTER_RESOURCE_REQUIREMENTS(功能驅(qū)動(dòng)此時(shí)可以處理這個(gè)irp,修改資源需求),當(dāng)確定好最終的資源需求后,系統(tǒng)就協(xié)調(diào)分配端、中斷號(hào)、DIRQLIRP_MN_START_DEVICEIoConnectInterrupt(OUTPKINTERRUPT*InterruptObject,//返回創(chuàng)建的中斷對(duì)象(一般是一個(gè)數(shù)組)INPKSERVICE_ROUTINEServiceRoutine,//我們的isr(ourisr)INPVOIDServiceContext,//isrINPKSPIN_LOCKSpinLock,//我們isr的自旋鎖,用于多cpu互斥(一般傳NULL即可)INULONGVector,//分配到的中斷號(hào)INKIRQLIrql,//isr對(duì)應(yīng)的INKINTERRUPT_MODEInterruptMode,//表示是否允許執(zhí)行本中斷的下一個(gè)中斷INBOOLEANShareVector,//表示本中斷對(duì)象是否想要共享中斷號(hào)以及是否允許共享INKAFFINITYProcessorEnableMask,//本isr的cpu親緣性,一般全部cpu都親緣。INBOOLEANFloatingSave)//一般為FALSE{PKINTERRUPTPKINTERRUPTInterruptUsed;//當(dāng)前的中斷對(duì)象PKSPIN_LOCKSpinLockUsed;//實(shí)際使用的自旋鎖BOOLEANFirstRun;CCHARCount0;//cpu*InterruptObject=AffinityProcessorEnableMask&KeActiveProcessors;//本isr的cpu親緣性與實(shí)有cpu的交集while(Affinity){if(Affinity&1)Count++;Affinity>>=1;}if(!Count)returnSTATUS_INVALID_PARAMETER;IoInterrupt=ExAllocatePoolWithTag(NonPagedPool,(Count-1)*sizeof(KINTERRUPT)if(!IoInterrupt)return*InterruptObject=&IoInterrupt-SpinLockUsed=SpinLock?SpinLock:&IoInterrupt->SpinLock;Interrupt(PKINTERRUPT)(IoInterrupt1);//后面的中斷對(duì)象數(shù)組地址FirstRun=TRUE;RtlZeroMemory(IoInterrupt,sizeof(IO_INTERRUPT));Affinity=ProcessorEnableMask&KeActiveProcessors;for(Count0;Affinity;CountAffinity1)Count其實(shí)表示cpu{if(Affinity&{InterruptUsed=FirstRun?&IoInterrupt->FirstInterrupt:{//ififreturn}ifFirstRun=Else//記錄各cpu的那個(gè)中斷號(hào)上掛接的中斷對(duì)象地址}}return}如上,這個(gè)函數(shù)用來將指定isr掛接到各個(gè)cpu的指定中斷號(hào)上。因?yàn)樵诙郼pu系統(tǒng)中,一個(gè)設(shè)備可以向每個(gè)cpu都發(fā)出中斷,因此,必須在每個(gè)cpu的IDT中都要掛接登記那個(gè)中斷的isr。具體是怎么掛接的呢?這個(gè)函數(shù)會(huì)創(chuàng)建一個(gè)中斷對(duì)象數(shù)組,然后將各個(gè)中斷對(duì)象對(duì)應(yīng)掛接到各cpu的同一中斷號(hào)上。由于老式機(jī)器是單cpu的,因此,早期的中斷對(duì)象結(jié)構(gòu)IO_INTERRUPT就包含一個(gè)中斷對(duì)象任意,后來的機(jī)器對(duì)其進(jìn)行了擴(kuò)展,在這個(gè)結(jié)構(gòu)后面是一個(gè)中斷對(duì)象數(shù)組,用來掛接到其他cpu上。typedefstruct{PKINTERRUPTInterrupt[UM_PROCESSORS];//記錄各cpu上掛接的中斷對(duì)象地址}IO_INTERRUPT,typedefstruct_KINTERRUPT{CSHORTCSHORTLIST_ENTRYInterruptListEntry;//用來掛入中斷對(duì)象鏈表PVOIDServiceContext;//isr參數(shù)ULONGTickCount;//沒用PKSPIN_LOCKActualLock;//我們isr實(shí)際使用的自旋鎖PKINTERRUPT_ROUTINEDispatchAddress;//中間的Dispatchisr函數(shù)地址CCHARNumber;//要掛往的目標(biāo)cpuKIRQLIrql;//isr對(duì)應(yīng)的isrBOOLEANFloatingSave;//一般為FALSEKINTERRUPT_MODEMode;//是否允許繼續(xù)執(zhí)行本中斷對(duì)象后面的中斷對(duì)象的isrULONGServiceCount;//沒用ULONGDispatchCode[DISPATCH_LENGTH];//這不是數(shù)組,而是一段代碼,表示本中斷對(duì)象的模板}KeInitializeInterrupt(INPKINTERRUPTINPKSERVICE_ROUTINEServiceRoutine,INPVOIDServiceContext,INPKSPIN_LOCKSpinLock,INULONGVector,INKIRQLIrql,INKIRQLSynchronizeIrql,INKINTERRUPT_MODEINBOOLEANShareVector,INCHARProcessorNumber,INBOOLEAN{ULONGPULONGDispatchCode&Interrupt->DispatchCode[0],PatchDispatchCode;//patch表示補(bǔ)丁處Interrupt->Type=InterruptObject;Interrupt->Size=if(SpinLock)//由于這個(gè)函數(shù)未導(dǎo)出,由系統(tǒng)內(nèi)部調(diào)用,傳的SpinLock參數(shù)很少為NULLInterrupt->ActualLockSpinLock;//使用頭部中公共的自旋鎖或者我們提供的自旋鎖{}
Interrupt->ActualLock=&Interrupt->SpinLock;Interrupt->ServiceRoutine=ServiceRoutine;Interrupt->ServiceContext=ServiceContext;Interrupt->Vector=Vector;Interrupt->Irql=Interrupt->SynchronizeIrql=SynchronizeIrql;Interrupt->Mode=InterruptMode;Interrupt->ShareVector=ShareVector;Interrupt->Number=ProcessorNumber;Interrupt->FloatingSave=FloatingSave;Interrupt->TickCount=MAXULONG;Interrupt->DispatchCount=MAXULONG;for(i0;iDISPATCH_LENGTH;*DispatchCode++=Patch=(PULONG)((ULONG)Patch+((ULONG)&KiInterruptTemplateObject-4-*PatchPtrToUlong(Interrupt);//也即將原movedx,0movedx,本中斷對(duì)象的地址Interrupt->Connected=FALSE;//尚未掛入}KiEnterTrapmovedx,0//這條指令的操作數(shù)0將態(tài)修改成具體中斷對(duì)象的地moveax,offset@KiInterruptTemplateHandler@8//KiInterruptTemplateHandler函數(shù)jmpeaxBOOLEAN//返回值表示是否掛接成功KeConnectInterrupt(INPKINTERRUPTInterrupt){BOOLEANConnected,Error,Status;KIRQLIrql,OldIrql;UCHARULONGDISPATCH_INFONumber=Interrupt->Number;//目標(biāo)cpuVectorInterrupt->Vector;//目標(biāo)中斷號(hào)Irql=Interrupt->Irql;SynchronizeIrqlif((Irql>HIGH_LEVEL)||(Number>=KeNumberProcessors)||(Interrupt->SynchronizeIrql<Irql)||(Interrupt->FloatingSave)){return}Connected=Error=KeSetSystemAffinityThread(1Number);//改變當(dāng)前線程的cpu親緣性先,挪到目標(biāo)cpuOldIrql=KiAcquireDispatcherLock();if(!Interrupt->Connected)//if尚未掛接{KiGetVectorDispatch(Vector,&Dispatch);if(Dispatch.TypeNoConnect{Interrupt->Connected=Connected=TRUE;KiConnectVectorToInterrupt(Interrupt,StatusHalEnableSystemInterrupt(Vector,Irql,Interrupt->Mode);//APIC相關(guān)if(!Status)Error=TRUE;}elseif((Dispatch.Type!=UnknownConnect)&&//已掛接有中斷對(duì)象(Interrupt->ShareVector)&& (Dispatch.Interrupt->ShareVector)&&(Dispatch.Interrupt->Mode==Interrupt->Mode)){Interrupt->Connected=Connected=if(Dispatch.Type!={ASSERT(Dispatch.Interrupt->Mode!=Latched);}}}if((Connected)&&(Error)){Connected=}return}VOIDKiGetVectorDispatch(INULONGVector,INPDISPATCH_INFO{PKINTERRUPT_ROUTINEPVOIDUCHARUCHAREntryHalVectorToIDTEntry(Vector);//這個(gè)宏將中斷向量號(hào)轉(zhuǎn)換為IDT表項(xiàng)索引(一般相同Dispatch->NoDispatch=(PVOID)(((ULONG_PTR)&KiStartUnexpectedRange)(Entry–0x30)*KiUnexpectedEntrySize);Dispatch->FloatingDispatch=NULL;//尚不支持Dispatch->FlatDispatch=NULL;CurrentKeQueryInterruptHandler(Vector);//獲得這個(gè)中斷向量處當(dāng)前存放的isrif((PKINTERRUPT_ROUTINE)Current==Dispatch-{}{
Dispatch->InterruptNULL;//表示尚未掛接有任何中斷對(duì)象Dispatch->Interrupt=CONTAINING_RECORD(Current,KINTERRUPT,DispatchCode);Handler=Dispatch->Interrupt->DispatchAddress;if(Handler==Dispatch-Dispatch->Type=ChainConnect;//上次的中斷對(duì)象是以方式掛上去elseif((Handler==Dispatch->InterruptDispatch)||(Handler==Dispatch->FloatingDispatch)){}
==}}是個(gè)用戶自定義的isr,也可能沒有isr(即以KiUnexpectedInterruptN函數(shù)占位)。KeQueryInterruptHandler(INULONG{PKIPCRPcr=UCHAREntry=return(PVOID)(((Pcr->IDT[Entry].ExtendedOffset<<16)&0xFFFF0000)|(Pcr->IDT[Entry].Offset&0xFFFF));}VOIDKiConnectVectorToInterrupt(INPKINTERRUPTInterrupt,INCONNECT_TYPEType{DISPATCH_INFOKiGetVectorDispatch(Interrupt->Vector,&Dispatch);if(TypeNoConnect)//if用戶要撤銷掛接Handler=Dispatch.NoDispatch;{//填好本中斷對(duì)象的dispatchInterrupt->DispatchAddress=(Type==NormalConnect)?Handler=(PVOID)&Interrupt->DispatchCode;//本中斷對(duì)象的模板isr}KeRegisterInterruptHandler(Interrupt->Vector,Handler);}VOIDKeRegisterInterruptHandler(INULONGVector,INPVOID{UCHARULONG_PTRPKIPCRPcr=Entry=Address=Pcr->IDT[Entry].ExtendedOffset=(USHORT)(Address>>16);Pcr->IDT[Entry].Offset=(USHORT)Address;}的,那么這些中斷對(duì)象將組成一個(gè)鏈表。這樣,當(dāng)cpuIDTVOIDKiInterruptTemplateHandler(INPKTRAP_FRAMETrapFrame,INPKINTERRUPTInterrupt){,}isr都是KiChainedDispatch,反之則是KiInterruptDispatch。我們看:VOIDKiChainedDispatch(INPKTRAP_FRAMETrapFrame,INPKINTERRUPT{KIRQLBOOLEANPLIST_ENTRYNextEntry,ListHead;({ListHead=&Interrupt->InterruptListEntry;NextEntry=ListHead;{if(Interrupt->SynchronizeIrqlInterrupt->Irql)//再次提升irqlOldIrql=KfRaiseIrql(Interrupt->SynchronizeIrql);Handled=Interrupt->ServiceRoutine(Interrupt,Interrupt->ServiceContext);if(Interrupt->SynchronizeIrql>Interrupt->Irql)if((Handled)&&(Interrupt->Mode==LevelSensitive))break;NextEntry=NextEntry->Flink;if(NextEntryListHead)//if{if(Interrupt->Mode==LevelSensitive)if(!Handled)break;//if}Interrupt=CONTAINING_RECORD(NextEntry,KINTERRUPT,}KiExitInterrupt(TrapFrame,OldIrql,}Else//清理中斷Trap幀,恢復(fù)中斷現(xiàn)場(chǎng),回到原斷點(diǎn)處繼續(xù)執(zhí)行KiExitInterrupt(TrapFrame,OldIrql,TRUE);}BOOLEANInterruptService(instruct_KINTERRUPT*Interrupt,inPVOIDServiceContexTRUE。否則應(yīng)返回FALSE,讓系統(tǒng)繼續(xù)尋找中斷對(duì)象鏈表中的下一個(gè)中斷對(duì)象去認(rèn)領(lǐng)。VOIDFASTCALLKiInterruptDispatch(INPKTRAP_FRAMETrapFrame,INPKINTERRUPT{KIRQL{}}
KiExitInterrupt(TrapFrame,OldIrql,FALSE);KiExitInterrupt(TrapFrame,OldIrql,r后,就返回了,不會(huì)有在鏈表中查找的過程。VOIDIoDisconnectInterrupt(PKINTERRUPT{LONGIoInterruptCONTAINING_RECORD(InterruptObject,IO_INTERRUPT,FirstInterrupt);for(i=0;i<KeNumberProcessors;i++)//撤銷其它中斷對(duì)象的掛接{if(IoInterrupt->Interrupt[i])}}BOOLEANKeDisconnectInterrupt(INPKINTERRUPT{KIRQLOldIrql,Irql;ULONGVector;DISPATCH_INFODispatch;BOOLEANState;KeSetSystemAffinityThread(1<<Interrupt->Number);OldIrql=KiAcquireDispatcherLock();State=Interrupt->Connected;if(State){Irql=Interrupt->Irql;Vector=Interrupt->Vector;if(Dispatch.Type==ChainConnect){ASSERT(Irql<=if(InterruptDispatch.Interrupt)//if{Dispatch.Interrupt=CONTAINING_RECORD(Dispatch.Interrupt->}NextInterrupt=CONTAINING_RECORD(Dispatch.Interrupt-if(Dispatch.InterruptNextInterrupt)//也即if{,}}//{HalDisableSystemInterrupt(Interrupt->Vector,Irql);}Interrupt->Connected=}returnState;}三層。第一層是中斷對(duì)象的模板isr,第二層是中斷對(duì)象的dispatchisr,第三層才是用戶自己提供的isrisr。因此,也可以說,我們提供的那個(gè)isrIDTisrisr。當(dāng)然,程序員,也可以IDT中的表項(xiàng),改成自己的isr,這就是所謂的isrhook(注意要進(jìn)行isrhook的話,必須每個(gè)cpu都要hook)最后我們看一下典型的系統(tǒng)時(shí)鐘中斷是怎么處理的。系統(tǒng)每隔10ms產(chǎn)生一次時(shí)鐘中斷,時(shí)鐘中斷的IRQ固定是0,中斷號(hào)默認(rèn)映射到0x30,時(shí)鐘中斷的isr最終進(jìn)入下面的函數(shù)。VOIDHalpClockInterruptHandler(INPKTRAP_FRAME{KIRQLIrql;ifHalBeginSystemInterrupt(CLOCK2_LEVEL,0x30,&Irql))//0x30{/*Updatetheperformancecounter*/HalpPerfCounter.QuadPart+=HalpCurrentRollOver;HalpPerfCounterCutoff=KiEnableTimerWatchdog;}}VOIDKeUpdateSystemTime(INPKTRAP_FRAMETrapFrame,INULONGIncrement,INKIRQL{PKPRCBPrcb=KeGetCurrentPrcb();ULARGE_INTEGERCurrentTime,InterruptTime;ULONGHand,OldTickCount;InterruptTime.HighPartSharedUserData->InterruptTime.High1Time;InterruptTime.Lort=SharedUserData->InterruptTime.Lort;InterruptTime.QuadPart+=Increment;//Increment一般為10msSharedUserData->InterruptTime.High1TimeInterruptTime.HighPart;SharedUserData->InterruptTime.Lort=InterruptTime.Lort;SharedUserData->InterruptTime.High2TimeInterruptTime.HighPart;OldTickCount=KeTickCount.Lort;/*Checkfor pletetick*/if(KiTickOffset<=0){CurrentTime.HighPart=SharedUserData->SystemTime.High1Time;CurrentTime.Lort=SharedUserData->SystemTime.Lort;CurrentTime.QuadPart+=KeTimeAdjustment;SharedUserDa
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年湖北電力建設(shè)第一工程公司招聘筆試參考題庫含答案解析
- 2025年度個(gè)人信用擔(dān)保裝修借款合同范本3篇
- 2025年個(gè)人金融理財(cái)產(chǎn)品投資合同4篇
- 2025年度油氣輸送鋼管租賃合作合同2篇
- 2025年度個(gè)人農(nóng)田科技種植項(xiàng)目合作協(xié)議4篇
- 2025版二手房免稅托管與租賃一體化服務(wù)合同
- 2025版協(xié)議離婚全程法律服務(wù)及婚姻財(cái)產(chǎn)分割合同3篇
- 2025年度二零二五年度鋼廠廢鋼再生產(chǎn)品銷售合同2篇
- 2025版新能源電池生產(chǎn)承包經(jīng)營合同示范文本3篇
- 2025-2030全球叉車機(jī)器人行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 春節(jié)拜年的由來習(xí)俗來歷故事
- 2023年河北省中考數(shù)學(xué)試卷(含解析)
- 通信電子線路(哈爾濱工程大學(xué))智慧樹知到課后章節(jié)答案2023年下哈爾濱工程大學(xué)
- 《公路勘測(cè)細(xì)則》(C10-2007 )【可編輯】
- 皮膚惡性黑色素瘤-疾病研究白皮書
- 從心理學(xué)看現(xiàn)代家庭教育課件
- C語言程序設(shè)計(jì)PPT(第7版)高職完整全套教學(xué)課件
- 頭頸外科臨床診療指南2021版
- 大國重器北斗系統(tǒng)
- 網(wǎng)球運(yùn)動(dòng)知識(shí)教育PPT模板
- 防火墻漏洞掃描基礎(chǔ)知識(shí)
評(píng)論
0/150
提交評(píng)論