--- Mike McCormack mike@codeweavers.com wrote:
Damjan Jovanovic wrote:
I've been trying to add STI (still image) support
to
Wine, and I've made some progress. However, I see
a
deep and unsurmountable need to add (at least user-space) device drivers to Wine, and I would
like
some feedback on these ideas.
Drivers belong in the kernel. If there's no Linux driver for a device, then Wine cannot support it. In that case, the first step is to write a Linux device driver for it, which has the added advantage that other native linux applications can use the hardware.
The interface from user space to kernel space should be done via standard Linux mechanisms, such as ioctl. The Video4Linux API already offers such an interface.
You can't load a Windows driver that accesses hardware in Wine, as Wine is a user-space application with no I/O privileges.
I am not trying to _load_ a Windows driver (that either requires kernel support for the Windows DDK, like ndiswrapper has, or emulation of an entire x86, like bochs does).
What I am trying to do is _replace_ a Windows driver with equivalent libusb functionality, getting, in effect, something like this:
Application (eg. the Gimp) | v special SANE backend | v SANE to TWAIN converter | v Windows user-space TWAIN driver (by manufacturer) | v STI | v Wine (with "drivers") | v Wine (user-space) driver | v libusb | v kernel
Mike
Damjan
__________________________________ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
I am not trying to _load_ a Windows driver (that either requires kernel support for the Windows DDK, like ndiswrapper has, or emulation of an entire x86, like bochs does).
Not really. It just needs some sort of device-class-specific forwarding protocol. usbfs and libusb already do that, and you should be able to run any windows driver that way without even touching the kernel. ndiswrapper does what it does because they want to expose non-usb devices and to the whole linux system at that. I.e. they support pci devices as well as usb. If they wanted to support usb only, it's all plain userspace. You can emulate network adapters in userspace using TAP or however it's called, and you can talk to arbitrary usb devices from userspace via usbfs and libusb.
In fact, for a wide variety of PCI drivers out there it should be perfectly feasible to provide a "short-circuit" kernel driver that could expose full access to a PCI device do a userland application, thus allowing wine to support arbitrary PCI devices as well. Considering that 2.6 kernel already has hardware abstraction that disconnects actual hardware accesses (like port/read writes and so on) from the logic of the PCI device drivers, it wouldn't be that hard to make such a gizmo.
http://vtun.sourceforge.net/tun/faq.html http://libusb.sourceforge.net/
Cheers, Kuba
On Sat, 2 Apr 2005 08:15, Kuba Ober wrote:
Not really. It just needs some sort of device-class-specific forwarding protocol. usbfs and libusb already do that, and you should be able to run any windows driver that way without even touching the kernel.
USB (along with SCSI) is a special case that because of its architecture can participate in such a forwarding arrangement for devices other than the hub or host controller device. Most other device drivers (and when I say device driver I mean the thing that drives the hardware) involve direct use of the input and output instructions of the CPU, and interrupts.
Now, you *could* trap the input and output instructions and emulate them via a kernel module, likely one involving entries in /proc to provide an interface for granting access to particular I/O ports and a file that could be used to access each device for which ports were made available.
Of course such a mechanism would be much slower than a native driver, and may run into problems with timing issues. Interrupts pose a particular challenge in that ideally the process handling the device should be activated immediately, and the Linux kernel currently provides no interface to say "switch to this task now" - the scheduler code simply does not provide for it (which is a shame, because a directed yield call with an associated call to return the remainder of the donated time slice(*) to the donor would be a "simple" way of radically improving the performance of anything that uses wineserver).
So, input an output instructions: possible but likely to be slow, sometimes unacceptably slow. Interrupts are more of a problem due to the inability to do a directed yield.
If you seriously want to attempt this, I would suggest your first port of call would be to the kernel list to discuss the possibility of implementing directed yield.
* - a directed yield call would allow the current thread to donate the remainder of its current time slice to another thread. The context switch occurs immediately. For maximum value, such a call effectively requires a companion call that allows that other thread to return any of the time slice it does not need to the donor, without necessarily knowing who the donor was.
On Mon, 4 Apr 2005, Troy Rollo wrote:
run into problems with timing issues. Interrupts pose a particular challenge in that ideally the process handling the device should be activated immediately, and the Linux kernel currently provides no interface to say "switch to this task now" - the scheduler code simply does not provide for it (which is a shame, because a directed yield call with an associated call to return the remainder of the donated time slice(*) to the donor would be a "simple" way of radically improving the performance of anything that uses wineserver).
Um, I'm fairly certain that rendezvous via any kernel synchronization mechanism (semaphores, condition variables, etc) will do exactly what you want. The blocked task goes to sleep and the rest of the time slice is preferentially transfered to the newly-active task. Such a mechanism is much more general than your proposed special interface, and accomplishes the same end. --scott
JMBLUG SARANAC MI6 mustard KUBARK quiche ammunition TASS ODEARL Mossad nuclear security SEQUIN KUHOOK Moscow shotgun TPAJAX jihad NRA Suharto ( http://cscott.net/ )
Hi,
On Sun, Apr 03, 2005 at 08:20:48PM -0400, C. Scott Ananian wrote:
On Mon, 4 Apr 2005, Troy Rollo wrote:
run into problems with timing issues. Interrupts pose a particular challenge in that ideally the process handling the device should be activated immediately, and the Linux kernel currently provides no interface to say "switch to this task now" - the scheduler code simply does not provide for it (which is a shame, because a directed yield call with an associated call to return the remainder of the donated time slice(*) to the donor would be a "simple" way of radically improving the performance of anything that uses wineserver).
Um, I'm fairly certain that rendezvous via any kernel synchronization mechanism (semaphores, condition variables, etc) will do exactly what you want. The blocked task goes to sleep and the rest of the time slice is preferentially transfered to the newly-active task. Such a mechanism is much more general than your proposed special interface, and accomplishes the same end.
Ah, right, THAT one was the main reason a direct yield is not implemented. The usual blocking architecture achieves the same thing.
Andreas Mohr
On Mon, 4 Apr 2005 10:20, C. Scott Ananian wrote:
Um, I'm fairly certain that rendezvous via any kernel synchronization mechanism (semaphores, condition variables, etc) will do exactly what you want. The blocked task goes to sleep and the rest of the time slice is preferentially transfered to the newly-active task.
I'm not sure where you got that from, but would appreciate any references. I know that a casual reading of some manual pages might suggest this, but that does not necessarily reflect the real in-kernel behaviour. The manual pages may mislead because it is not necessarily obvious to somebody who has not worked at the kernel level (or had the benefit of John Lyons' lecturing) that there is a difference between a process being "runnable" (ready to run or "awake"), and a process being in the "running" state (actually executing on a CPU). It also doesn't help that the "ps" command uses "R" for "runnable" and has no separate state indicator for "running".
The historical (UNIX) behaviour has always been that any processes waiting on the event merely gets woken when the event arrives, but that will only affect *whether* the process is considered for running, not *when*. The "when" part is normally "when the scheduler is good and ready" to run it.
If it were any different, a pair of conspiring threads would be able to starve the rest of the system (the directed yield/return to donor mechanism does not do that as the donee only gets time up until the original thread would have lost its time slice anyway).
I have not seen anywhere in the Linux kernel that behaves differently to this, and I can see nothing in the scheduler that causes or enables a determinative and immediate transfer of control to a particular thread.
On Mon, 4 Apr 2005 17:53, Andreas Mohr wrote:
AFAIR (some recent discussion?) there were good reasons for not implementing that, since it isn't all that helpful. But I'm not sure...
A reference to the discussion would be helpful - I can't find it by searching the ck list archive.
On Mon, 4 Apr 2005 17:55, Andreas Mohr wrote:
the main reason a direct yield is not implemented [is that] The usual blocking architecture achieves the same thing.
I think perhaps we are talking at cross purposes. In directed yield, the donor thread, which has access to the CPU until such time as it either yields or is pre-empted, donates that access directly to the donee thread. The donee thread immediately gets access to the CPU, and can return the CPU to the donor thread if it completes its task before the original thread would have been pre-empted. Ideally the time is charged to the donor rather than the donee.
As far as I can see, there is nothing in the 2.6 scheduler that does that.
Hi,
On Mon, Apr 04, 2005 at 08:58:32AM +1000, Troy Rollo wrote:
Of course such a mechanism would be much slower than a native driver, and may run into problems with timing issues. Interrupts pose a particular challenge in that ideally the process handling the device should be activated immediately, and the Linux kernel currently provides no interface to say "switch to this task now" - the scheduler code simply does not provide for it (which is a shame, because a directed yield call with an associated call to return the remainder of the donated time slice(*) to the donor would be a "simple" way of radically improving the performance of anything that uses wineserver).
AFAIR (some recent discussion?) there were good reasons for not implementing that, since it isn't all that helpful. But I'm not sure...
So, input an output instructions: possible but likely to be slow, sometimes unacceptably slow. Interrupts are more of a problem due to the inability to do a directed yield.
If you seriously want to attempt this, I would suggest your first port of call would be to the kernel list to discuss the possibility of implementing directed yield.
Nope, that should probably be the Con Kolivas list, since they do a LOT more about scheduling things.
An interesting experiment could be using a recent Con Kolivas kernel (2.6.11-ck3) and installing schedtoold and let wineserver run in isochronous scheduling (SCHED_ISO). Then try some "nice" games to see what happens...
Andreas Mohr