Re: 10 Commandments for WDM driver Development
- From: "Doron Holan [MSFT]" <doronh@xxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 19 Sep 2007 16:18:49 -0700
do not check the IRQL upon entry to every function in production code, acquiring the current IRQL is a very expensive operation. checking in a debug build can be done though
d
--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
"ananda" <ananda@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:12C45493-AEF2-460A-9974-DA189170A43D@xxxxxxxxxxxxxxxx
I just took a OSR class on WDM driver development and here are some golden
nuggests I collected. All that is good, the credit goes OSR and if you find
something wrong in my collection the fault is mine(-: Hope you will find it
useful:
IRQL
1.Check for IRQL when ever you enter for function
2.Refer DDK documentation for IRQL before calling any function.
3.If a thread is running at its lowest IRQL you cannot lower it, you can
only bump it up.
4.You cannot PAGE FAULT at DISPATCH_LEVEL
5.Paging I/O is done at APC level
6.User always runs at PASSIVE_LEVEL
7.Kernel as much as possible runs at PASSIVE_LEVEL.
8.PASSIVE_LEVEL allows an even work load distribution
9.DPC’s runs at DISPATCH_LEVEL and cannot be preempted (but is
interruptible) because the dispatcher also runs at DISPATCH_LEVEL
10.KeLowerIrql() and KeRaiseIrql() are used for IRQL manipulation.
IRP
1.IRP’s are created by the IoManager on behalf of an application or driver.
Upper part of IRP is fixed data bottom part has the stack locations which
gets pushed and popped as the IRP moves up and down multiple drivers.
2.App to driver has only one means to pass “control” that is via IRPs, data
can be exchanged by shared memory.
3.IoManager does not queue the IRPs for the driver, it just dumps it as and
when it gets it. It is the drivers responsibility to queue.
4.IRP is fully self contained and is complete only when a driver calls
IoCompleteRequest. The return status indicates to the IoManager whether or
not data may need to be copied back to user mode. The app can get the above
status set by calling GetLastError()
5.Irp->IoStatus.Information contains the length of transfer and is reflected
as BytesReturned, the last but one parameter of DeviceIoControl()
6.This is used by the IoManger to copy the data from the SystemBuffer to
OutputBuffer.
7.IoCompleteRequest() is the last call which tells the IoManager the IRP is
done. Once IoCompleteRequest() has been called the IRP SHOULD not be touched!!
8.Driver to Driver can communicate by IRP . Since drivers are in the same
address space they can share memory and communicate with each other thru
shared routintes.
9.A single IRP might go up down the driver layers
IoGetCurrentIrpStackLocation() will bind the driver to the IRP values on
which ever driver it is called.
10.Only when the function returns will the app get back the control from the
driver. The applications thread which is running in kernel context should
return.
INTERRUPT
1.Only OS can generate an Interrupt
2.The driver has to register with Iomanager with the interrupt number with
which it shall be called.
3.An ISR has to exist and the IDT table binds the interrupt vector with the
ISR
4.ISR runs at Device IRQL (DIRQL) and must spend minimal time and call a DPC
function.
5.DPC runs at Dispatch Level IRQL, it runs till it is finished or is
interrupted by a higher Interrupt and it runs at an arbitrary context.
6.Mutex, Semaphore and Events provide synchronization at IRQL <
DISPATCH_LEVEL and SpinLock provide synchronization at IRQL >=
DISPATCH_LEVEL.
7.Events can be waited upon by the driver
8.When you call spinlock it automatically raises the IRQL to the IRQL of the
spinlock
9.This helps in synchronizing the processor on which it is running.
10.Only the processor(s) which holds or waiting on a given SpinLock is(are)
busy. The other processors are running unperturbed.
CONTEXT and MISC
1.Other then the highest level driver all drivers Intermediate and lower
does not run in User context.
2.Irrespective of User/Kernel mode thread, only the thread priority
determines which one is the next to run
3.IRP_MN_STOP_DEVICE is called only for resource balancing.
4.NT driver development procedure is still valid and used.
5.NT Driver + PnP + Power = WDM
6.WDM + Framework which automates PnP + Power interface = KMDF
Device installation and app communication to a particular device of its choice
1.How does the device get installed
a.Assume a new PCI Ethernet card has been plugged in and system booted
b.Pci.sys the bus driver enumerates all the PCI devices it sees
c.Reads the Configuration space and gets the Hardware ID of the device and
creates the PDO.
d.This is passed on to the PnP manager. PnP manager looks in the
IoDeviceList and does not find an entry to this PDO
e.Puts out the message window asking for the driver
f.The user points it to the *.inf file which points to the correct driver
g.DriverEntry() registers all the standard driver entry points and the PnP
manager calls AddDevice()
h.IoCreateDevice() creates a Device Object. If the caller provides a name
an entry is made the NameSpace
i.Then calls IoRegisterDeviceInterface() which ties in the name to a PDO and
the GUID ties in to the device class.
j.Summary: We have created a PDO-DriverName table in the namespace.
2.How does an app communicate to a device of its choice. The assumption here
is the device has been fully installed and fully functional.
a.During system boot the bus driver enumerates all the devices, looks at
their config space gets the Hardware ID and creates a PDO for each of them.
b.These PDO’s are passed on to the PnP manager. PnP manager refers to a
table which connects the Hardware ID to a GUID.
c.So we have the system fully initialized
d.The app calls SetupDiGetClassDevs(),SetupDiEnumDeviceInterfaces(), and
SetupDiGetDeviceInterfaceDetail() to enumerate the devices. This gives you a
name that you can use with CreateFile to get a handle.
e.Basically you get a handle which you can pass it to ReadFile(),
DeviceIoControl()
f.The IoManager creates the IRP and via the handle gets the FILE_OBJECT
thru which it can reach the correct driver and the correct function in it
.
- References:
- 10 Commandments for WDM driver Development
- From: ananda
- 10 Commandments for WDM driver Development
- Prev by Date: Re: filter driver cause windows system power problems
- Next by Date: How to build a DLL using the W2K3 DDK ??? I keep on getting a LIB instead!
- Previous by thread: Re: 10 Commandments for WDM driver Development
- Next by thread: Re: about 802.1x
- Index(es):
Relevant Pages
|