So, you’d like to write a Windows kernel mode driver? No? Well, run along then.
Curious though? Then read on.
I’ve always loved system programming – for some reason the interface to hardware is just so much more exciting and appealing than pure software API interfaces. You have a complex machine at your disposal, which can only be directed by an arcane sequence of carefully executed reads and writes to its control bits. Of course some hardware can be really exciting and fun to use (e.g. Nintendo Gameboy Advance was an excellent platform), and other interfaces can be pretty grueling and boring (My least favorite so far is the I2C hardware on the NXP LPC1342), but it’s always a great feeling to write a bunch of commands and have the hardware smoothly execute the complex maneuver you have prepared. Most of my experience in system programming has been on embedded platforms, microcontrollers, game consoles. The hardware in modern PCs is actually surprisingly similar, though because of the architecture differences, devices use DMA more often for efficient access.
It’s actually really simple to get going with a new driver on Windows – not that the system is simple, Windows drivers are very complex – they can run on multiple versions of the Windows kernel and are required to participate in some level of the system’s power management system, so there’s a lot of arcane details at play – However, there are various driver frameworks which handle all of these details for you, allowing you to focus on just the functionality you care about.
In this multi-part series I’m going to walk through the process of building a new driver (using WDF/KMDF), getting it to load on hardware (a PCI Express device), and receiving usermode requests and programming the hardware to do something. Eventually I’ll repeat this with some other frameworks (I have NDIS and Storport in mind)
This isn’t hard, but it is obscure and a bit arcane so it’s not a path that I believe is visible to new driver developers. The documentation is pretty thorough but the massive breadth of detail in Windows kernel driver development can be daunting for a newcomer.
Note also that I don’t intend to showcase all the pitfalls of driver development here, but I’ll mention some of them as they’re relevant.
One final side detail is that I’m currently employed by Microsoft. To be clear, though, this series is the product of my own time using publicly available information which I’ll try to link extensively. I’m fortunate to have had a lot of opportunities to learn these details in my work and I’m eager to make it easier for others to get started. There’s a daunting amount of information available, often written with the assumption that you’re familiar with the space (which you soon will be, given a few early steps into driver development)
So, without further delay, this is Part 1: Building and loading a driver.