User-space device drivers
Driver authors - and their users - might have a much easier time if drivers could be written to run in user space. In addition to mitigating the above-mentioned kernel programming issues, user-space driver development would allow the creation of a stable ABI; it also, presumably, would eliminate any licensing issues associated with closed-source drivers. User-space driver writers could also use any language they choose, "even Python."
Peter and company have set out to make user-space drivers possible. Some of the necessary pieces are already in place. Standard Linux will allow a suitably privileged process to access I/O ports, for example. Low-address memory-mapped I/O registers can be accessed via a mmap() of /dev/mem. There is also an interface which gives user-space processes access to the PCI configuration space; this interface works via ioctl() calls on /proc files, though, thus upsetting the sensibilities of most kernel hackers. These facilities are enough to allow some user-space drivers (particularly XFree86) to work, but they are not sufficient to enable a wider range of drivers to move out of the kernel.
One of the big gaps is interrupts; there is no way, currently, for user-space processes to register and respond to device interrupts. A patch from the Gelato project addresses this gap by creating a set of files under /proc. A process wanting to deal with interrupt 11, say, would open /proc/irq/11/irq. Reading the resulting file descriptor enables the interrupt and blocks the process until a device interrupt happens; control then returns to user-space, which can figure out what to do. A typical user-space driver will set up a separate thread to wait for interrupts in this manner; the actual work can be handed off to a different thread within the program.
Peter presented some graphs showing that interrupt response times suffer very little when interrupt handlers run in user space. The main limitation at the moment seems to be the fact that shared interrupts are not supported.
Another thing that user-space processes cannot normally do is set up DMA operations. To enable DMA, a new set of system calls has been added. The interface appears to be in a bit of flux, but it will be something like the following. The driver starts by opening a special file for device operations:
int usr_pci_open(int bus, int slot, int function);
There is then a function for setting up DMA mappings:
int usr_pci_map(int fd, int cmd, struct mapping_info *info);
The cmd argument can be USR_ALLOC_CONSISTENT to set up a long-lived consistent mapping, or USR_MAP to create a streaming, scatter/gather mapping. In either case, the info argument is used to pass in the relevant information, and to get the necessary address(es). There is also, of course, a USR_UNMAP operation for when the DMA is complete.
Many user-space drivers will be able to obtain their requests directly from user space; the X server works in this way. Many other drivers, however, will need to hook into the kernel for this information. The current patch includes a mechanism (Peter described it as ugly) for a user-space block driver to register itself with the kernel and get I/O requests. It works by opening another special file and using it to communicate requests and responses back and forth. A similar interface apparently exists for network drivers.
Getting a user-space driver patch into the kernel could be an interesting challenge. Many kernel hackers, certainly, resist changes that look like they are pushing Linux toward something that looks like a microkernel architecture - or which might legitimize binary-only drivers. On the other hand, some drivers bring a great deal of baggage into the kernel with them which might be better kept in user space; think of some of the code required by some sound drivers or the modulation software needed by "linmodem" drivers. The ability to run these drivers in user space could be a nice thing to have.
See the
Gelato user-level drivers page for more information.
Index entries for this article | |
---|---|
Kernel | Device drivers/In user space |
Posted Jan 22, 2004 5:54 UTC (Thu)
by danshearer (guest, #18686)
[Link] (3 responses)
One of them is filesystems, which are a very logical thing to do in userspace. Peter's work doesn't address that at all. Years ago (back in 2.0) Jeremy Fitzharding (sp?) from Sydney did userfs, which let you do things like mount an ftp site. Some obvious fs candidates such as imapfs involve very long strings and according to (a) people who really know what they are doing and (b) my bumbling experiments, 64k strings are a *really* bad idea in kernel modules. Another one is virtualisation. Read Jeff Dike on pushing User Mode Linux into kernel space for some clues on where this might be going. Jeff articulates advanced architecture and design better than most, so it is worthwhile looking for his stuff. His idea in this case is to port UML from the current libc interfaces at the backend to kernel interfaces, something like a module. Think of it like IBM's VM with OSs running underneath that, and the kernel of each OS is in true kernel space but within that applications (drivers, in this case) are completely protected. --
Posted Jan 22, 2004 12:37 UTC (Thu)
by rjw (guest, #10415)
[Link] (2 responses)
Posted Jan 22, 2004 21:22 UTC (Thu)
by scripter (subscriber, #2654)
[Link]
http://sourceforge.net/projects/avf
http://www.freenet.org.nz/python/lufs-python/
Posted Jan 23, 2004 17:44 UTC (Fri)
by aleXXX (subscriber, #2742)
[Link]
Posted Jan 22, 2004 19:53 UTC (Thu)
by stuart2048 (guest, #6241)
[Link] (2 responses)
Posted Jan 23, 2004 20:45 UTC (Fri)
by jonabbey (guest, #2736)
[Link] (1 responses)
Posted Mar 9, 2004 3:13 UTC (Tue)
by PeterChubb (guest, #20062)
[Link]
In the case of a kernel mode driver, the same faults often require a reboot...
Posted Jan 29, 2004 16:04 UTC (Thu)
by HalfMoon (guest, #3211)
[Link]
This Gelato approach would seem to be focussed on a particular
style of userspace driver, which works on non-virtualized devices.
Specifically, it aims for PCI (or ISA) style devices, where
the device driver needs to touch "real hardware".
USB is a good example of a different style driver, one where
the device driver can't touch the hardware. In fact you can
view USB drivers as the clients in a client/server framework,
with the "server" being the device.
The bus is really a special purpose network link, used to
exchange packets between device and host.
(And always initiated by the host, not the device/"server".)
So userspace USB drivers
work with virtualized devices ... they start with a formalized
protocol to talk with the hardware, which doesn't involve
register access, IRQs, or memory mapping except indirectly.
There are two approaches right now to userspace USB drivers.
There are discussions underway to create "usbfs2", which
should eventually replace "usbfs".
It'll look much more like gadgetfs than "usbfs", with few
ioctls and using the standard AIO framework.
So that's something else to keep in mind. This Gelato
framework doesn't seem like it'd work well with USB, or
with other device models that have already upleveled and
virtualized their hardware.
Posted Jan 30, 2004 14:20 UTC (Fri)
by forthy (guest, #1525)
[Link]
The interrupt delivery part is something that has been necessary for
years, because X still can't give you any way to syncronize to VBL
interrupts (except OpenGL). On the other hand, I don't feel too happy with user land directly
accessing IO ports. This is still dangerous, and buggy X drivers often can
hang the machine, too. Memory mapped IO pages should be ok, given that the
kernel would allow to map the PCI memory per device, not from /dev/mem. I
suggets to keep the IO port part of a device driver inside kernel space.
p>
Posted Jan 30, 2004 16:16 UTC (Fri)
by joib (subscriber, #8541)
[Link]
Posted Jun 19, 2007 8:35 UTC (Tue)
by Jel (guest, #22988)
[Link]
Presumably the server side was basically just registering a message queue,
This wasn't a memory-protected kernel, but if we're talking userspace
Why not use a model like this?
There are several threads hanging out of the "drivers in userspace" tangle.User-space device drivers
Dan Shearer
dan@shearer.org
Google for FUSE and LUFS for the most active user space FS projects. FUSE even has a bridge allowing the use of KDE IO slaves as a mountable filesystem.
User-space device drivers
http://uservfs.sourceforge.net/
User-space device drivers
You can find some information about the kioslave-fuse bridge at: User-space device drivers
http://kde.ground.cz/tiki-index.php?page=KIO+Fuse+Gateway
And yes, it works, loading and saving files via konqueror in OOo or gimp
using ioslaves and fuse :-)
You can also contact me directly: neundorf@kde.org
Bye
Alex
What fun! Back in the days of "who's got the fastest IPC" my master's thesis project, the Raven Kernel, was based on a user level approach (for as much as I could get away with...).
User-space device drivers
I did interrupt dispatching quite differently than Gelato. In Gelato, a user thread "reads" interrupts from an open file descriptor. In Raven, I took a more asynchronous approach: the kernel interrupt handler upcalls into the user driver (essentially interrupting the user code), where it then directly executes the handler code to service the device.
My motivation here was to make the user handler code execute with as low latency as possible. There were some tricky corner cases to implement, but I eventually got it working. ;-)
But after all that, I much prefer the simplicity of Gelato's approach and will stay tuned to their progress!
--Stuart
Snare's userland audit daemon works in the same way Gelato does.. it loops reading audit events from /proc/audit. This method has the very great virtue of simplicity and it can actually be quite fast and efficient.
It'll be neat to see where this goes for user mode drivers, but I wonder what happens if a user mode driver fails? Would the kernel be smart enough to stop preparing the data for the driver? I know when the Snare audit daemon closes /proc/audit, the kernel notices that it has been closed, and amends its behavior to avoid queueing up additional audit events.
User-space device drivers
When a userland driver fails, just kill it and start again. You may lose a few packets (for a network device) or any transactions that are halfway throough (for a disc device), but in most cases, this can be recovered from.User-space device drivers
USB is different
User-space device drivers
IIRC the Plan 9 operating system allows user-space device drivers. They reason they did that was to bring the development advantages of microkernels described in this article, and then by loading the hopefully debugged driver into the kernel proper the speed benefits of a monolithic kernel are available. I think the point was that the same device driver code could be used for both, though a recompile is almost certainly needed?
User-space device drivers
This all sounds pretty horrible. Back in '83 or '84, the Amiga came out, Event-driven API
with a much nicer, event-driven device API. At least from the client
side, it was just a matter of sending events. So, say, for the narrator
device, you would send something like { SET_PITCH, ..., 2000 }, and it
would set the pitch of the speaker's voice. This was asynchronous of
course, so it worked really well with devices like SCSI units/buses.
and waiting for instructions.
anyway, then it shouldn't matter. The OS was fully multitasking, and
fairly real-time for the day, as I understand it.