




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
中断处(0x2A-0x2E5个系统预的中断向量,0x2A:KiGetTickCount,0x2B:KiCallbaclReturn0x2C:KiRaiseAssertion,0x2D:KiDebugService,0x2E:KiSystemService)硬:最后的表项供驱动程序硬件中断使用和自定义其他软中断使用(0x30-0xFF)linux等其他系统是怎么划分这块号段的,不管,我们只看Windows的情况为什么钓是在这段范围内搜索空白表项了(其实我们也完全可以从0x14开始搜索) IRQ2>8259A 一个IRQ,进而,多个设备可以分配同一个中断号。因此,一个中断号可以共享给多个设备同时使用。IRP_MN_QUERY_RESOURCE_REQUIREMENTS,查询得到初步的资源需求。然后,pnp管理器会找到相应的硬件IRP_MN_FILTER_RESOURCE_REQUIREMENTS(功能驱动此时可以处理这个irp,修改资源需求),当确定好最终的资源需求后,系统就协调分配端、中断号、DIRQLIRP_MN_START_DEVICEIoConnectInterrupt(OUTPKINTERRUPT*InterruptObject,//返回创建的中断对象(一般是一个数组)INPKSERVICE_ROUTINEServiceRoutine,//我们的isr(ourisr)INPVOIDServiceContext,//isrINPKSPIN_LOCKSpinLock,//我们isr的自旋锁,用于多cpu互斥(一般传NULL即可)INULONGVector,//分配到的中断号INKIRQLIrql,//isr对应的INKINTERRUPT_MODEInterruptMode,//表示是否允许执行本中断的下一个中断INBOOLEANShareVector,//表示本中断对象是否想要共享中断号以及是否允许共享INKAFFINITYProcessorEnableMask,//本isr的cpu亲缘性,一般全部cpu都亲缘。INBOOLEANFloatingSave)//一般为FALSE{PKINTERRUPTPKINTERRUPTInterruptUsed;//当前的中断对象PKSPIN_LOCKSpinLockUsed;//实际使用的自旋锁BOOLEANFirstRun;CCHARCount0;//cpu*InterruptObject=AffinityProcessorEnableMask&KeActiveProcessors;//本isr的cpu亲缘性与实有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);//后面的中断对象数组地址FirstRun=TRUE;RtlZeroMemory(IoInterrupt,sizeof(IO_INTERRUPT));Affinity=ProcessorEnableMask&KeActiveProcessors;for(Count0;Affinity;CountAffinity1)Count其实表示cpu{if(Affinity&{InterruptUsed=FirstRun?&IoInterrupt->FirstInterrupt:{//ififreturn}ifFirstRun=Else//记录各cpu的那个中断号上挂接的中断对象地址}}return}如上,这个函数用来将指定isr挂接到各个cpu的指定中断号上。因为在多cpu系统中,一个设备可以向每个cpu都发出中断,因此,必须在每个cpu的IDT中都要挂接登记那个中断的isr。具体是怎么挂接的呢?这个函数会创建一个中断对象数组,然后将各个中断对象对应挂接到各cpu的同一中断号上。由于老式机器是单cpu的,因此,早期的中断对象结构IO_INTERRUPT就包含一个中断对象任意,后来的机器对其进行了扩展,在这个结构后面是一个中断对象数组,用来挂接到其他cpu上。typedefstruct{PKINTERRUPTInterrupt[UM_PROCESSORS];//记录各cpu上挂接的中断对象地址}IO_INTERRUPT,typedefstruct_KINTERRUPT{CSHORTCSHORTLIST_ENTRYInterruptListEntry;//用来挂入中断对象链表PVOIDServiceContext;//isr参数ULONGTickCount;//没用PKSPIN_LOCKActualLock;//我们isr实际使用的自旋锁PKINTERRUPT_ROUTINEDispatchAddress;//中间的Dispatchisr函数地址CCHARNumber;//要挂往的目标cpuKIRQLIrql;//isr对应的isrBOOLEANFloatingSave;//一般为FALSEKINTERRUPT_MODEMode;//是否允许继续执行本中断对象后面的中断对象的isrULONGServiceCount;//没用ULONGDispatchCode[DISPATCH_LENGTH];//这不是数组,而是一段代码,表示本中断对象的模板}KeInitializeInterrupt(INPKINTERRUPTINPKSERVICE_ROUTINEServiceRoutine,INPVOIDServiceContext,INPKSPIN_LOCKSpinLock,INULONGVector,INKIRQLIrql,INKIRQLSynchronizeIrql,INKINTERRUPT_MODEINBOOLEANShareVector,INCHARProcessorNumber,INBOOLEAN{ULONGPULONGDispatchCode&Interrupt->DispatchCode[0],PatchDispatchCode;//patch表示补丁处Interrupt->Type=InterruptObject;Interrupt->Size=if(SpinLock)//由于这个函数未导出,由系统内部调用,传的SpinLock参数很少为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,本中断对象的地址Interrupt->Connected=FALSE;//尚未挂入}KiEnterTrapmovedx,0//这条指令的操作数0将态修改成具体中断对象的地moveax,offset@KiInterruptTemplateHandler@8//KiInterruptTemplateHandler函数jmpeaxBOOLEAN//返回值表示是否挂接成功KeConnectInterrupt(INPKINTERRUPTInterrupt){BOOLEANConnected,Error,Status;KIRQLIrql,OldIrql;UCHARULONGDISPATCH_INFONumber=Interrupt->Number;//目标cpuVectorInterrupt->Vector;//目标中断号Irql=Interrupt->Irql;SynchronizeIrqlif((Irql>HIGH_LEVEL)||(Number>=KeNumberProcessors)||(Interrupt->SynchronizeIrql<Irql)||(Interrupt->FloatingSave)){return}Connected=Error=KeSetSystemAffinityThread(1Number);//改变当前线程的cpu亲缘性先,挪到目标cpuOldIrql=KiAcquireDispatcherLock();if(!Interrupt->Connected)//if尚未挂接{KiGetVectorDispatch(Vector,&Dispatch);if(Dispatch.TypeNoConnect{Interrupt->Connected=Connected=TRUE;KiConnectVectorToInterrupt(Interrupt,StatusHalEnableSystemInterrupt(Vector,Irql,Interrupt->Mode);//APIC相关if(!Status)Error=TRUE;}elseif((Dispatch.Type!=UnknownConnect)&&//已挂接有中断对象(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);//这个宏将中断向量号转换为IDT表项索引(一般相同Dispatch->NoDispatch=(PVOID)(((ULONG_PTR)&KiStartUnexpectedRange)(Entry–0x30)*KiUnexpectedEntrySize);Dispatch->FloatingDispatch=NULL;//尚不支持Dispatch->FlatDispatch=NULL;CurrentKeQueryInterruptHandler(Vector);//获得这个中断向量处当前存放的isrif((PKINTERRUPT_ROUTINE)Current==Dispatch-{}{
Dispatch->InterruptNULL;//表示尚未挂接有任何中断对象Dispatch->Interrupt=CONTAINING_RECORD(Current,KINTERRUPT,DispatchCode);Handler=Dispatch->Interrupt->DispatchAddress;if(Handler==Dispatch-Dispatch->Type=ChainConnect;//上次的中断对象是以方式挂上去elseif((Handler==Dispatch->InterruptDispatch)||(Handler==Dispatch->FloatingDispatch)){}
==}}是个用户自定义的isr,也可能没有isr(即以KiUnexpectedInterruptN函数占位)。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;{//填好本中断对象的dispatchInterrupt->DispatchAddress=(Type==NormalConnect)?Handler=(PVOID)&Interrupt->DispatchCode;//本中断对象的模板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;}的,那么这些中断对象将组成一个链表。这样,当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帧,恢复中断现场,回到原断点处继续执行KiExitInterrupt(TrapFrame,OldIrql,TRUE);}BOOLEANInterruptService(instruct_KINTERRUPT*Interrupt,inPVOIDServiceContexTRUE。否则应返回FALSE,让系统继续寻找中断对象链表中的下一个中断对象去认领。VOIDFASTCALLKiInterruptDispatch(INPKTRAP_FRAMETrapFrame,INPKINTERRUPT{KIRQL{}}
KiExitInterrupt(TrapFrame,OldIrql,FALSE);KiExitInterrupt(TrapFrame,OldIrql,r后,就返回了,不会有在链表中查找的过程。VOIDIoDisconnectInterrupt(PKINTERRUPT{LONGIoInterruptCONTAINING_RECORD(InterruptObject,IO_INTERRUPT,FirstInterrupt);for(i=0;i<KeNumberProcessors;i++)//撤销其它中断对象的挂接{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;}三层。第一层是中断对象的模板isr,第二层是中断对象的dispatchisr,第三层才是用户自己提供的isrisr。因此,也可以说,我们提供的那个isrIDTisrisr。当然,程序员,也可以IDT中的表项,改成自己的isr,这就是所谓的isrhook(注意要进行isrhook的话,必须每个cpu都要hook)最后我们看一下典型的系统时钟中断是怎么处理的。系统每隔10ms产生一次时钟中断,时钟中断的IRQ固定是0,中断号默认映射到0x30,时钟中断的isr最终进入下面的函数。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等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年天津交通职业学院单招职业倾向性考试题库必考题
- 2025年云南理工职业学院单招综合素质考试题库及答案1套
- 2020-2021深圳宝安区展华实验学校小学三年级数学下期末第一次模拟试题(含答案)
- 2020-2021北京第一零五中学小学三年级数学下期末一模试题(及答案)
- 单轨空中列车施工方案
- 2025年新高考地理全真模拟试卷 5套(含答案解析)
- 2024年河南省中考满分作文《不畏困难勇攀高峰》
- 专题01 地球和地图-2025年中考地理一轮复习知识清单(背诵版)
- 个人购买柴油合同范例
- 财务业务合规程序计划
- 人教版小学三年级数学下册《复式统计表》名师公开课获奖课件百校联赛一等奖课件
- 心衰护理课件教学课件
- 基于人工智能的供应链协同优化平台建设方案
- 《大学语文》普通高等院校语文课程完整全套教学课件
- 预防校园欺凌主题班会课件(共36张课件)
- 伸缩臂式22m高空作业车安全操作规程
- 全国国家版图知识竞赛题库及答案(中小学组)
- 顾客满意度调查分析报告表
- 《托育服务政策法规与职业伦理》全套教学课件
- 湖北省武汉市实验外国语学校小学部小学六年级小升初期末语文试题(含答案)
- 山东省专升本综合一(机械设计制造及其自动化)模拟试卷1(共264题)
评论
0/150
提交评论