insmod驱动
时间:2010-10-13 来源:_mystic
主要是2.6.26内核的module.c中check_version()发生了改变,在检查不到符号版本的时候返回0或者是-ENOEXEC,而之前的版本是返回1,导致的这个问题。
代码如下:
解决方法:
1、重新编译内核,关闭CONFIG_MODVERSIONS选项
2、重新编译内核开启MODULE_FORCE_LOAD选项,强制加载
3、拷贝Module.symversion到内核源码目录,然后在内核源码目录执行make prepare,然后再在编译Module的时候加上KERN_DIR=/usr/src/linux
4、修改Module代码,通过/proc/kallsyms来获得地址,并赋给函数指针来使用
参考资料:
http://www.4front-tech.com/forum/viewtopic.php?p=10907&sid=43dc39cc92cbe35d27a4f89ec1208eb0
http://groups.google.com/group/linux.debian.bugs.dist/browse_thread/thread/1c724e019da71903
http://ubuntuforums.org/showthread.php?p=6119045
代码如下:
2.6.26: #ifdef CONFIG_MODVERSIONS static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc) { unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ 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); for (i = 0; i < num_versions; i++) { if (strcmp(versions[i].name, symname) != 0) continue; if (versions[i].crc == *crc) return 1; DEBUGP("Found checksum %lX vs module %lX\n", *crc, versions[i].crc); goto bad_version; } 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", mod->name, symname); return 0; } static int try_to_force_load(struct module *mod, const char *symname) { #ifdef CONFIG_MODULE_FORCE_LOAD if (!(tainted & TAINT_FORCED_MODULE)) printk("%s: no version for \"%s\" found: kernel tainted.\n", mod->name, symname); add_taint_module(mod, TAINT_FORCED_MODULE); return 0; #else return -ENOEXEC; #endif } 2.6.25: #ifdef CONFIG_MODVERSIONS static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc) { unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); for (i = 0; i < num_versions; i++) { if (strcmp(versions[i].name, symname) != 0) continue; if (versions[i].crc == *crc) return 1; printk("%s: disagrees about version of symbol %s\n", mod->name, symname); DEBUGP("Found checksum %lX vs module %lX\n", *crc, versions[i].crc); return 0; } /* Not in module's version table. OK, but that taints the kernel. */ if (!(tainted & TAINT_FORCED_MODULE)) printk("%s: no version for \"%s\" found: kernel tainted.\n", mod->name, symname); add_taint_module(mod, TAINT_FORCED_MODULE); return 1; } |
解决方法:
1、重新编译内核,关闭CONFIG_MODVERSIONS选项
2、重新编译内核开启MODULE_FORCE_LOAD选项,强制加载
3、拷贝Module.symversion到内核源码目录,然后在内核源码目录执行make prepare,然后再在编译Module的时候加上KERN_DIR=/usr/src/linux
4、修改Module代码,通过/proc/kallsyms来获得地址,并赋给函数指针来使用
参考资料:
http://www.4front-tech.com/forum/viewtopic.php?p=10907&sid=43dc39cc92cbe35d27a4f89ec1208eb0
http://groups.google.com/group/linux.debian.bugs.dist/browse_thread/thread/1c724e019da71903
http://ubuntuforums.org/showthread.php?p=6119045
相关阅读 更多 +