speakup, 2.6.22, and the way forward
Daniel Drake
dsd at gentoo.org
Wed Jul 25 23:06:33 EDT 2007
I guess only a few people know of me on this list. I'm the maintainer of
the Gentoo Linux kernel. We work very hard to keep the Gentoo patchset
minimal, i.e. bug fixes only. However, we have a small number of feature
patches still included, which I refer to as "historical artifacts".
speakup falls into that category.
For all those extra patches, I've been spending time on-and-off making
them more suitable for upstream, and eventually submitting them for
inclusion. For this reason, I've ended up developing speakup here and
there over the last 2 years or so.
Here comes a bit of a brain dump. I've ceased from speakup development
at least for the moment, but I do want to share some of my experiences,
technical knowledge and ideas.
It appears that little development has happened on speakup in the last
few years, in relative terms to the size of the codebase. Most of it,
and pretty much all of the core, was written a long time ago. Since
then, kernel code quality has improved, and the code quality
requirements for inclusion are slowly but continually rising. So, the
longer speakup bit-rots, the further it is from being included.
As someone involved with "modern" kernel code, to put it bluntly,
speakup is ugly and hard to comprehend. It also has numerous portability
issues.
Focusing on one particular technical area: how speakup accesses serial
ports and ISA hardware. As both serial and ISA are legacy busses, on x86
hardware you can perform I/O on such channels just by writing verbatim
data to somewhere in memory, or reading from another special location,
and you don't really have any further complications.
This is not true for any modern busses, which are generally more
complicated. It is also not true for ISA and serial on other architectures.
So, speakup is already fairly limited that it relies on the legacy of
the x86 architecture (which is maturing), and doesn't really have a "way
forward" in terms of hardware access for its current model.
This is why speakup doesn't work with USB-serial adapters. The protocol
to communicate over that adapter is of course the same, but because
you're talking USB, you can't just stream to some location in memory,
you have to deal with USB packets etc.
This legacy serial access method would probably be one reason for
rejection if we were to submit speakup to the mainline kernel before 2.6.22.
Now, 2.6.22 has removed the legacy way of accessing serial ports and now
makes serial appear like a more modern bus. speakup can no longer
function, because it can't find the memory addresses for the ports.
While working on speakup, it has been repeatedly frustrating because the
speakup code screams "do it in userspace". It's often much nicer to
implement things outside of the kernel where possible, and I think
speakup would be no exception.
Kirk is opposed to this, as understandably, if it's in userspace then he
can no longer hack on the kernel or diagnose early boot problems,
because there's no access to the text on screen. Nobody can argue with
this, except for the upstream kernel developers who require at least 2
things for kernel inclusion: a user base (which speakup has), and high
quality well-designed code (which speakup does not have).
On the other hand, the inability to do kernel hacking doesn't seem to be
such a big deal for most users. I understand that Ubuntu didn't even
kick speakup into action during kernel boot, neither in the initrd, but
actually midway through userspace startup.
How does the userspace argument relate to 2.6.22? Well, the only *clean*
ways that I can think of for making speakup work with 2.6.22 involve
userspace having to poke speakup into action.
First idea: create a speakup serial line discipline. Convert the speakup
synth drivers to using the tty layer to push/pull data to and from this
line discipline. This has the advantage that speakup can now be used on
all architectures, and would even work for USB-serial adapters.
The disadvantage here is that userspace is the entity which must apply a
serial line discipline to a serial port. i.e. something in userspace
must say "I want speakup running on /dev/ttyS0". It's an ioctl to do
this, if I remember correctly.
One example of something that does similarly is the serial input driver
layer (serial mice/touchscreens). The input layer has a "serio" line
discipline, and all serial drivers that work on other protocols can also
use this serio line discipline. Userspace (usually the X server or gdm)
applies the serio input discipline to the serial port it wants to use
when it wants to use it.
Second idea, building on the above: if such a design were acceptable, to
rely on userspace for speakup to work, maybe we can move much more out
of the kernel. Specifically, the whole serial port accessing code.
In this scheme, the speakup kernel part would export /dev/speakup or
similar, a simple stream of text which should be read aloud by the
synthesizer. Then, a speakup userspace agent would read this text,
reformat it in a protocol suitable for the synthesizer in question, and
write() it to a device node such as /dev/ttyS0.
Both of the above ideas require a decent amount of work, and I don't
have the time or interest to get further involved. Additionally, they
both violate Kirk's original design of being sufficiently low-level so
that the synth is still functional even when the kernel has crashed.
I hope this helps. Keep on fighting :)
Daniel
More information about the Speakup
mailing list