I am trying to get a conceptual understanding of the purposes the kernel modules can have. The motivation for this question was a realization that interface to an actual hardware goes through multiple kernel modules.

For example, the USB gadget driver has multiple kernel modules, where only one is used to actually communicate with the hardware. ( http://www.linux-usb.org/gadget/ )

What is the reason of implementing this "kernel module stack" structure? Doesn't it just complicate the process of getting a hardware device to work (you have to worry that you have 3 modules running instead of one)?


What is the reason of implementing this "kernel module stack" structure?

This is the way pretty much all software is written, in modular stacks. Consider your GUI: there's all the kernel space stuff involved including a driver stack, then in userspace you have the X server, and on top of that a window manager, and on top of that probably a desktop environment, and on top of that (e.g.) your browser.

That's a software stack.

The reason is fairly straightforward: consider the situation if there were no such userspace stack. Every GUI application would have to write it's own code interfacing with the kernel to access the screen, etc. Staying organized in relation to other GUI applications would be completely voluntary (read: a serious mess), the system's memory would be completely filled with redundant things, and almost no one would bother writing anything because of the immense amount of work involved.

The situation is exactly the same with same with kernel modules. A piece which can be put to more than one purpose must be an independent piece. So WRT to USB devices, rather than every driver having to build into itself a driver for the USB controller as well, you have one driver for the controller and individual device drivers interface with that.

Doesn't it just complicate the process?

No, it greatly simplifies it. True, you may have 3 modules involved instead of one, but if there were just one, it would have to implement the things the other two implement anyway.

There are many benefits to modular design and it is a fundamental tenant of software engineering. Strong modularity is essential to avoiding the sin of excessive coupling. I am sure if you ask anyone who has spent a lot of time programming that as they have gotten better at it and become more competent with larger and more complex projects, they have become more and more modular with their work -- i.e., they have grown to write smaller and more discrete pieces. This amounts to realizing that you will be better off with 3 parts instead of 1 whenever it makes sense to do so (finding "where it makes sense" is part of the skill -- the more places you can see, the better).1

If that seems counter-intuitive, consider what happens if a module, bigfoobar, misbehaves indicating a bug. Figuring out where it is will be much simpler if it is actually composed of three smaller parts, because you can independently test big, foo, and bar to determine which one is the culprit. Furthermore, foo may have a general use elsewhere (e.g., as part of altfoothing, but note that naming conventions don't really work that way). The more places foo is used, the more contexts it is subjected to and the more robust (functional, efficient, bug-free) it is likely to end up.

1. The further you look into a stack the more you will recognize it is composed of a regress of other stacks on a smaller and smaller scale. 90% (don't quote me) of the userspace code your CPU executes is actually part of the native C library, which is a relatively small executable. This is part of what makes it possible to run a wide variety of complex software efficiently -- because everything is made from the same few little pieces. Think about lego and the difference between having 5 big blocks or 50 smaller ones.

  • I understand the benefits of a stack in userspace, I was hoping that the device drivers are enough low level to tend to have a single driver per device implementation which implements the open() close() read() write(). – TheMeaningfulEngineer Mar 3 '14 at 16:38
  • Sure, that's about cohesion and kernel modules do work that way -- e.g., there are not separate drivers used to read and write to a filesystem. There's just the fs driver (but different ones for different filesystems). Perhaps there is a more specific question about a specific module you have in mind... – goldilocks Mar 3 '14 at 16:46
  • I'm interested in the Alsa driver stack, so once i figured it isn't just a get a single vendor supplied file to compile with your kernel kind of problem problem (cause i manged to do that). I wanted to check if I have the correct conceptual overview. – TheMeaningfulEngineer Mar 3 '14 at 16:56
  • I'd presume ALSA is at least two parts -- a general core which handles I/O from userspace and then a hardware specific part that fits together with that. Vendors rarely supply anything in whole to linux, the drivers are done the other way around (by linux for whatever, instead of by whatever for linux), although sometimes vendors do have there own alternatives (e.g. nvidia and ati ogl packages). – goldilocks Mar 3 '14 at 17:02

Consider e.g. a USB pendrive. There is a module which talks USB (interacts with the actual hardware), a layer handling this as a SCSI block device, general block device handling; and then a layer handling the actual filessytem which organizes the data on disk. Most of those can be actual Linux kernel modules. Others are layers that are fixed, but nevertheless separate.

Looking at this in isolation, it does look like overkill. But it has several benefits: First, if you consider the conceptual distance between "Give me the first 50 bytes of file foo.txt on the device" and "Toggle those pins exactly so" you'd see the need to divide this into smaller steps to be able to grasp it. Second, and much more important for operating systems in general, is that by slicing the stack this way you can use the exact same data organization on your pendrive, a floppy disk or a variety of hard disks. If a different filesystem comes along, you can again mix and match. Same thing for new types of devices (USB is a relative newcomer to Linux, this organization made it easy (for some weird value of "easy," to be sure) to add them seamlessly).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.