[pvrusb2] Disagreeable symbols and CONFIG_MODVERSIONS

Mike Isely isely at isely.net
Fri Dec 9 23:52:32 CST 2005


On Fri, 9 Dec 2005, Mike Isely wrote:

> On Fri, 9 Dec 2005, cardboil wrote:
>
>> I uninstalled the video4linux and ivtv rpms I had installed.  I downloaded
>> the 20051126 snapshot of the pvrusb driver.  I compiled the pvrusb2 driver
>> and the ivtv drivers per the pvrusb2 instructions.  But, I still get the
>> same errors:
>> 
>> [root at 192 mythtv]# dmesg|grep -i pvrusb2
>> pvrusb2: disagrees about version of symbol tveeprom_hauppauge_analog
>> pvrusb2: Unknown symbol tveeprom_hauppauge_analog
>
> If what you are saying is correct, this should absolutely be impossible. 
> Clearly if you are compiling both areas the same way with the same 
> environment then there should be no version disagreement.  I am at a loss to 
> explain why this is happening for you.  There's nothing unique about either 
> subdirectory (ivtv or driver) that could trigger this kind of error.  Either 
> there is still a different in how you've built them or you're not loading the 
> tveeprom.ko that you think you are loading.  I know, this isn't very helpful, 
> but I'm out of ideas here.
>
>  -Mike
>

I've done some research on this.  Good news: I've reproduced the problem. 
Bad news: CONFIG_MODVERSIONS has a lot to do with it.

When CONFIG_MODVERSIONS is enabled, additional code is generated during 
module build that implements a table of CRCs for the module, one CRC 
corresponding to each unresolved symbol.  You can see this table by 
looking at pvrusb2.mod.c which is in the driver directory and is generated 
as part of the module build.  This CRC table is an association of symbol 
vs CRC, and is used when the module is loaded.  Basically the kernel 
module loader has a table in core of all exportable symbols, with a stored 
CRC for each.  When a new module is loaded and its external references are 
resolved, the table entries are compared as well.  You can see this action 
taking place in kernel/module.c at roughly line 889 (in the kernel tree - 
just grep for the error message we've learned to know and hate).  If the 
CRC of the known symbol doesn't match the expected CRC stored in the 
incoming module that is trying to resolve the symbol, you get the 
"<module>:  disagrees about version of symbol <symbol_name>" message and 
the module load fails.

I was not seeing this problem because I've been running all along with 
CONFIG_MODVERSIONS turned off in my kernels - this option has to be on in 
order to enable this checking code.  I should point out here that this is 
tagged as an *experimental* feature which suggests that maybe you 
shouldn't have it on.  But I digress...

In the particular case of the symbol tveeprom_hauppauge_analog, we have an 
interesting issue because that symbol is resolved by the kernel-built 
tveerprom.ko so I'm thinking that the kernel's "expected" CRC for this 
symbol is coming from there.  But when we stuff in the ivtv-sourced 
instance of tveeprom.ko, this same symbol must have a different CRC and 
thus we get the error.  I'm not entirely sure about this, but it's the 
working theory I have at the moment.  (I imagine this same problem is 
going to happen in the ivtv driver itself by the way, for exactly the same 
reason.)

I don't have a "real" solution for this yet.  I need to learn more about 
this.  In the mean time however you can still use the driver-provided 
tveeprom.ko instance by rebuilding your kernel with CONFIG_MODVERSIONS off 
(like I've been doing all along).  And no, you should NOT need this on in 
order to use the nvidia binary driver - I've been using that driver all 
along with this option off and everything there is fine.

BTW, of all the support modules, the only actual symbol directly resolved 
by any of them that's needed by the pvrusb2 is in fact just 
tveeprom_hauppauge_analog.  All other interactions are indirect, i.e. the 
other modules set up run-time hooks into the kernel I2C subsystem and the 
pvrusb2 driver accesses them indirectly through that means thus not 
needing any kind of direct symbol resolution.  That's why the problem only 
happens for tveeprom.ko and not the other modules (this is because pvrusb2 
is using the "direct call" method of access that I described in the 
pvrusb2-eeprom.html web page).

This has been an interesting bug chase.  I learned something new here.

Some interesting references...

This is an LKML post describing the new modversions functionality.  It's 
here where I finally understood what was going on:

   http://www.ussg.iu.edu/hypermail/linux/kernel/0301.3/0272.html

This is an IEEE article about Linux kernel modules.  I haven't read it 
through yet, but at first glance it looks like a good source of info:

   http://www.cs.unb.ca/courses/cs4405/lectures/Loadable_kernel_modules.pdf

If I find a way to make this symbol from tveeprom resolve correctly even 
in the face of CONFIG_MODVERSIONS being enabled, I will post an 
explanation.  I will also update the pvrusb2 web page at some point to 
describe it.  This is obviously an FAQ item, at the very least.

   -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