Http://blog.chinaunix.net/uid-20543672-id-3023148.html
A few days ago a colleague asked me: If a module to call the function of another module, do not do anything special processing. I just knew I needed to be called the function Export_symbol ();. However, because of the specific module experiment has not done, I immediately made a show to him, I also verified. As soon as the experiment was done, the problem came: though the compilation passed (with a warning:WARNING:"Exported_function_2" [/home/tekkaman/development/research/linux_module/caller/caller.ko]undefined!, but when the module of the exported function is mounted, and the calling module is mounted, an error cannot be mounted: # Insmod Exporter_1.ko Hello, Tekkaman Ninja. Exported_function_1 is online! # insmod Exporter_2.ko Hello, Tekkaman Ninja. Exported_function_2 is online! # Insmod Caller.ko Caller:no symbol version forExported_function_2 Caller:Unknown SymbolExported_function_2 (err-22) Caller:no symbol version forExported_function_1 Caller:Unknown SymbolExported_function_1 (err-22)Insmod:error inserting' Caller.ko ':-1 Invalid parametersHere I share my test cases as follows, you can first look at the code:
Linux_module_func_export.rar (please modify the kernel source directory and the cross compiler definition) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ after the problem, I went to Google onlineSolving Method: Kernel 2.6.26 driver module "Unknown symbol in module" problem
One of the 15 floor Daidaiangel solution is positive solution, reproduced as follows:This is the 2.6.26 version of the bug after the Linux kernel (detailed description, see HTTP://BUGZILLA.KERNEL.ORG/SHOW_BUG.CGI%3FID%3D12446) and this bug won't be fix
The solution is to put the mod_a module.symvers into the mod_b's current path, compiling mod_b, and the symbolic information will be automatically connected. Alternatively, use Kbuild_extra_symbols to specify Mod_a module.symvers in the mod_b makefile, such as: kbuild_extra_symbols=/mod_a/module.symvers
when compiling mod_b, the path to search for Module.symvers is: 1, kernel source path, e.g./usr/src/kernels/linux-2.6.28.10 2, the path specified by the m= in Makefile, which is equivalent to the value of the variable Kbuild_extmod 3, the value of the variable Kbuild_extra_symbolsAnd the 16 floor littertiger The nature of the problem:
15 floor analysis thoroughly simple to say, is the small B generation when do not know small a symbol of the check code, small b loaded when the naturalCheck Checksum code error。 There is also a web as a reference, the solution is the same: Linux kernel module load Error "No symbol version for Struct_module" solution
This method can indeed solve the problem, as long as the above test program in the caller of the makefile added "Kbuild_extra_symbols" is good (inside already have, remove the annotation, the path to change, but must be absolute path OH. )。 Recompile the caller module.
experimental process: root@dm816x-evm:/# insmod exporter_1.ko Hello, Tekkaman Ninja. Exported_function_1 is online! root@dm816x-evm:/# insmod Exporter_2.ko Hello, Tekkaman Ninja. Exported_function_2 is online! root@dm816x-evm:/# insmod Caller.ko Hello, Tekkaman Ninja. Now call exporters ' s function! I ' m exported_function_1. (in/home/tekkaman/development/research/linux_module/exporter_1/exporter_1.c) I ' m exported_function_2. (IN/HOME/TEKKAMAN/DEVELOPMENT/RESEARCH/LINUX_MODULE/EXPORTER_2/EXPORTER_2.C)
But the problem is solved on the one hand, always need to know the source of the problem and the specific situation.
Note: The following content involves a number of kernel module mount mechanisms, if necessary, please refer to the "in-depth Linux kernel framework," the seventh module, highly recommended that you read.
I found the reason on the Internet and Linux Code: (1) The information on the Internet due to the recent hacker intrusion, linux.org Web site adjustment, after the bugzilla will not go. Therefore, the bug information recorded above cannot be queried. Fortunately, I found someone from the bugid:12446 to his own blog and a Bug details information, I do a little collation, easy to read: [Bugme-new] [Bug 12446] new:unable to Insmod module. Unknwon symbol found
Bug 12446-unable to Insmod module. Unknwon symbol found
summary:unable to Insmod module. Unknwon symbol found product:drivers version:2.5 kernelversion:2.6.28 Platform:all Os/version:linux Tree:mainline status:newSeverity:blocking priority:p1 component:network Assignedto:jgarzik at pobox.com reportedby:amit at netxen.com
Latest working kernel version:2.6.28 earliest failing kernel version:2.6.26 distribution:hardware environment:software E Nvironment:problem Description:when you to use the driver dependent on the other driver. It should load cleanely, if 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 isn't know to other driver.
Steps to Reproduce:1) Create two device drivers in two separate. Let say-Hello and bye 2) Export Symbol from Hello module and try to use this in bye module. 3) Compile both the driver separately. 4) Insmod Hello.ko 3) while insmod (ing) Bye.ko, gives error "Unknown Symbol found"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bug 12446-unable to Insmod module. Unknwon symbol found
-------Comment #1 from Roland kletzing 2009-01-17 02:44:19-------What about using Modprobe instead? (as this looks into MODULES.DEP to find the Dependend modules and load them before)-------Comment #2 from Sucheta 2009-01- 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, and 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 O n A.ko) Together:-Works (2) copying module.symvers from module "A" dir to the module "B" dir, before compiling:- 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 (d IDN ' 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 this in. mod.c file it maintains __versions array, which contains export symbol name and its CRC. We are 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 fin D_symbol succeeds).
check_version behavior comparison in 2.6.26 and earlier version kernels:- in earlier versions of kernel also, symbol couldn ' t is found in its version table. Still, Check_version used to return 1 (success) and the dependent module could is insmod (ed) successfully. However, in kernel 2.6.26 onwards, behavior has. Changed on Don't check_version the finding. Symbol in its version Table returns 0 (fail) and the dependent external module can ' t be inserted anymore.
Waiting eagerly for your reply. 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 are not a support facility, just a bug tracker and as A problem ' ve reported and nobody else has duplicated its a very very low priority, especially as its The tree code seeing it-------Comment #6 the from Amit Jain 2009-03-19 21:04:12-------It should the not to very very low priotity, It easy to reproduce. Its should is blocker bug, because anybody how would try to compile module dependent on the other module, would 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 am right. This seems a very specific, personal problem. Anyway, if you are it's a general kernel problem, please post an as simple as possible repro-case (i.e. Some sourcecode) for your problem, so chances'll raise that someone would look at your problem. I ' d recommend bringing this up to kernel related mailing lists-------Comment #9 from Rusty Russell 2009-03-22 23:00:51- ------this is true;a5dd69707424a35d2d2cc094e870f595ad61e916Changed this.
The argument is that modversions are supposed to version symbols used into a module, and this doesn ' t really -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 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'll on "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 Mod Ule.symvers in "a" Dir so "B" would find module.symvers of "a" e.g. Kbuild_extra_symbols=/mod_a/module.symvers During Building "B", the search path of module.symvers would be. Please correct me if I 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 a s the value of Kbuild_extmod 3, the value of Kbuild_extra_symbols
I am The IT ' s a generic kernel problem. It ' s better to fix it. Below attached a simple case which are from Below link:
http://topic.csdn.net/u/20081009/11/6fb7295c-0d30-4d4f-b390-af4413aa7f7e.html%3Fseed%3D1582387931
-------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 would be the "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's added in 2.6.26. Hope that clarifies, Rusty.From the above information, we can basically determine the general situation of this problem is:one of the kernel mainline code tree submissions modifies the function version verification mechanism when the kernel mounts the module, making it possible to mount the module at compile time for individual The function does not determine that the CRC checksum value cannot be checked by the Check_version function.
(2) information in the kernel source codeWith the tips above, I found the one in the kernel mainline code: Commit a5dd69707424a35d2d2cc094e870f595ad61e916 Author:rusty Russell < Rusty@rustcorp.com.au> Date:fri May 9 16:24:21 2008 +1000
Module:be more picky about allowing missing module versions
modules: More critical for modules that allow no this version (checksum value)
We allow missing __versions sections, because modprobe,--force strips it. It makes less sense to allow sections where there's no version for a specific symbol the module uses, so disallow.we allow no __versions paragraph, because "Modprobe--force" removed him. This makes it meaningless to allow individual symbols that are used by a module in a segment to be without version. so forbid it.
Signed-off-by:rusty Russell <rusty@rustcorp.com.au> Signed-off-by:linus Torvalds < Torvalds@linux-foundation.org>The specific version of this change is from 2.6.26-rc1~2.6.26-rc2:: ~/linux$ git tag--contains a5dd69707 v2.6.26 v2.6.26-rc2 v2.6.26-rc3 v2.6.26-rc4 v2.6.26-rc5 v2.6.26-rc6 V2.6.26-rc7 V 2.6.26-rc8 v2.6.26-rc9 v2.6.27 V2.6.27-rc1 ... This submitted description of the action:This is a module mount that the kernel intentionally prohibits the existence of individual functions without version verification information. and the diff for this modification is as follows:
: ~/linux$ git diff a5dd69707^. a5dd69707
Diff--git A/kernel/module.c B/kernel/module.c
Index 8E4528C. 2584c0e 100644
---a/kernel/module.c
+++ B/KERNEL/MODULE.C
@@ -917,6 +917,10 @@ -917,6 int check_version (ELF_SHDR *sechdrs,
if (!CRC)
return 1;
+/* No versions at all? Modprobe--force does this. */
+ if (versindex = 0)
+ return Try_to_force_load (mod, symname) = = 0;
+
versions = (void *) sechdrs[versindex].sh_addr;
Num_versions = Sechdrs[versindex].sh_size
/sizeof (struct modversion_info);
@@ -932,8 +936,9 @@ -932,8 int check_version (ELF_SHDR *sechdrs,
Goto bad_version;
}
-if (!try_to_force_load (mod, symname))
-return 1;
+ PRINTK (kern_warning "%s:no symbol version for%s\n",
+ mod->name, symname);
+ return 0;
Bad_version:
PRINTK ("%s:disagrees about version of symbol%s\n", for the explanation of this modification: (1) The first is to allow modules without __versions segments to load. (2) The second is to prohibit the __versions segment, but the individual function has no version checksum value of the module loaded. All two places rely on one function (KERNEL/MODULE.C): static int try_to_force_load (struct module *mod, const char *reason)
{
#ifdef config_module_force_load
if (!test_taint (Taint_forced_module))
PRINTK (kern_warning "%s:%s:kernel tainted.\n",
Mod->name, reason);
Add_taint_module (mod, taint_forced_module);
return 0;
#else
Return-enoexec;
#endif
Obviously this function is: if there is a configurationConfig_module_force_load, it always returns "0" if no configurationConfig_module_force_load,The error value (not 0) is always returned. So you can see:If you want to avoid the "no symbol version for" error, the requirement is to configure Config_module_force_load:[*] Enable Loadable module Support--->---enable loadable module support[*] Forced module loading However, it seems that after configuring the Config_module_force_load, using the--force parameter or a generic error, or can not mount the module, I will study the following.
(3) How to restore the former calibration mechanism. Know the reason, in fact, we can modify the source code to restore the original verification mechanism (for purely experimental purposes, I agree with the mechanism of the kernel), only need to do the following modifications can be: diff--git A/kernel/module.c b/kernel/module.c
Index d190664