beep.o is a loadable module that puts beep support
into the process level, and out of the kernel. It allows an
application (or daemon) to determine when the kernel has requested a beep,
and handle it in whatever manner is desired. Of course, one
way of handling it might be simply to ignore it. Another might
be to convert the beep into an audio operation on the soundcard.
/proc/beep, and any read operation on
this file blocks until a beep has been signalled. It is thus possible
to generate the new beep sounds, if necessary, just using a
few lines of shell script.
kd_mksound. For example:
cat /proc/ksyms | grep kd_mksoundIt probably won't be (it's not the default), but it's worth checking because you won't need to recompile the kernel if the symbol is exported.
If you don't find the symbol, you'll need to reconfigure and
recompile the kernel. This isn't the place to explain how to
recompile a kernel. The required modifications are very simple:
just add the following lines to the end of
/usr/src/linux/kernel/ksyms.c
and rebuild and redeploy the kernel.
You don't need to recompile any modules, just the kernel itself.
I haven't supplied a formal kernel patch because the modification
is so trivial.
extern void (*kd_mksound)(unsigned int count, unsigned int ticks); EXPORT_SYMBOL(kd_mksound);When you've rebooted, check that the symbol is exported, as described above. Give me a call if the procedure I have described does not cause the symbol to be exported. If you have module versioning turned on (this is the default), then you can expect a dummy version number to be appended to the real symbol, but it should still be recognizable.
Now compile and install the module. Unpack the archive into any handy directory, and check the directory settings at the top of the Makefile. These determine where the installed module, shell script and sample beep sound go. When you are satisfied with these, do
make clean make make installThe most important file created by this process is the loadable module itself,
beep.o.
You can load the module like this:
modprobe beepIf this is successful then you should find that the ordinary console beep has disappeared. This is because it's been seized by the beep module. If you get `unresolved symbol' messages from
modprobe,
please contact me.
In another console do
cat /proc/beepThis should simply wait until something happens that would normally cause a beep. The
cat command will return immediately,
when a beep is generated, outputting a pair of numbers. The first of
these is the requested beep frequency in Hz, the second the requested
beep duration in timer ticks (18 ticks to the second). It's up to you
whether your user-level process honours these values or not. In
practice, most software just asks the kernel to give a default beep,
so they probably aren't important.
Where you go after this is up to you, to a large extent. This package
contains a simple shell script `beepd' which uses the `play'
utility to play a wav file when a beep occurs.
If you don't have `play' or similar, the simplest was to get a
beep sound is probably just to
cat an audio file to /dev/dsp.
beep.o works by redirecting the kernel symbol
kd_mksound into a handler in the module. This redirection is
made when the module is installed, and reversed when it is
unloaded. Unloading therefore restores the normal beep. This
symbol is not exported by default from the Linux kernel, so
it necessary to add the EXPORT_SYMBOL line described
above.
The function kd_mksound is defined in the Linux source
in drivers/char/vt.c. If you look at this code you'll
notice that it explicitly controls the speaker hardware.
The beep.o module creates a new /proc file
called beep. When an application process reads
this file it is simply put to sleep. I have been careful that the
blocking consumes no CPU resources and allows the kernel idle task
to continue to run. The application is woken up when anything -- in
the kernel or elsewhere -- calls the function kd_mksound.
Normally this will be because the application has made an
ioctl request on the console driver to generate a beep.
The module wakes up the process, whose read from
/proc/beep then completes. The read contains the beep
frequency and duration requested by the application or the kernel.