歡迎您光臨本站 註冊首頁

在Linux2.6.26下用EXPORT_SYMBOL時出現Unknown symbol?

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

http://bugzilla.kernel.org/show_bug.cgi?id=12446

在Linux2.6.26下用EXPORT_SYMBOL時出現Unknown symbol?

如何解決!!

這是linux kernel 2.6.26 之後版本的bug (詳細描述, 請看http://bugzilla.kernel.org/show_bug.cgi?id=12446)
並且這個bug不會被fix

解決辦法是把mod_a的Module.symvers放到mod_b的當前路徑,從而編譯mod_b,符號信息會自動連接進去.
或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers, 如:
KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers

編譯mod_b時,搜索Module.symvers的路徑是:
1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
2, makefile中M=所指定的路徑, 它等效於變數KBUILD_EXTMOD的值
3, 變數KBUILD_EXTRA_SYMBOLS的值

Bug 12446 - Unable to insmod module. Unknwon symbol found
: Unable to insmod module. Unknwon symbol found

Status: REJECTED WILL_NOT_FIX
: Drivers
Other
: 2.5
: All Linux
: P1 low
Assigned To: drivers_other@kernel-bugs.osdl.org
:
:

:
Show dependency tree / graph
Reported: 2009-01-14 05:53 by amit jain
Modified: 2009-06-04 06:54 (History)
Kernel Version: 2.6.28
Tree: Mainline
Regression: No


Attachments



Description From amit jain 2009-01-14 05:53:57
   Latest working kernel version:2.6.28   Earliest failing kernel version:2.6.26   Distribution:   Hardware Environment:   Software Environment:   Problem Description:   When you use driver dependent on other driver. It should load cleanely, if   other is loaded. But in kernel 2.6.26 onwards its give error, unknown symbol   found.   Actually find_symbol able to find symbol but check_version unable to match crc.   Because crc is not know to other driver.       Steps to reproduce:   1) create two device drivers in two separate directories. let say hello and bye    2) Export Symbol from hello module and try to use that in bye module.   3) Compile both the driver separately.   4) insmod hello.ko   3) While insmod(ing) bye.ko, gives error "Unknown Symbol found"
------- Comment #1 From Roland Kletzing 2009-01-17 02:44:19 -------
   what about using modprobe instead ? (as this looks in modules.dep to find the   dependend modules and load them before) 
------- Comment #2 From sucheta 2009-01-18 21:40:43

-------
   Hi Roland, using modprobe doesn't work. The entries in modules.dep are added.   Still it ends up showing the same prints - "no symbol version for " and   "Unknown symbol ". And modprobe fails.
------- Comment #3 From amit jain 2009-01-19 00:20:32 -------
   Hi Roland,      Thanks a lot for replying. Below I have written details of experiments we   did and our understanding.      Problem: insmod failure for externally compiled module :-      Experiments:   (1) Compiling 2 modules a.ko and b.ko ( dependent on a.ko ) together :- Works      (2) Copying Module.symvers from module "a" dir to the module "b" dir, before   compiling b.ko :- Works.      (3) Modprobe after appending following lines in /lib/modules/modules.dep        /lib/modules/2.6.27.7-smp/kernel/drivers/net/a.ko       /lib/modules/2.6.27.7-smp/kernel/drivers/net/b.ko:   /lib/modules/2.6.27.7-smp/kernel/drivers/net/a.ko      :- Fails      (4) After compiling b.ko, just modifying b.mod.c file to include the undefined   symbol in its version table doesn't work (didn't expect to work ).      (5) export_objs (doesn't work):       In Makefile of a.ko:          export_objs := a.ko / export-objs := a.ko / exportobjs := a.ko.      (6) Adding "#define EXPORT_SYMTAB" in a.c file (doesn't work).      From above experiments, we found that In .mod.c file it maintains __versions   array, which contains export symbol name and its crc.   We see symbols of modules which are compiled with kernel. No symbols of   externally compiled modules.      The call trace is load_module -> simplify_symbols -> resolve_symbol ->    find_symbol and check_version ( if find_symbol succeeds ).      check_version behavior comparison in 2.6.26 and earlier version kernels :-      In earlier versions of kernel also, symbol couldn't be found in its version   table. Still, check_version used to    return 1 (success) and the dependent module could be insmod(ed) successfully.      However, in kernel 2.6.26 onwards, behavior has changed.  check_version on not   finding the reqd. symbol in its version table returns 0 (fail) and  the   dependent external module can't be inserted anymore.      Waiting eagerly for your reply. Thanks in advance.
------- Comment #4 From amit jain 2009-01-28 21:04:34

-------
   Any updates ?
