windows 2000 中斷等級(IRQL)產生對象IRQL名稱用途1、硬體 HIGH_LEVEL 機器校正和匯流排錯誤2、POWER_LEVEL電源故障中斷3、IPI_LEVELMP系統處理器間門鈴4、CLOCK2_LEVEL間隔時鐘25、CLOck1_LEVEL間隔時鐘16、PROFILE_LEVEL設定檔計時器7、DORQLIO裝置中斷的平台依賴行等級數8、軟體DISPATCH_LEVEL線程調度和延遲程序呼叫的執行 9、APC_LEVEL非同步程序呼叫執行 10、PASSIVE_LEVEL下常線程執行等級訪問寄存器知道硬體功能後,還須知道如何通過程式設計方法引用裝置的寄存器.為了達到這一目標,還必須知道兩種資訊.1.裝置的第一個寄存器地址.2.寄存器所有的地址空間.通常裝置寄存器位於連續的地址空間上.因此,第一個寄存器的地址是訪問所有其他寄存器必須的線索.不幸的是,地址這一術語在不同平台上的虛擬位址空間中具有不同的含義.可以通過CPU專用的I/O指令,或者通過標準內在引用指令.CPU專用I/O指令訪問.Intel x86體繫結構中,I/O地址空間是64KB大小(16位),在組合語言定義兩個指令用於在此空間中讀取和寫入:IN和OUT訪問I/O空間中6各連接埠的HAL宏READ_PORT_XXX 從一個連接埠讀取一個單值WRITE_PORT_XXX 將一個單值寫入連接埠READ_PORT_BUFFER_XXX 從連續的I/O連接埠讀取一組值WRITE_PORT_BUFFER_XXX 將一組值寫入連續的I/O連接埠.記憶體映射寄存器READ_REGISTER_XXX 從I/O寄存器讀取一個單值WRITE_REGISTER_XXX 將一個單值寫入一個I/O寄存器READ_REGISTER_BUFFER_XXX 從連續的I/O寄存器讀取一組值WRITE_REGISTER_BUFFER_XXX 將一組值寫入連續的I/O寄存器.驅動程式常用列程1.DriverEntry(驅動程式入口)pDriverObject->DriverEntry = DriverEntry;IRQL = PASSIVE_LEVELNTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath){}2.Reinitialize(重新初始化常式)pDriverObject->DriverReinitialize = DriverReinitialize;3.DriverUnload(卸載常式)pDriverObject->DriverEntry = DriverEntry;4.Shutdown(關閉常式)pDriverObject->DriverShutdown = DriverShutdown;5.Bugcheck(故障檢驗常式)pDriverObject->DriverBugcheck = DriverBugcheck;6.CreateDispatch(當使用者層調用中CreateFile時執行. IRP_MJ_CREATE)7.CloseDispatch(當使用者層調用CloseHandle時執行. IRP_MJ_CLOSE)8.WriteDispatch(當使用者屋調用WriteFile時執行. IRP_MJ_WRITE)9.ReadDispatch(當使用者層調用ReadFile時執行. IRP_MJ_READ)10.DeviceControlDispatch(當使用者層調用DeviceIoControl執行.IRP_MJ_DEVICE_CONTROL)Dispatch列程邦定到驅動對象的MajorFunction指標上 pDriverObject->MajorFunction[IRP_MJ_CREATE] =CreateDispatch;pDriverObject->MajorFunction[IRP_MJ_CLOSE] =CloseDispatch;pDriverObject->MajorFunction[IRP_MJ_WRITE] =WriteDispatch;pDriverObject->MajorFunction[IRP_MJ_READ] =ReadDispatch;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =DeviceControlDispatch;11.DriverStartIo(當裝置須要開始資料轉送時執行)pDriverObject->DriverStartIo = DriverStartIo;同步回調常式1.ControllerControl常式單一的控制器(卡)支援多個函數.每次卡上只有一個函數運行.當I/O完成時,驅動程式釋放控制器.通常在一個DpcForIsr常式中.2.AdapterControl常式當所有權得到時允許時,回調常式執行.通常是一個DMA通道.3.SynchCritSection常式通常用於訪問寄存器同步.IRP結構typedef struct _IRP { CSHORT Type; USHORT Size; // // Define the common fields used to control the IRP. // // // Define a pointer to the Memory Descriptor List (MDL) for this I/O // request. This field is only used if the I/O is "direct I/O". // PMDL MdlAddress; //指向使用者空間的記憶體描述列表 // // Flags word - used to remember various flags. // ULONG Flags; // // // The following union is used for one of three purposes: // // 1. This IRP is an associated IRP. The field is a pointer to a master // IRP. // // 2. This is the master IRP. The field is the count of the number of // IRPs which must complete (associated IRPs) before the master can // complete. // // 3. This operation is being buffered and the field is the address of // the system space buffer. // union { struct _IRP *MasterIrp; LONG IrpCount; PVOID SystemBuffer; //指向系統緩衝區 } AssociatedIrp; // // Thread list entry - allows queueing the IRP to the thread pending I/O // request packet list. // LIST_ENTRY ThreadListEntry; // // I/O status - final status of operation. // IO_STATUS_BLOCK IoStatus; // 包含I/O請求的狀態 // // Requestor mode - mode of the original requestor of this operation. // KPROCESSOR_MODE RequestorMode; // // Pending returned - TRUE if pending was initially returned as the // status for this packet. // BOOLEAN PendingReturned; // // Stack state information. // CHAR StackCount; CHAR CurrentLocation; // // Cancel - packet has been canceled. // BOOLEAN Cancel; //表示IRP已經取消 // // Cancel Irql - Irql at which the cancel spinlock was acquired. // KIRQL CancelIrql; // // ApcEnvironment - Used to save the APC environment at the time that the // packet was initialized. // CCHAR ApcEnvironment; // // Allocation control flags. // UCHAR AllocationFlags; // // User parameters. // PIO_STATUS_BLOCK UserIosb; PKEVENT UserEvent; union { struct { PIO_APC_ROUTINE UserApcRoutine; PVOID UserApcContext; } AsynchronousParameters; LARGE_INTEGER AllocationSize; } Overlay; // // CancelRoutine - Used to contain the address of a cancel routine supplied // by a device driver when the IRP is in a cancelable state. // PDRIVER_CANCEL CancelRoutine; // // Note that the UserBuffer parameter is outside of the stack so that I/O // completion can copy data back into the user's address space without // having to know exactly which service was being invoked. The length // of the copy is stored in the second half of the I/O status block. If // the UserBuffer field is NULL, then no copy is performed. // PVOID UserBuffer; //I/O緩衝區的使用者空間地址 // // Kernel structures // // The following section contains kernel structures which the IRP needs // in order to place various work information in kernel controller system // queues. Because the size and alignment cannot be controlled, they are // placed here at the end so they just hang off and do not affect the // alignment of other fields in the IRP. // union { struct { union { // // DeviceQueueEntry - The device queue entry field is used to // queue the IRP to the device driver device queue. // KDEVICE_QUEUE_ENTRY DeviceQueueEntry; struct { // // The following are available to the driver to use in // whatever manner is desired, while the driver owns the // packet. // PVOID DriverContext[4]; } ; } ; // // Thread - pointer to caller's Thread Control Block. // PETHREAD Thread; // // Auxiliary buffer - pointer to any auxiliary buffer that is // required to pass information to a driver that is not contained // in a normal buffer. // PCHAR AuxiliaryBuffer; // // The following unnamed structure must be exactly identical // to the unnamed structure used in the minipacket header used // for completion queue entries. // struct { // // List entry - used to queue the packet to completion queue, among // others. // LIST_ENTRY ListEntry; union { // // Current stack location - contains a pointer to the current // IO_STACK_LOCATION structure in the IRP stack. This field // should never be directly accessed by drivers. They should // use the standard functions. //truct _IO_STACK_LOCATION *CurrentStackLocation; //I/O堆棧位,儲存I/O請求的函數代碼和參數 s // // Minipacket type. // ULONG PacketType; }; }; // // Original file object - pointer to the original file object // that was used to open the file. This field is owned by the // I/O system and should not be used by any other drivers. // PFILE_OBJECT OriginalFileObject; } Overlay; // // APC - This APC control block is used for the special kernel APC as // well as for the caller's APC, if one was specified in the original // argument list. If so, then the APC is reused for the normal APC for // whatever mode the caller was in and the "special" routine that is // invoked before the APC gets control simply deallocates the IRP. // KAPC Apc; // // CompletionKey - This is the key that is used to distinguish // individual I/O operations initiated on a single file handle. // PVOID CompletionKey; } Tail;} IRP, *PIRP;操作IRP頭的函數IoStatrtPacket 把IRP發送到Start I/O常式 DispatchIoCompleteRequest 指示所有處理都已經完成. DpcForcIarIoStartNextPacket 把下一個IRP發送到Start I/O常式 DpcForIsrIoCallDriver 把IRP發送到別一個驅動 Dispatch IoAllocateIrp 請求額外的IRP Dispatch IoFreeIrp 釋放驅動程式分配的IRP I/O CompletionIRP堆棧位置IoGetCurrentIrpSteckLocation 擷取指向調用者堆棧(Stack slot)的指標 DispatchIoMarkIrpPending 把調用者堆棧槽標誌為需要進一步處理 DispatchIoGetNextIrpStackLocation 擷取指向下一個低級驅動程式的堆棧槽的指標 DispatchIoSetNextIrpStackLocation 把I/O堆棧指標壓入一個位置. DispatchIoSetCompleteRoutime 把I/O完成常式放在下一個低級驅動程式的I/O堆棧槽上 Dispatch驅動程式對象可設定的欄位.PDRIVER_STARTIO DriverStartIo 驅動程式 Start I/O 常式的地址PDRIVER_UNLOAD DriverUnload 驅動程式 Unload常式的地址.PDRIVER_DISPATCH MajorFunction 驅動程式Dispatch常式表,由I/O作業碼索引PDEVICE_OBJECT DeviceObject 該驅動程式建立的裝置對象的連結清單裝置對象結構PVOID DeviceExtension 指向裝置擴充結構PDRIVER_OBJECT DriverObject 指向該裝置的驅動程式對象ULONG Flags 規定裝置的緩衝策略是(DO_BUFFERED_IO 或者 DO_DIRECT_IO)PDEVICE_OBJECT NextDevice 指向屬於該驅動程式的下一個裝置CCHAR StackSize 發送到該裝置的IRP所需的最少數量的I/O堆棧位置ULONG AlignmentRequirement 緩衝區要求記憶體調整操作裝置對象的函數IoCreateDevice 建立裝置對象 DirverEntry或AddDeviceIoCreateSymbolicLink 使裝置對象對Win32可見 DirverEntry或AddDeviceIoAttachDevice 把一個過濾器附加在裝置對象上 DirverEntry或AddDeviceIoAttachDeviceByPointer 把一個過濾器附加在裝置對象上 DirverEntry或AddDeviceIoGetDeviceObjectPointer 把驅動程式放在另一個驅動程式之上 DirverEntry或AddDevice IoCallDriver 把IRP請求發送到另一個驅動程式 DispatchIoDetachDevice 斷開與低級驅動程式的串連 Unload 或 RemoveDeivceIoDeleteSymbolicLink 從Win32 名字空間中刪除裝置對象 Unload 或 RemoveDeivceIoDeleteDevice 從系統中刪除裝置對象 Unload 或 RemoveDeivce控制器對象的訪問函數IoCreateController 建立控制器對象 IoAllocateController 請求控制器的獨佔權IoFreeController 釋放控制器擁有權IoDeleteController 從系統中刪除控制對象操縱配接器物件的函數 (主要用於DMA傳輸)IoGetDmaAdapter 擷取指向配接器物件的指標AllocateAdapterChannel 請求單獨擁有DMA硬體MapTransfer 建立用於資料轉送的DMA硬體FlushAdapterBuffers 資料部分傳輸之後,清洗緩衝區資料FreeMapRegisters 釋放映射寄存器FreeAdapterChannel 釋放配接器物件中斷對象中斷對象僅僅給核心中斷發送器提供了一種尋找方法,在一個中斷髮生時找到正確的服務常式操作中斷對象HalGetInterruptVector 將匯流排相關的中斷失量轉換成系統範圍的值.IoConnectInterrupt 將插斷服務常式與一個中斷失量關聯.KeSynchronizeExecution 同步運於不同的IRQL等級上的驅動程式IoDisconnectInterrupt 刪除中斷對象記憶體配置類型1.通過核心堆棧分配(堆棧大小為12K)2.使用池地區 使用ExAllocatePool 或 ExFreePool3.地區緩衝區先使用 ExAllocatePool 再使用ExInitializeZone 初始化分配使用ExAllocateFromZone 或者 ExInterLocked-AllocateFromZone(互鎖的函數)釋放地區 ExFreeToZone 或 InterLockedFreeToZone(互鎖)使用ExExtendZone 或 ExInterlockedExtendZone 擴充4.使用後備列表初始化:ExInitializeNPagedLookasideList 或 ExInitializePagedLookasideList分配:ExAllocateNPagedLookasideList 或 ExAllocatePagedLookasideList釋放:ExFreeToNPageLookasideList 或 ExFreeToPageLookasideList刪除後備列表:ExDeleteNPageLookasideList 或 ExDeletePageLookasideList中斷同步中斷阻止(interrupt blocking)KeRaiselrql將CPU的IRQL層級改為規定的值KeLowerlrql將低CPU的IRQL值KeGetCurrentIrql返回傳出調用的CPU的IRQL值IO完成常式的IRQL是由下層驅動程式調用而決定的固引入了核心事件來處理IO完成常式