首页 »编程综合 » reactos:reactos操作系统实现(96) »正文
reactos:reactos操作系统实现(96)
来源: 发布时间:星期一, 2009年9月28日 浏览:0次 评论:0
![](/icons/46373diaoyong.gif) ![](/icons/46373hanshu.gif) IoConnectInterrupt来设置键中断处理 ![](/icons/46373hanshu.gif) ![](/icons/46373dou2.gif) #028 Status = IoConnectInterrupt( #029 &PortDeviceExtension->KeyboardInterrupt.Object, #030 i8042KbdInterruptService, #031 DeviceExtension, &PortDeviceExtension->SpinLock, #032 PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax, #033 PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt, #034 PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE); #035 (!NT_SUCCESS(Status)) #036 { #037 WARN_(I8042PRT, "IoConnectInterrupt failed with status 0x%08x\n", Status); #038 Status; #039 } #040 设置最大 ![](/icons/46373de.gif) 请求级别 ![](/icons/46373dou2.gif) #041 (DirqlMax PortDeviceExtension->KeyboardInterrupt.Dirql) #042 PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; 设置键盘已经 ![](/icons/46373chushi.gif) 化 ![](/icons/46373dou2.gif) #043 PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED; #044 STATUS_SUCCESS; #045 } 其实是 ![](/icons/46373diaoyong.gif) IO管理器里 ![](/icons/46373de.gif) 中断设置 ![](/icons/46373hanshu.gif) IoConnectInterrupt ![](/icons/46373dou.gif) 实现如下:
#001 NTSTATUS #002 NTAPI #003 IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, #004 IN PKSERVICE_ROUTINE ServiceRoutine, #005 IN PVOID ServiceContext, #006 IN PKSPIN_LOCK SpinLock, #007 IN ULONG Vector, #008 IN KIRQL Irql, #009 IN KIRQL SynchronizeIrql, #010 IN KINTERRUPT_MODE InterruptMode, #011 IN BOOLEAN ShareVector, #012 IN KAFFINITY ProcessorEnableMask, #013 IN BOOLEAN FloatingSave) #014 { InterruptObject是返回中断处理对象 ![](/icons/46373dou2.gif) ServiceRoutine是中断 ![](/icons/46373diaoyong.gif) ![](/icons/46373hanshu.gif) ![](/icons/46373dou2.gif) ServiceContext是中断 ![](/icons/46373diaoyong.gif) ![](/icons/46373hanshu.gif) 使用 ![](/icons/46373de.gif) 参数 ![](/icons/46373dou2.gif) SpinLock是访问输入参数 ![](/icons/46373de.gif) 自旋锁 ![](/icons/46373dou2.gif) Vector是PNP管理器分配 ![](/icons/46373de.gif) 中断号 ![](/icons/46373dou2.gif) Irql是中断请求优先级 ![](/icons/46373dou2.gif) SynchronizeIrql是同步请求优先级 ![](/icons/46373dou2.gif) InterruptMode是中断 ![](/icons/46373de.gif) 模式 ![](/icons/46373dou2.gif) ShareVector是中断资源是否共享 ![](/icons/46373dou2.gif) ProcessorEnableMask是中断允许发生 ![](/icons/46373de.gif) 处理器 ![](/icons/46373dou2.gif) FloatingSave指明是否保存浮点堆栈 ![](/icons/46373dou2.gif) #015 PKINTERRUPT Interrupt; #016 PKINTERRUPT InterruptUsed; #017 PIO_INTERRUPT IoInterrupt; #018 PKSPIN_LOCK SpinLockUsed; #019 BOOLEAN FirstRun; #020 CCHAR Count = 0; #021 KAFFINITY Affinity; #022 PAGED_CODE ; #023
假定失败 ![](/icons/46373de.gif) 返回结果 ![](/icons/46373dou2.gif) #024 /* Assume failure */ #025 *InterruptObject = NULL; #026 获取处理器位 ![](/icons/46373dou2.gif) #027 /* Get the affinity */ #028 Affinity = ProcessorEnableMask & KeActiveProcessors; #029 while (Affinity) #030 { #031 /* Increase count */ #032 (Affinity & 1) Count ; #033 Affinity >>= 1; #034 } #035 确保这个CPU有中断响应 ![](/icons/46373dou2.gif) #036 /* Make sure we have a valid CPU count */ #037 (!Count) STATUS_INVALID_PARAMETER; #038 分配 ![](/icons/46373yi.gif) 个IO中断结构 ![](/icons/46373dou2.gif) #039 /* Allocate the .gif' /> of I/O Interrupts */ #040 IoInterrupt = ExAllocatePoolWithTag(NonPagedPool, #041 (Count - 1) * (KINTERRUPT) + #042 (IO_INTERRUPT), #043 TAG_KINTERRUPT); #044 (!IoInterrupt) STATUS_INSUFFICIENT_RESOURCES; #045 如果驱动 ![](/icons/46373chengxu.gif) 传入自旋锁 ![](/icons/46373dou.gif) 就使用驱动 ![](/icons/46373chengxu.gif) ![](/icons/46373de.gif) ![](/icons/46373dou.gif) 否则就使用内核分配 ![](/icons/46373de.gif)
#046 /* Select which Spinlock to use */ #047 SpinLockUsed = SpinLock ? SpinLock : &IoInterrupt->SpinLock; #048 设置返回 ![](/icons/46373de.gif) 中断对象 ![](/icons/46373dou2.gif) #049 /* We first start with a built-in Interrupt inside the I/O Structure */ #050 *InterruptObject = &IoInterrupt->FirstInterrupt; #051 Interrupt = (PKINTERRUPT)(IoInterrupt + 1); #052 FirstRun = TRUE; #053 ![](/icons/46373chushi.gif) 化中断对象结构 ![](/icons/46373dou2.gif) #054 /* Start with a fresh structure */ #055 RtlZeroMemory(IoInterrupt, (IO_INTERRUPT)); #056 开始创建所有CPU ![](/icons/46373de.gif) 中断 ![](/icons/46373dou2.gif) #057 /* Now create all the errupts */ #058 Affinity = ProcessorEnableMask & KeActiveProcessors; #059 for (Count = 0; Affinity; Count , Affinity >>= 1) #060 { 检查这个CPU是否有中断设置 ![](/icons/46373dou2.gif) #061 /* Check it's enabled for this CPU */ #062 (Affinity & 1) #063 { 是否第 ![](/icons/46373yi.gif) 个CPU中断设置 ![](/icons/46373dou2.gif) #064 /* Check which one we will use */ #065 InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt; #066
设置中断对象 ![](/icons/46373dou2.gif) #067 /* Initialize it */ #068 KeInitializeInterrupt(InterruptUsed, #069 ServiceRoutine, #070 ServiceContext, #071 SpinLockUsed, #072 Vector, #073 Irql, #074 SynchronizeIrql, #075 InterruptMode, #076 ShareVector, #077 Count, #078 FloatingSave); #079 #080 /* Connect it */ ![](/icons/46373diaoyong.gif) 内核 ![](/icons/46373hanshu.gif) KeConnectInterrupt设置中断 ![](/icons/46373dou2.gif) #081 (!KeConnectInterrupt(InterruptUsed)) #082 { #083 /* Check how far we got */ #084 (FirstRun) #085 { #086 /* We failed early so just free this */ #087 ExFreePool(IoInterrupt); #088 } #089 ![](/icons/46373else.gif) #090 {
如果没有设置中断成功 ![](/icons/46373dou.gif) 就返回出错 ![](/icons/46373dou2.gif) #091 /* Far enough, so disconnect everything */ #092 IoDisconnectInterrupt(&IoInterrupt->FirstInterrupt); #093 } #094 #095 /* And fail */ #096 STATUS_INVALID_PARAMETER; #097 } #098 设置第 ![](/icons/46373yi.gif) 个中断响应 ![](/icons/46373dou.gif) 已经设置完成 ![](/icons/46373dou2.gif) #099 /* Now we've used up our First Run */ #100 (FirstRun) #101 { #102 FirstRun = FALSE; #103 } #104 ![](/icons/46373else.gif) #105 { 把其它CPU ![](/icons/46373de.gif) 中断放到队列后面 ![](/icons/46373dou2.gif) #106 /* Move on to the next one */ #107 IoInterrupt->Interrupt[(UCHAR)Count] = Interrupt ; #108 } #109 } #110 } #111 #112 /* Return Success */ #113 STATUS_SUCCESS; #114 } 在这个 ![](/icons/46373hanshu.gif) 主要到两个内核 ![](/icons/46373hanshu.gif) 来设置中断 ![](/icons/46373dou.gif) 它就是 ![](/icons/46373hanshu.gif) KeInitializeInterrupt 和KeConnectInterrupt ![](/icons/46373dou2.gif) 下来分析 ![](/icons/46373hanshu.gif) KeConnectInterrupt实现 ![](/icons/46373dou.gif) 看看它是如何样把中断服务器和内核连接在 ![](/icons/46373yi.gif) 起 ![](/icons/46373de.gif) ![](/icons/46373dou.gif) 如下:
#001 BOOLEAN #002 NTAPI #003 KeConnectInterrupt(IN PKINTERRUPT Interrupt) #004 { #005 BOOLEAN Connected, Error, Status; #006 KIRQL Irql, OldIrql; #007 UCHAR Number; #008 ULONG Vector; #009 DISPATCH_INFO Dispatch; #010 从中断里获取中断号所在CPU、中断向量、中断优先级 ![](/icons/46373dou2.gif) #011 /* Get data from errupt */ #012 Number = Interrupt->Number; #013 Vector = Interrupt->Vector; #014 Irql = Interrupt->Irql; #015 检查参数是否有效 ![](/icons/46373dou2.gif) #016 /* Validate the tings */ #017 ((Irql > HIGH_LEVEL) || #018 (Number >= KeNumberProcessors) || #019 (Interrupt->SynchronizeIrql < Irql) || #020 (Interrupt->FloatingSave)) #021 { #022 FALSE; #023 } #024 设置缺省状态 ![](/icons/46373dou2.gif) #025 /* Set defaults */ #026 Connected = FALSE; #027 Error = FALSE; #028 设置起作用 ![](/icons/46373de.gif) CPU ![](/icons/46373dou2.gif) #029 /* Set the system affinity and acquire the dispatcher lock */ #030 KeSet AffinityThread(1 << Number); #031 OldIrql = KiAcquireDispatcherLock ; #032
检查中断是否已经连接到系统里 ![](/icons/46373dou2.gif) #033 /* Check it's already been connected */ #034 (!Interrupt->Connected) #035 { 如果没有连接 ![](/icons/46373dou.gif) 就查找分发信息 ![](/icons/46373dou2.gif) #036 /* Get vector dispatching information */ #037 KiGetVectorDispatch(Vector, &Dispatch); #038 如果分发器也没有连接这个中断 ![](/icons/46373dou2.gif) #039 /* Check the vector is already connected */ #040 (Dispatch.Type NoConnect) #041 { 开始连接这个中断处理 ![](/icons/46373hanshu.gif) ![](/icons/46373dou2.gif) #042 /* Do the connection */ #043 Interrupt->Connected = Connected = TRUE; #044 #045 /* Initialize the list */ #046 InitializeListHead(&Interrupt->InterruptListEntry); #047 连接中断处理 ![](/icons/46373dou.gif) 并启动这个中断 ![](/icons/46373dou2.gif) #048 /* Connect and enable the errupt */ #049 KiConnectVectorToInterrupt(Interrupt, NormalConnect); #050 Status = HalEnable Interrupt(Vector, Irql, Interrupt->Mode); #051 (!Status) Error = TRUE; #052 } #053 ((Dispatch.Type != UnknownConnect) && #054 (Interrupt->ShareVector) && #055 (Dispatch.Interrupt->ShareVector) && #056 (Dispatch.Interrupt->Mode Interrupt->Mode)) #057 {
这里是处理共享中断 ![](/icons/46373de.gif) 情况 ![](/icons/46373dou2.gif) #058 /* The vector is shared and the errupts are compatible */ #059 ASSERT(FALSE); // FIXME: NOT YET SUPPORTED/TESTED #060 Interrupt->Connected = Connected = TRUE; #061 ASSERT(Irql <= SYNCH_LEVEL); #062 是否为第 ![](/icons/46373yi.gif) 个连接 ![](/icons/46373dou2.gif) #063 /* Check this is the first chain */ #064 (Dispatch.Type != ChainConnect) #065 { #066 /* Setup the chainned handler */ #067 KiConnectVectorToInterrupt(Dispatch.Interrupt, ChainConnect); #068 } #069 把这个中断放到中断响应列表里 ![](/icons/46373dou2.gif) #070 /* Insert o the errupt list */ #071 InsertTailList(&Dispatch.Interrupt->InterruptListEntry, #072 &Interrupt->InterruptListEntry); #073 } #074 } #075 #076 /* Unlock the dispatcher and revert affinity */ #077 KiReleaseDispatcherLock(OldIrql); #078 KeRevertToUserAffinityThread ; #079 如果连接失败 ![](/icons/46373dou.gif) 就准备下 ![](/icons/46373yi.gif) 次连接 ![](/icons/46373dou2.gif) #080 /* Check we failed while trying to connect */ #081 ((Connected) && (Error)) #082 { #083 DPRINT1("HalEnable Interrupt failed\n"); #084 KeDisconnectInterrupt(Interrupt); #085 Connected = FALSE; #086 } #087 #088 /* Return to caller */ #089 Connected; #090 }
相关文章
读者评论
发表评论
|
|