[pvrusb2] Disagreeable symbols and CONFIG_MODVERSIONS
Mike Isely
isely at isely.net
Sat Dec 10 01:48:25 CST 2005
I think I've figured out the last piece of this puzzle.
When CONFIG_MODVERSIONS is in use, the kernel build system generates these
per-symbol CRCs by taking into account every aspect related to the
symbol's declaration - like its argument types, the definition of those
argument types, the return type, etc. This is done for each symbol
exported by a module (a definition) and for each symbol that needs to be
imported into a module (a declaration). The idea here is to make sure
that the symbol has been defined in precisely the same way it has been
declared. If the declaration and definition disagree, then their CRCs
won't match and the module loader catches this, prints that nasty message
and aborts the load of the module in question. Obviously if a symbol's
declaration and definition do not match, then there may be an
incompatibility and this is how the kernel CONFIG_MODVERSIONS mechanism
prevents usage of incompatible symbols.
For example, if I declare and call function foobar this way:
void foobar(short abc, char *def);
But the module actually defines foobar this way:
void foobar(char *def) {
/* whatever */
}
Obviously such a mismatched call will likely generate bad behavior and
possibly a kernel oops. But since the CRC for foobar stored in the module
defining foobar won't match the CRC for foobar stored in the module using
foobar, the mismatch will be caught and the kernel won't let you load that
combination of modules at the same time.
In theory this all looks great. But why, might you ask, is this mechanism
not working for tveeprom_hauppauge_analog? That's because we REALLY DO
have conflicting definitions here.
Look back at my diatribe in pvrusb2-eeprom.html, and you'll see how I
point out that the V4L defined version of this function uses a struct
tveeprom that is different than the struct tveeprom used by the ivtv
defined version of this function. The CRC generation algorithm is
apparently using the full definition of the tveeprom structure as input
into the CRC value. Now, in pvrusb2-eeprom.c I do some really ugly
hackery to make a run time determination of which struct tveeprom is
really the correct one so the code is actually fairly safe. But this sort
of thing still trips up the CRC generation. It turns out that in the
pvrusb2 driver build, pvrusb2-eeprom.c will see the V4L defined prototype
for tveeprom_hauppauge_analog and struct tveeprom, so the expected CRC
will be the V4L version of the function. Thus we now see why we get this
"disagrees about version of symbol" error when we try to load the ivtv
version of tveeprom.ko with the other definition - and a different CRC.
Right now I don't see a good solution. The simple fact is that I'm trying
to make the pvrusb2 driver survive a screwed up situation between V4L and
ivtv and there's only so much I can do here. There's really only two
choices here: (1) Don't enable CONFIG_MODVERSIONS in your kernel build (if
you can), or (2) Don't bother trying to use the tveeprom.ko supplied with
the pvrusb2 driver. I should also point out here that the same problem
should happen if you try to use the "real" ivtv driver's tveeprom.ko, for
exactly the same reason. This means that if you really do want ivtv to
run co-resident with the pvrusb2 driver, then you are only really left
with choice (1).
I'm going to bed now. Next chance I get, after sleeping all this off,
I'll see about updating the web pages to include this new information.
For some reason I seem to have acquired a nasty headache...
-Mike
--
| Mike Isely | PGP fingerprint
Spammers Die!! | | 03 54 43 4D 75 E5 CC 92
| isely @ pobox (dot) com | 71 16 01 E2 B5 F5 C1 E8
| |
More information about the pvrusb2
mailing list