Digivation Lucent Linmodem Information

Team

Mark Spieth general keeper of repository and main code maintainer. This is me.
Marvin Stodolsky defacto project manager, build script and documentation maintainer.
Main question answerer and general wizard who has patience.
Talk to marv first ;-) (sorry marv)
Russell Nelson Mailing list maintainer
Jacques Goldberg Mailing list archives and linmodem site maintainer
Christoph Hebeisen Maintainer of many web pages, package and code contributor
Alexei Chentsov 2.6 contributor

Apologies to anyone omitted

Disclaimer

DISCLAIMER: This software comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Therefore no liability will be assumed for any damage including (but not limited to) system crashes, loss of data, hardware failure, loss of business and all other direct or consequential damage that may result from the use of this software.

Linmodem mod goals

The goal of the linmodem patches is to provide a self-contained build package that does not require kernel source to build.

Better description exist, especially on heby's pages. See links. This page exists mainly to share the technical details of the tricks used to adapt someone else's proprietary code with a generic base. I hope you find them useful.

Structure

Agere Systems (previously Lucent Technologies) has kindly made available a driver which forms the basis of the package. It currently consists of a prorietary binary only component and 2 open source components serial.c and ltmodem.c. serial.c is different for each major kernel version. To differentiate these they were called serial-lt-2.#.c. A common makefile and configure script exists to perform the build with the correct components.

Old Structure

Prior to the nice mixed proprietary/open source version, agere supplied a precompiled kernel module which was specific to a specific kernel. Fixscript was created to convert the module to the kernel in question.

Tricks developed and used

Fixscript

Fixscript is a useful little utility script which changes symbols in kernel modules so that they match the symbols expected by the kernel. It also changes the kernel version in the module to the current runnig kernel.

It is written in bash and requires objcopy from the binutils package to perform its magic as well as awk, cut, sed, tr.

Note that the symbol name changes do not modify structure definitions so extreme care must be taken to ensure the common structures between the kernel and non-matching modules are the same. If they aren't, it will most likely crash the kernel at some stage.

download fixscript v1.9 here
There is also an updated version fixscript2 v1.10 here which supports the newer vermagic kernel versioning system.

The key to making this successful is to examine the kernel headers used between the version used to compile the module and the kernel version you wish to use.
Any structures, such as tty, must be made to match in the new version.
The most common changes is for the kernel maintainers to add fields in the middle of the structure.
These new fields should be kept but moved to the end of the structure os that the field offsets are the same in both kernels.
Then after these changes have been made, you need to build a new kernel with this new structure alignment.
This will work for any proprietary module.
The key is to identify the structures used.
nm is useful in determining which kernel functions are used.
The prototypes for these functions will tell you what structures are used.
From then on its relatively easy to figure out which ones have changed and then fix them.

Symbol hijacking

This is a method add features to a proprietary binary function. It is used primarily to override the x_input function in the proprietary part to allow for the disabling of line sense, which doesnt seem to work on some hardware implementations.

byte x_input( byte mode )
{
        byte rv;
        rv = x_input_orig( mode );
        if (ignore_line_sense)
        {
                if (mode == 0x39)
                        rv = 0;
        }
        return rv;
}

objcopy is first used to make x_input a weak symbol so it can be overridden. Also since the object uses memset, we need to replace that with a call to our own ltmodem_memset as memset is not a function in most kernels, but an inline function which is not linkable.

objcopy -W x_input --redefine-sym memset=ltmodem_memset $(BINARYOBJS) xxx.o

The linker is then used on the proprietary obj file to rename the symbol x_input to x_input_orig, with the new x_input calls.

ld -r -defsym x_input_orig=x_input -o xxx.o xxx1.o

Both the objcopy and the ld stages are required. The first one makes x_input weak. The second stage changes the definition of x_input to x_input_orig, but doesn't change the references to the new symbol. redefine-sym in objcopy renames all instances including references and definitions.

Here is another piece of test code which provides an additional ati command.

objcopy -W at_i $(BINARYOBJS) xxx.o

ld -r -defsym x_ati_orig=x_ati -o xxx.o xxx1.o

The following code segment shows how this can be done.

void at_output_msg(const char *s, int len);
void atparse_cmd();
void at_i_orig();
extern char * at_cmd_ptr;
void at_i()
{
        extern char * at_cmd_ptr;
	static const char * ati_excl_str = "linmodem";
        if (*at_cmd_ptr == '!')
        {
                at_cmd_ptr++;
		at_output_msg(ati_excl_str,strlen(ati_excl_str));
                atparse_cmd();
        }
        else
        {
                at_i_orig();
        }
}

atparse_cmd is called after our new "ati!" command is handled so any other commands on the same line are handled too, the original at_i function is called if it is not the new character sequence.

2.6 issues

2.6 kernels have a new feature for kernel module building called modpost. modpost is still in flux and is not provided as yet as a part of a no kernel source package. Thus it has been incorporated into the main ltmodem package so that 2.6 builds happen correctly.

asmlinkage

The newer (8.30+) proprietary modules are compiled with gcc 3 which defaults to no regparm parameter passing. However, gcc 2.95+ defaults to regparm for all kernel builds. Also some 2.6 kernel packagers, notably fedora core, also use regparm. Thus to use these kernels with this module, an interface is required. This means that all functions exported from and called by the proprietary module must be marked as asmlinkage. Due to the use of timers, a timer callback interface is also required.

Interrupt and SMP locking issues.

These are still not fully resolved. The main program that exposes this is hylafax. Currently investigating (17/7/2004). This is not kernel related. Anyone with good ideas or patches, please let me know.

Links

last updated: 17 July 2004