reactos操作系统实现(98)
通过上面的分析,发现设置一个中断处理是非常复杂的,下面就来通过图来分析一个中断发生时,中断处理的过程如下图:
其实所有上面代码,就是设置这些流程里工作的函数关键代码,以便整个中断连接起来。其中一些函数是在汇编代码里面,这些都需要仔细分析才能理解。
主要调用下面这两个汇编代码,如下: #001 .func KiInterruptTemplate #002 _KiInterruptTemplate: #003 #004 /* Enter interrupt trap */ #005 INT_PROLOG kit_a,kit_t,DoPushFakeErrorCode #006 #007 _KiInterruptTemplate2ndDispatch: #008 /* Dummy code,will be replaced by the address of the KINTERRUPT */ #009 mov edi,0 #010 #011 _KiInterruptTemplateObject: #012 /* Dummy jump,will be replaced by the actual jump */ #013 jmp _KeSynchronizeExecution@12 #014 #015 _KiInterruptTemplateDispatch: #016 /* Marks the end of the template so that the jump above can be edited */ #017 #018 TRAP_FIXUPS kit_a,DoFixupV86,DoFixupAbios #019 .endfunc
和
#001 .func KiInterruptDispatch@0 #002 _KiInterruptDispatch@0: #003 #004 /* Increase interrupt count */ #005 inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT] #006 #007 /* Save trap frame */ #008 mov ebp,esp #009 #010 /* Save vector and IRQL */ #011 mov eax,[edi+KINTERRUPT_VECTOR] #012 mov ecx,[edi+KINTERRUPT_SYNCHRONIZE_IRQL] #013 #014 /* Save old irql */ #015 push eax #016 sub esp,4 #017 #018 /* Begin interrupt */ #019 push esp #020 push eax #021 push ecx #022 call _HalBeginSystemInterrupt@12 #023 #024 /* Check if it was handled */ #025 or al,al #026 jz SpuriousInt #027 #028 /* Acquire the lock */ #029 GetIntLock: #030 mov esi,[edi+KINTERRUPT_ACTUAL_LOCK] #031 ACQUIRE_SPINLOCK(esi,IntSpin) #032 #033 /* Make sure that this interrupt isn't storming */ #034 VERIFY_INT kid #035 #036 /* Save the tick count */ #037 mov ebx,_KeTickCount #038 #039 /* Call the ISR */ #040 mov eax,[edi+KINTERRUPT_SERVICE_CONTEXT] #041 push eax #042 push edi #043 call [edi+KINTERRUPT_SERVICE_ROUTINE] #044 #045 /* Check if the ISR timed out */ #046 add ebx,_KiISRTimeout #047 cmp _KeTickCount,ebx #048 jnc IsrTimeout #049 #050 ReleaseLock: #051 /* Release the lock */ #052 RELEASE_SPINLOCK(esi) #053 #054 /* Exit the interrupt */ #055 INT_EPILOG 0 #056 #057 SpuriousInt: #058 /* Exit the interrupt */ #059 add esp,8 #060 INT_EPILOG 1 #061 #062 #ifdef CONFIG_SMP #063 IntSpin: #064 SPIN_ON_LOCK(esi,GetIntLock) #065 #endif #066 #067 IsrTimeout: #068 /* Print warning message */ #069 push [edi+KINTERRUPT_SERVICE_ROUTINE] #070 push offset _IsrTimeoutMsg #071 call _DbgPrint #072 add esp,8 #073 #074 /* Break into debugger,then continue */ #075 int 3 #076 jmp ReleaseLock #077 #078 /* Cleanup verification */ #079 VERIFY_INT_END kid,0 #080.endfunc (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |