DJ laments there are no practical guides to driver writing.
DJ, allow me, as I so often do, to vocally disagree with you :). You seem to be making two closely related claims:
- There’s no information in OS textbooks on how to structure a driver to fit into any given operating system’s driver architecture
- There’s no information in OS textbooks on how drivers ought to interact with their hardware to make useful stuff happen
1. General operating systems textbooks are not the place to find this information, because if they were they wouldn’t be general operating systems textbooks.
Depth and breadth are usually a trade-off in books. If a book were so thorough and detailed in its treatment of Linux drivers that you could use it as your sole reference while writing one, it could not possibly do the same justice to drivers for Solaris, Free/Net/OpenBSD, AIX, Mac OS X/IOKit, Win32, WinNT, Vista, or any other operating system, and it surely can’t cover things like process scheduling, networking, virtual memory, filesystems, or any of those other things kernels sometimes do. The reason you read an operating systems book is to get a (necessarily) broad coverage of what all operating systems do.
If you want to get specific enough to one kernel and one subsystem that you can actually use it as a reference to build a driver, you probably want to put Modern Operating Systems back on the shelf and try Linux Device Drivers, a book focused on exactly what you see as lacking in general operating systems books.
Taking a mild divergence to head off a counterargument, it’s completely acceptable for the usual OS curriculum to exclude drivers, while including many other parts of operating systems, say, basics of concurrency. The difference in curriculum reflects the likelihood the average student will encounter the material during his career. The average programmer has very high odds of using concurrent systems sometime in his career, even more so today with the advent of multicore systems. Any more than the most basic concurrent programming (paranoid locks everywhere) involves some knowledge of what the OS is doing. In contrast, the average programmer will never be anywhere near driver code. Those who do write or maintain drivers take onto themselves responsibility to further research the field, the same way we expect those working with highly parallel systems to study a bit more than locks and semaphores.
2. I’m willing to accept that there’s little information available on actually driving hardware, but that’s because the information you’re looking for is very narrowly applicable, proprietary, distributed across the whole field, in rapid flux, and/or lacks any common principles or organization. Difficult to put that into a textbook with a ten- or twenty-year lifespan.
There’s so little information generally available about how to drive hardware because it’s intensely device-dependent. Once you get to the IO port level everything ends up pretty specific to the particular chip you’re talking to. Sure, ATA’s standard, so it’s not hard to drive a hard disk. But how about the ATA controller chip? How do you ask it to send a command and get the result? Not so standard.
The impression I get from the field (see disclaimer below) is that everybody kinda builds the hw/sw interface to be as simple as possible for the firmware and hardware guys to build. This varies fairly widely with different guys and different organizational knowledge. Firmware and hardware are extremely expensive and difficult to build correctly, and anything that can be simplified should be; anything that can be offloaded to (testable, debuggable, patchable) software should be. When everyone builds their hardware the way easiest for themselves and their organization and offloads everything else to software, everybody’s hardware will look completely different and will have completely different expectations of the driver’s role. Consequently, everybody’s drivers will look completely different.
A secondary reason for lack of standardization is that until recently most first-party drivers for mass-market hardware were closed-source. When your competitors’ specs are closed to you and your own spec is closed to them, standardization is just not possible. This is changing, though, and we’ll see what happens. There have also been notable exceptions, when an entire industry segment decided to stop being dumb and standardize. EHCI stands out as a shining example. (IDE/ATA/SATA as standard disk access might qualify, though they have their origins in ancient disk protocols defined by the operating system, not the disk vendor, and any disk had to meet that protocol or you couldn’t use it. Standardization was imposed by the OS, not agreed upon by the vendors)
In such an environment, OS books can’t really get any more specific than “Here’s how you read from or write to an I/O port” for the same reason they can’t really get any more specific than “Here’s how you read or write to a network socket”. To tell you how to use, say, FTP, is to tie themselves to today’s practice and take up paper and author’s time that could be better devoted to general principles of networking. They probably ought to describe PIO and DMA, for the same reason they describe IP and TCP. But the OS books are and should be mute on how to drive the hardware. Those rules are different between every chipmaker and every chip, and change every year and every rev. They belong in datasheets and reference manuals, not general textbooks.
Conclusion
For now, every operating system has a different driver architecture, so a general operating systems textbook can’t and shouldn’t devote too much attention to any given system. Furthermore, every piece of hardware has a different host interface, so a general operating systems textbook can’t and a driver reference book sometimes shouldn’t devote too much attention to any given piece of hardware.
The way to change this is for different kernels to agree on a driver architecture, or for different hardware makers to agree on a host interface. The first is not likely to change anytime soon; Linus is not about to chuck the bottom quarter of 2.6, Apple’s kernel team hasn’t shown signs of life lately, Sun still hates everyone, and Microsoft is still dumb.
What is changing is that host interfaces are standardizing. USB was a great leap forward in this regard. Other than the UHCI/OHCI misstep, EHCI means anybody’s host adapter works the same as any others, and device classes mean anybody’s device works the same as nay others. No more does every serial and parallel widget in the store need its own driver. Disk interfaces have long been standardized (out of necessity). I thought Ethernet NICs have a broadly-supported standard, but I can’t track it down.
Disclaimer: I’m very new to hardware design, I’ve never written a driver, and I’ve only been through the first-level undergrad operating systems course. I calls ‘em as I sees ‘em, but I may not see ‘em very well from where I stand. I welcome discussion.