UIO: user-space drivers
Like the previous version, UIO does not completely eliminate the need for kernel-space code. A small module is required to set up the device, perhaps interface to the PCI bus, and register an interrupt handler. The last function (interrupt handling) is particularly important; much can be done in user space, but there needs to be an in-kernel interrupt handler which knows how to tell the device to stop crying for attention.
The kernel module includes <linux/uio_driver.h>. If it's a driver for a PCI device, it should register itself as a PCI driver in the usual way. When it comes time to connect a device (perhaps in the PCI probe() function), the driver fills in a uio_info structure:
struct uio_info { char *name; char *version; struct uio_mem mem[MAX_UIO_MAPS]; long irq; unsigned long irq_flags; void *priv; irqreturn_t (*handler)(int irq, struct uio_info *dev_info); int (*mmap)(struct uio_info *info, struct vm_area_struct *vma); int (*open)(struct uio_info *info, struct inode *inode); int (*release)(struct uio_info *info, struct inode *inode); /* Internal stuff omitted */ };
Here, name is the name of the device and version is the driver version (which will show up in sysfs). The number of the interrupt used by the device (if any) goes into irq, with irq_flags being the flags which will be passed to request_irq(). The function which handles interrupts is handler(). This handler should acknowledge the interrupt; it usually does not need to do anything else. The mmap(), open(), and release() functions are called from the equivalent file_operations members.
The mem array describes any memory areas which can be mapped into user space. The uio_mem structure looks like:
struct uio_mem { unsigned long addr; unsigned long size; int memtype; void __iomem *internal_addr; /* ... */ };
For each mappable area, addr is the relevant address, and size is the size of the area. If it's an I/O memory area, internal_addr is the address returned by ioremap(). The memtype field describes what the area really is:
- UIO_MEM_PHYS indicates that addr is a physical
address, generally for an I/O memory area.
- UIO_MEM_LOGICAL is memory in the kernel logical address
space, such as that returned by kmalloc().
- UIO_MEM_VIRTUAL is memory in the kernel virtual address space - the space used by vmalloc_user() and friends.
Once the structure is filled in, the driver stub passes it to:
int uio_register_device(struct device *parent, struct uio_info *info);
The parent pointer tells the kernel which "real" device is associated with the UIO device; if the driver is for a PCI device, parent will be pci_dev->dev.
There is not much more to the kernel-space UIO API. When a device goes away, the driver should call:
void uio_unregister_device(struct uio_info *info);
The final function of note is:
void uio_event_notify(struct uio_info *info);
Its purpose is to notify the UIO core that an event (typically an interrupt) has occurred. The stub driver need not call uio_event_notify() for real interrupts, but it can be used to simulate interrupts in other situations.
On the user space side, the first UIO-handled device will show up as /dev/uio0 (assuming a normal udev setup). The user-space driver will open the device. Reading the device returns an int value which is the event count (number of interrupts) seen by the device; if no interrupts have come in since the last read, the operation will block until an interrupt happens (though non-blocking operation is supported in the usual way as well). The file descriptor can be passed to poll().
The memory areas described by the kernel-space driver can be mapped into user space with the mmap() call. The interface is just a little strange: the offset value passed to mmap() should be N times the page size for the Nth memory area. So, on a system with 4096-byte pages, the first memory area will be found with an offset of zero, the second at 4096, the third at 8192, etc. Once that is figured out, though, everything is pretty straightforward.
There are some limitations, of course. UIO drivers are char drivers; there is no provision for creating user-space block or network drivers at this time. It is not possible to set up DMA operations from user space. But, for drivers which can be implemented with I/O memory access and simple interrupt handlers, the necessary pieces are in place. The patch set includes an example driver to show how it all works. According to Thomas Gleixner, the original, fully in-kernel version of the driver had to implement 68 different ioctl() commands and was over 5,000 lines long. The associated user-space code was over 3,000 lines as well. The new driver eliminates all of that, with a total of 156 lines of kernel code and just under 3,000 lines in user space.
Andrew Morton has expressed some reservations about the patch:
The authors respond that it's not really about doing proprietary drivers,
though some of that will undoubtedly go on. There's a number of people,
especially in the embedded space, who want to do user-space drivers, for
prototyping purposes if nothing else. The UIO framework gives them a
relatively safe and standard way to write these drivers, which is seen as
being better than having them each create their own kernel hooks. The
patch has not been merged as of this writing, but, unless stronger
objections arise, it's chances of getting into 2.6.22 are reasonably good.
Index entries for this article | |
---|---|
Kernel | Device drivers/In user space |
Posted May 3, 2007 20:06 UTC (Thu)
by xav (guest, #18536)
[Link] (12 responses)
Posted May 4, 2007 14:43 UTC (Fri)
by nlucas (guest, #33793)
[Link] (7 responses)
This dangerously seems like an atempt to be able to create proprietary drivers and bypass the GPL.
On one hand I understand the good of having user-space drivers, but on the the other hand I don't see how that can be done and not create this loophole.
Posted May 4, 2007 16:11 UTC (Fri)
by zlynx (guest, #2285)
[Link] (2 responses)
It depends on if your goal is to write an excellent, open OS kernel or to force all software in the world to become GPL.
Posted May 4, 2007 17:19 UTC (Fri)
by nlucas (guest, #33793)
[Link] (1 responses)
The kind of user-space drivers people were doing don't compare with the drivers you will be able to do, even if you probably can't do a user-space graphics driver.
Also note that I'm not a GPL zealot, but I agree with the "doomsday scenario for linux in a binary world" (OTOH I don't buy the "stable API nonsense").
Other than that, I don't have problems running the nvidia drivers at my home PC (the few games I still play need 3D).
Posted Oct 19, 2007 3:22 UTC (Fri)
by ofranja (guest, #11084)
[Link]
Posted Jun 5, 2007 10:15 UTC (Tue)
by hjkoch (guest, #45353)
[Link] (1 responses)
Posted Jul 29, 2007 21:43 UTC (Sun)
by vphirric (guest, #32877)
[Link]
Posted Oct 7, 2009 9:55 UTC (Wed)
by etienne_lorrain@yahoo.fr (guest, #38022)
[Link] (1 responses)
Probably only me, probably because IANAL, but I fail to see how an UIO driver would not be a derivative work of the kernel.
Posted Oct 7, 2009 18:28 UTC (Wed)
by dlang (guest, #313)
[Link]
if it was then every windows program would be derived from windows (after all, what other OS implements those system calls? SAMBA doesn't count as it is explicitly a copy of the windows API)
as such the license of the kernel is irrelevant for UIO simply because it is userspace and is using the defined interface.
Posted Jun 5, 2007 10:01 UTC (Tue)
by hjkoch (guest, #45353)
[Link] (3 responses)
Posted Jul 23, 2007 5:54 UTC (Mon)
by ringerc (subscriber, #3071)
[Link] (2 responses)
Some printer drivers are implemented in userspace and are not GPL. The Samsung monstrosity recently covered by LWN is one such example. Another is the CUPS filter & backend shipped with the Xerox CentreWare suite, which is a living fossil, complete with dropping its self into random bits of /usr . This issue concerns me too. On one hand, I'd prefer a closed source driver to no driver much of the time. On the other hand, if it's a bad driver it's not much better than no driver at all, and lacking the ability to fix or debug it because it's just a binary blob would be seriously annoying. Hopefully this won't lead to a large surge in closed source userspace drivers. Still, if it does, at least they'll have to work harder to bring the machine down.
Posted Oct 10, 2007 2:36 UTC (Wed)
by Richard_J_Neill (subscriber, #23093)
[Link] (1 responses)
For example, I bought an expensive ($500) fast 32-bit parallel I/O card 4 years ago, which claimed to have Linux support. This turned out to be "but only on RedHat 7.3 with the default kernel". In the end, we threw out the hardware. Actually, we replaced it with another "Linux-supported" hardware item, called a QuickUSB. This also had only a binary driver, but it used libusb, and we were able to reverse-engineer it to write a GPL-driver. (But it still wasn't good enough in the end).
Posted Oct 6, 2009 9:07 UTC (Tue)
by Nisok (guest, #61161)
[Link]
Posted Sep 3, 2009 1:48 UTC (Thu)
by wangting@gmail.com (guest, #60495)
[Link]
Posted Dec 13, 2009 19:38 UTC (Sun)
by nixscripter (guest, #62488)
[Link]
If you can memory-map to RAM on the PCI bus now, you could just mmap() to a buffer under the driver's control instead. It could have not only device RAM, but also a flag for "interrupt occurred", which the application would clear, and a kernel space interrupt handler would set. You don't need a userspace interrupt handler at all.
"But that would be incredibly slow!" Yes, it would. And if you want more drivers for Linux, but don't want proprietary ones taking over, then offer a choice: userspace, closed source, and slow; or kernel space, open source, and fast. If that hardware engineer doesn't know about kernel hacking, then he should make it open source, and it will be fixed by people who know the kernel inside out. That's the idea behind an open-source project, right?
However, for those less political, UIO does seem a good solution.
Posted May 5, 2017 7:01 UTC (Fri)
by shankun (guest, #115471)
[Link]
People in the embedded space don't do prototypes. They hack something until it works, then it's done.UIO: user-space drivers
I'm with you. It sounds more like an excuse than a real reason.UIO: user-space drivers
So what if people do use it to bypass the GPL? Developers were doing user-space drivers *anyway*. And doing it badly in most cases.UIO: user-space drivers
UIO: user-space drivers
UIO: user-space drivers
Companies which do not want their work to become GPL'ed just need to make
a tiny little "wrapper" driver inside the kernel, and then implement
everything that matters in the userspace. In some (not to say many)
scenarios, this approach actually is much better and saner than
implementing everything in the kernel driver.
BTW, one thing "home Linux users" should remember is that Linux is not
strong in the home PCs as it is strong in the server market. Many
companies in that scenario do not care about openess of some driver, as
long as it works and/or you (the seller) fix it in case it breaks.
Sometimes they prefer not having the source code and buy from someone who
is more expensive, because the solution is better and more complete.
IMHO, keeping this UIO infrastructure out of the kernel fearing a "binary
takeover" would be like keeping FUSE out of the kernel fearing
"proprietary filesystems" from taking over Linux: something we should not
be afraid of.
And that's it.
As one of the main authors of UIO I can tell you that license issues were UIO: user-space drivers
never an important topic in our discussions. Our judge and jury is Greg
Kroah-Hartman, who is certainly not in favor of proprietary drivers. Our
target audience are programmers in industry, who have to write a driver
for an exotic card that could never make it into mainline. They're neither
kernel experts nor do they write good code (they don't have the time).
With UIO, they can let somebody else write the 150 lines of kernel code,
which _has_ to be GPL, and the big part can be done in userspace, with the
same tools and knowledge needed for their application, anyway. Yes, in
userspace it's possible to choose a different license, but that's not
UIO's fault or intention. It's been like this since Linux exists.
Hear hear -- and may I also add that there are lots of specialized little hardware widgets that need software control that simply do not present a character- or block- device paradigm. If your widget is some bizzare one-shot FPGA interface or the like, the existence of this kind of infrastructure is huge help. Thanks much!UIO: user-space drivers
UIO: user-space drivers
That would obviously be different if this interface was implemented in *BSD, Solaris, Windows... but I do not see that being the intent.
And implementing a GPL layer to connect a non-GPL driver would not change that the non-GPL driver is a derivative work of a GPL driver, which is a derivative work of the kernel.
Now if the law were applied...
UIO: user-space drivers
Yes. And if it's an in-kernel driver, they either violate the GPL and/or UIO: user-space drivers
hack up something completely unmaintainable. UIO gives them the
possibility to do the dirty part of the driver in user space, and it can
simply become a part of their application. They can use the tools they
know, and don't have kernel version issues. And they can choose any
license they want for the userspace part. BTW, all userspace drivers I'm
aware of are GPL.
Printer drivers
It should also be easier to reverse-engineer a userspace driver by just watching what it does. What is *really* nasty are binary drivers with a dependency on a specific (usually 3-years obsolete) kernel version.Printer drivers
Printer drivers
Could you please give me these GPL drivers?
UIO: user-space drivers
UIO: user-space drivers
UIO: user-space drivers