分类: linux
2007-04-07 15:47:30
description: a sample driver
vermagic: 2.6.5-1.358 686 regparm 4kstacks gcc-3.3
depends:
我们可以借助选项--force-vermagic解决该问题,但这种方法有潜在的危险,所以在成熟的模块中也是不可接受的。 解决方法是我们构建一个同我们预先编译好的内核完全相同的编译环境。如何具体实现将是该章后面的内容。
首先,准备同你目前的内核版本完全一致的内核代码树。然后,找到你的当前内核的编译配置文件。通常它可以在路径 /boot下找到,使用像config-2.6.x的文件名。你可以直接将它拷贝到内核代码树的路径下: cp /boot/config-`uname -r` /usr/src/linux-`uname -r`/.config。
让我们再次注意一下先前的错误信息:仔细看的话你会发现,即使使用完全相同的配置文件,版本印戳还是有细小的差异的,但这足以导致模块加载的失败。这其中的差异就是在模块中出现却不在内核中出现的custom字符串,是由某些发行版提供的修改过的makefile导致的。检查/usr/src/linux/makefile,确保下面这些特定的版本信息同你使用的内核完全一致:
version = 2
patchlevel = 6
sublevel = 5
extraversion = -1.358custom
...
像上面的情况你就需要将extraversion一项改为-1.358。我们的建议是将原始的makefile备份在/lib/modules/2.6.5-1.358/build下。 一个简单的命令cp /lib/modules/`uname -r`/build/makefile /usr/src/linux-`uname -r`即可。 另外,如果你已经在运行一个由上面的错误的makefile编译的内核,你应该重新执行make,或直接对应/lib/modules/2.6.x/build/include/linux/version.h从文件 /usr/src/linux-2.6.x/include/linux/version.h修改uts_release,或用前者覆盖后者的。
现在,请执行make来更新设置和版本相关的头文件,目标文件:
[root@pcsenonsrv linux-2.6.x]# make
chk include/linux/version.h
upd include/linux/version.h
symlink include/asm -> include/asm-i386
split include/linux/autoconf.h -> include/config/*
hostcc scripts/basic/fixdep
hostcc scripts/basic/split-include
hostcc scripts/basic/docproc
hostcc scripts/conmakehash
hostcc scripts/kallsyms
cc scripts/empty.o
...
如果你不是确实想编译一个内核,你可以在split后通过按下ctrl-c中止编译过程。因为此时你需要的文件 已经就绪了。现在你可以返回你的模块目录然后编译加载它:此时模块将完全针对你的当前内核编译,加载时也不会由任何错误提示。