![]() |
![]() |
|||||||
1 Basic questions1.1 Help, I need a driver for...Sorry, wrong FAQ, wrong newsgroup, and/or wrong web page. This is about writing drivers. 1.2 What is a "device driver"?
In terms of computer software, a "driver" is a routine or set of
routines that implements the device-specific aspects of generic I/O
operations.
For example, an application calls a system function that
directs the operating system to write the contents of a buffer in
memory to a particular device.
(In Win32, this would be In primitive PC operating environments such as MS-DOS, drivers were specific to individual applications. For example, part of the success of Word Perfect for DOS was due to its support for a very wide variety of printers. But none of Word Perfect's printer drivers would work with any other applications, so when you installed Autocad, for example, you had to install Autocad's printer driver for your printers as well as Word Perfect's. As far as the operating system is concerned, these aren't really "drivers" at all; they're just parts of the user application. It's just that the applications are structured to separate their device-dependent from their device-independent code. Under the 16-bit Microsoft Windows environment, the display and printer drivers became the province of the "operating environment". That is, Windows supplied drivers for a variety of video cards and for a variety of printers, which could be used by any Windows application. Makers of video cards and printers not supported by the stock drivers could and did provide their own Windows drivers, and these too could be used by any application. Many other types of devices, however, were still controlled by individual applications. Under Windows NT, kernel mode drivers handle all I/O devices; It is not even possible for user-mode code to access I/O hardware without the aid of a kernel mode driver. 1.3 What are the various types of NT device drivers?Virtual device drivers, GDI drivers, and kernel mode drivers. 1.3.1 Virtual device drivers (VDDs)VDDs are Win32 DLLs with specific entry point and installation requirements. They allow 16-bit applications (DOS and Win16 applications) to access certain I/O ports, be informed of certain device interrupts, and so on, when running under Windows NT. By "certain", we mean those without security ramifications: 16-bit applications running under NT are allowed to access devices such as serial and parallel ports, but not the disk controller. Note, however, that VDDs do not actually access I/O hardware from user mode. They simply provide routines that the NTVDM calls after trapping a 16-bit app's attempts to reference IO ports. The actual I/O hardware access is done by an ordinary NT kernel mode driver. Here is a bit more on how these work. 1.3.2 GDI driversGDI drivers, also known as Win32 Graphics Drivers and Kernel Mode Graphics Drivers, run in kernel mode but are nonetheless very different from the "kernel mode drivers" that are the main focus of this FAQ. GDI drivers exist to implement the video controller-specific or printer-specific aspects of GDI functions. They are built as DLLs and are loaded into system address space where their routines are called by the GDI routines in Win32K.Sys. The execution environment of a GDI drivers is radically different from that of kernel mode drivers in several important ways. GDI drivers always execute in the context of their caller's thread, and the functions they implement are always regarded as compute-bound and synchronous. That is, the GDI driver is invoked to perform a function, and does not return to its caller until that function is complete. The functions implemented by GDI drivers involve operations that are always executed synchronously, with no wait-for-interrupt necessary for either notification of the hardware's completion of the operation nor of its readiness for the next operation. In fact, there is no mechanism by which the GDI APIs can support asynchronous operations nor export such behavior to their applications. 1.3.3 Kernel Mode Drivers (KMDs)Kernel mode drivers implement the device-specfic aspects of I/O requests such as (in Win32 terms) CreateFile, CloseHandle (for file objects), ReadFile, WriteFile, and DeviceIoControl. In general, kernel mode drivers are the only drivers that can touch I/O hardware, although GDI video drivers do have access to the video card. SCSI miniport and netcard (NDIS) drivers are special cases of kernel mode drivers. So are SCSI class drivers, file system drivers, redirectors, and transport-layer network components, although these do not touch I/O hardware directly. Note that as of NT 4.0, GDI drivers also run in kernel mode, but they have a substantially different architecture from the drivers we call "kernel mode drivers." In particular, operations to GDI drivers are normally synchronous; a GDI driver does not return to its caller until the operation requested by the caller has been completed, and the operation is performed in the context of the requesting thread, whereas just the opposite is true of kernel mode drivers. By contrast, kernel mode drivers usually implement functions that require waiting for an interrupt, waiting for a device to become available, etc. During such "waiting" periods the kernel mode driver simply returns to its caller, allowing the caller to perform other work in parallel with the I/O operation. Alternately, the caller can simply wait ("block") until the I/O is complete. This FAQ is mostly about kernel mode drivers. Other types of WNT drivers may eventually be covered in other FAQs, though I know of none at the moment. 1.3.4 What do you mean by "kernel mode"?"Kernel mode" refers to the more privileged memory access mode of the processor, "user mode" being the less privileged. This is a part of the processor's hardware state. On x86 processors, this "memory access mode" is known as the IO privilege level (IOPL); NT's kernel and user modes are IOPL 0 and IOPL 3, respectively. These are often colloquially called "ring 0" and "ring 3." NT does not use ring 1 or ring 2. On the Alpha the two modes are actually called kernel and user. Time spent in kernel mode is what many of NT's displays, such as Performance Monitor, report as "privileged" time. The term "kernel" is unfortunately and confusingly used in several different ways within Windows NT. For example, NT's operating system code is organized into several major components called the "executive," the "kernel," and the "HAL;" kernel mode drivers and GDI drivers also provide major aspects of the operating system's functionality. All of these components run in kernel mode. Yet a third use of the term "kernel" is in the terms "kernel APIs" and "kernel objects" in the Win32 APIs. Win32 defines several categories of "objects" that it works on and corresponding categories of APIs that work on those objects. "Kernel objects", and the "Win32 kernel APIs" that work on them, are those implemented by kernel mode components other than the GDI and and User routines in Win32K.Sys. 1.3.5 Does NT support Windows 9x-style VxD's?No. No, not even under WDM. On the other hand, Windows 98 supports a subset of the NT driver interfaces, with some extensions, known collectively as the WDM driver model. 1.4 So, how do I know if I need a kernel mode driver?If you have an I/O device for which NT doesn't have a driver, or for which the NT-supplied driver doesn't implement the functions you need, you'll need to find or write a kernel mode driver for your device. 1.4.1 But do I really need a kernel mode driver?This question usually appears something like this: Look, my little data collection app just wants to peek and poke at the parallel port now and then. Are you sure that I can't do this from my app, that I have to provide a driver and issue Win32 I/O calls instead?
To be rigorous about it, yes.
Under Windows NT, applications run in user mode (ring 3 on Intel),
and under WNT, code executing in user mode is not allowed to issue
1.4.2 I thought heard about a magazine article that showed a way around this.
There was indeed an article in Dr. Dobbs' Journal, May 1996,
that showed how to allow Win32 applications under NT to directly access I/O ports.
It works only on Intel platforms and is not really a counterexample
to the claim that "you need a kernel mode driver",
since it takes code running in kernel mode---supplied
by a kernel mode driver---to do the magic.
It does not allow you to service interrupts, initiate DMA, or do anything
else with the device other than read and write its I/O ports.
You can actually get that functionality with the
Nonetheless, I must say that the article describes a very nice bit of
NT kernel hacking.
Here is a
brief description of 1.4.3 What about VDDs? Don't they allow I/O access from user mode? How do they get away with it?They don't, really; they just help NT fool 16-bit apps into thinking they are doing I/O access. (See above.) 1.5 Okay, so I need a driver. But can I get away without writing a driver?Maybe. Depending on your requirements, there are commercial products that may allow you to avoid writing a driver for your device. (See the Related Products pages.)
These products each provide a kernel mode driver that implements a
variety of In general the I/O throughput of a device handled with the aid of one of these "general purpose, configurable" drivers will be lower than if it was controlled by a driver written specifically for the device, and the I/O calls the app needs to issue will be different from those implemented by a "real" purpose-built driver. However, the performance and functionality may be quite acceptable for many uses, and in any case these products provide a great way to exercise your hardware before a complete driver can be written. If you have more time than money, there are two example drivers supplied with the DDK that allow you to access I/O port and physical memory space:
Both of these drivers require some knowledge of NT kernel drivers to compile, install, and use, and are probably not something you want to put in the field as part of a production system. But they're fine for experimenting, they serve as good simple illustrations of many essential techniques for all drivers, and they can be useful starting points for your own development. 1.6 What about driver "wizards", class libraries, etc.?These do exist (see the Related Products page) and they have been in use for some time now with no significant problems reported in public forums. I offer just one caution: Don't let the "wizard" or class library fool you into thinking that you don't need to learn the underlying DDK interfaces; after all, that's the level at which you'll be debugging, and if you don't understand it, you won't be able to debug it. instead, use them as aids to learning those interfaces. Several posters to the relevant newsgroups have indicated that these packages were useful to them in exactly that way. top of page | up | previous | next | home |
||||||||