Hi,
A few weeks ago I did some work to support our USB device driver stack
in userspace. It's at a point where it works enough for casual playing.
Since I won't have any time to work on it more in the coming few weeks,
I'm posting this quick howto now.
what:
ugen provides access to any USB device via a generic interface.
I wrote a fake host controller which talks to the kernel driver stack
the regular way, but passes requests to ugen. This way we can use the
kernel device driver stack in userspace. As a picture the stack looks
a little like this:
application
some driver(s), e.g. sd@scsibus R
more drivers, e.g. umass U
uhub (sys/dev/usb/uhub.c) M
userspace rumpusbhc (rump/dev/wip/librumpusbhc) P
kernel ugen
ohci/ehci/uhci
hardware usb
I've tested sd@umass to be functional enough so that I can mount a
file system off of it an access it. Also, if_rum works enough to be
able to probe, load the firware, and raise the interface up (however,
since the driver doesn't really work even in the kernel for my hardware,
I haven't pursued rum much further).
how:
Nothing is installed by default for now. You need to compile and
install all the libraries under sys/rump/dev/wip (in each of them, make
dependall && make install). After that, some applications are required.
For examples, see src/share/examples/rump. sdread shows how to mount
a file system and access it. wirelessconf shows how to send commands
to the interface and also how to make sure the device driver running in
rump can access the firmware image on the host system.
Other USB devices may or may not work. But since failure results in
an application core dump, well, you won't lose much if they don't.
Currently the autoconf glue must be written by hand, but the examples
in rump/dev/wip/libumass and rump/dev/wip/libusbrum can pretty much be
easily copypasted and modified to suit other needs.
You also need to convince ugen to attach at a high priority. This can
either be done by passing "flags 1" to the driver, i.e.
"ugen* at uhub? port ? flags 1" in the kernel config. Additionally,
on -current, you can set the kernel variable ugen_override to 1 to
control behaviour at runtime. While testing, I noticed that ugen
occasionally gets "stuck" after a crashing test case, so if the device is
suddenly not responding anymore, unplugging and replugging it might help.
why:
For one, it's nice to be able to play with kernel USB device drivers
without crashing the kernel. For two, it allows to support a more
complete software stack in rump (e.g. you don't really need if_virt
to multiplex on /dev/tap anymore to virtualize the networking stack --
you can use real hardware ... if you want to). For three, you can use
drivers from other versions of NetBSD (e.g. I use -current on 5.0).
I'm sure there are other reasons too ...