------- Comment #5 From Alan 2009-03-19 10:19:16 -------
   No but this is not a support facility, just a bug tracker and as a problem only   you've reported and nobody else has duplicated its a very very low priority,   especially as its only out of tree code seeing it
------- Comment #6 From amit jain 2009-03-19 21:04:12 -------
   It should not be very very low priotity, Its easy to reproduce.    Its should be blocker bug, because anybody how will try to compile module   dependent on other module, will fail.      Strange, Why didn't nobody reply on it.   I am really stuck, because of this problem.
------- Comment #7 From Tejun Heo 2009-03-19 21:48:40 -------
   cc'ing Rusty Russell.
------- Comment #8 From Roland Kletzing 2009-03-20 12:11:23 -------
   hello amit,    i think alan is right. this seems a very specific, personal problem.       anyway, if you think it`s a general kernel problem, please post an as simple as   possible repro-case (i.e. some sourcecode) for your problem, so chances will   raise that someone will look at your problem.       i`d recommend bringing this up on kernel related mailing lists
------- Comment #9 From Rusty Russell 2009-03-22 23:00:51

-------
   This is true; a5dd69707424a35d2d2cc094e870f595ad61e916 changed this.      The argument is that modversions is supposed to version symbols used in a   module, and this   doesn't really work for out-of-tree modules (unless you copy Module.symvers   across, as done   above).   Otherwise module B doesn't know the version of symbol A; we changed   such a missing   version to fail; the user *did* want us to check versions.      Currently you have to modprobe --force-modversion to load such a module.      I think the new behavior is correct.
------- Comment #10 From Qihua Dai 2009-06-04 05:28:02 -------
   I also met the same problem on kernel 2.6.28.10.   "modprobe --force-modversion" does work for me, it will report "invalid module   format"      Besides the solution of copy Module.symvers across, below solution can   workaround it:   In the makefile of "b", define KBUILD_EXTRA_SYMBOLS which points to   Module.symvers in "a" Dir so that "b" will find Module.symvers of "a"   e.g.   KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers      During building "b", the search path of Module.symvers will be. Please correct   me if my understanding is incorrect.   1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10    2, the value of $(M) defined in makefile, which is the same as the value of   KBUILD_EXTMOD   3, the value of KBUILD_EXTRA_SYMBOLS      I think it's a generic kernel problem. It's better to fix it. Below attached a   simple case which is from below link:   http://topic.csdn.net/u/20081009/11/6fb7295c-0d30-4d4f-b390-af4413aa7f7e.html?seed=1582387931      =============C/C   code   // Module A (mod_a.c)   #include<linux/init.h>   #include<linux/module.h>   #include<linux/kernel.h>      static int func1(void)   {          printk("In Func: %s...n",__func__);          return 0;   }      // Export symbol func1   EXPORT_SYMBOL(func1);      static int __init hello_init(void)   {          printk("Module 1,Init!n");          return 0;   }      static void __exit hello_exit(void)   {          printk("Module 1,Exit!n");   }      module_init(hello_init);   module_exit(hello_exit);         =============C/C   code   // Module B (mod_b.c)   #include<linux/init.h>   #include<linux/kernel.h>   #include<linux/module.h>      static int func2(void)   {          extern int func1(void);          func1();          printk("In Func: %s...n",__func__);          return 0;   }      static int __init hello_init(void)   {          printk("Module 2,Init!n");          func2();          return 0;   }      static void __exit hello_exit(void)   {          printk("Module 2,Exit!n");   }      module_init(hello_init);   module_exit(hello_exit);         =============Makefile for Module A       BatchFile code   obj-m  = mod1.o   mod1-y := mod_a.o      KVERSION = $(shell uname -r)      all:        make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules      clean:       make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean       rm -f *.o *.ko *.cmd         =============Makefile for Module B       BatchFile code   obj-m  = mod2.o   mod2-y := mod_b.o      KVERSION = $(shell uname -r)      all:        make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules      clean:       make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean       rm -f *.o *.ko *.cmd
------- Comment #11 From Qihua Dai 2009-06-04 05:31:40

-------
   A typo, it should be   ""modprobe --force-modversion" does NOT work for me, it will report "invalid   module   format""
------- Comment #12 From Rusty Russell 2009-06-04 06:54:15 -------
   You can't modprobe --force if  CONFIG_MODULE_FORCE_LOAD isn't set.  That was   added in 2.6.26, and is off by default.      Hope that clarifies,   Rusty.

You need to log in before you can comment on or make changes to this bug.


[火星人 ] 在Linux2.6.26下用EXPORT_SYMBOL時出現Unknown symbol?已經有1569次圍觀

http://coctec.com/docs/linux/show-post-48113.html