以便和源代码树中的目标文件相连。怎么建立这个内核源码树呢?可以从官网下载相对应的内核源码,编译之。
首先,看看我的内核版本。
[linc@localhost ~]$ uname -r2.6.35.6-45.fc14.i686
那么去官网www.kernel.org下载2.6.35.6的源码吧。
在首页找不到你要的版本不要急,点击FTP的链接,找到你想要的版本吧。
创建个目录,将源码解压在其中。(tar xfvz yourfile)
编译的第一项是内核配置,我的系统的Fedora,出现了点问题:
在源码目录下root执行make menuconfig,
出现错误:
*** Unable to find the ncurses libraries or the *** required header files. *** 'make menuconfig' requires the ncurses libraries. *** *** Install ncurses (ncurses-devel) and try again. *** make[1]: *** [scripts/kconfig/dochecklxdialog] 错误 1 make: *** [menuconfig] 错误
解决办法:
这是由于ncurses图形库导致的,下载它就好了。
yum install ncurses
yum install ncurses-devel
这次继续执行,出现配置界面。按如下来操作:
Loadable module support ---->
选择Module versioning support(按Y就ok),这个功能可以让你使用其他版本的内核模块。
接下来就可以编译了:
还是此目录下,执行make。很长时间,根据机器配置而异。喝茶去吧。
接着编译压缩形式的内核,make bzImage
[root@localhost linux-2.6.35.6]# make bzImage CHK include/linux/version.h CHK include/generated/utsrelease.h CALL scripts/checksyscalls.sh CHK include/generated/compile.h CHK include/linux/version.hmake[2]: `scripts/unifdef' is up to date. TEST posttestSucceed: decoded and checked 1249053 instructionsKernel: arch/x86/boot/bzImage is ready (#2)继续编译模块并将它们安装到系统标准位置:
make modules
make modules_install
完成后,/lib/modules/下多了个2.6.35.6目录。
至此,我们的内核树算是建立完成。
下面写个hello world来检验一下吧。
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){ printk(KERN_ALERT "Hello,world.i am linc.\n"); return 0;}static void hello_exit(void){ printk(KERN_ALERT "Goodbye, i am linc.\n");}module_init(hello_init);module_exit(hello_exit);写个makefile来编译它:
#如果已经定义KERNELRELEASE,说明是从内核构造系统调用的,#可利用其内建语句ifneq ($(KERNELRELEASE),)obj-m := test.o#否则是从命令行调用的,需要使用内核构造系统else KDIR := /lib/modules/2.6.35.6/buildall: make -C $(KDIR) M=$(PWD) modulesclean: rm -f *.ko *.o *.mod.o *.mod.c *.symversendif
编译:
[root@localhost drivers]# make
make -C /lib/modules/2.6.35.6/build M=/home/linc/linux/workspace/drivers modules
make[1]: Entering directory `/usr/src/kernels/linux-2.6.35.6'
CC [M] /home/linc/linux/workspace/drivers/test.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/linc/linux/workspace/drivers/test.mod.o
LD [M] /home/linc/linux/workspace/drivers/test.ko
make[1]: Leaving directory `/usr/src/kernels/linux-2.6.35.6'
安装和卸载:
insmod test.ko
rmmod test.ko如果此时仍然遇到问题:
[root@localhost drivers]# insmod test.ko insmod: error inserting 'test.ko': -1 Invalid module format我们看一下具体详细信息:
[root@localhost drivers]# dmesg | tail[ 356.269653] test: version magic '2.6.35.6 SMP mod_unload modversions 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686 '说明ko的kernel版本与当前运行的版本仍然不一致。此时我尝试重新编译内核,结果仍然一样。就参考
《Linux 2.6.x 内核模块加载错误 “Invalid module format” 解决办法》 将版本强制修改一下,让其保持一致。方法如下:
找到utsrelease.h文件,在源码树下linux-2.6.35.6/include/generated。将版本号修改。重新编译,发现仍有错误:
[ 1149.371180] test: version magic '2.6.35.6-45.fc14.i686 SMP mod_unload modversions 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686 '对比上述信息,发现我的VERMAGIC_STRING多了一个词“modversions”,好吧,为了一直,索性将linux-2.6.35.6/include/linux/vermagic.h文件中对VERMAGIC_STRING做
下调整。去掉MODULE_VERMAGIC_MODVERSIONS信息。如下:
#include <generated/utsrelease.h>#include <linux/module.h>/* Simply sanity version stamp for modules. */#ifdef CONFIG_SMP#define MODULE_VERMAGIC_SMP "SMP "#else#define MODULE_VERMAGIC_SMP ""#endif#ifdef CONFIG_PREEMPT#define MODULE_VERMAGIC_PREEMPT "preempt "#else#define MODULE_VERMAGIC_PREEMPT ""#endif#ifdef CONFIG_MODULE_UNLOAD#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "#else#define MODULE_VERMAGIC_MODULE_UNLOAD ""#endif#ifdef CONFIG_MODVERSIONS#define MODULE_VERMAGIC_MODVERSIONS "modversions "#else#define MODULE_VERMAGIC_MODVERSIONS ""#endif#ifndef MODULE_ARCH_VERMAGIC#define MODULE_ARCH_VERMAGIC ""#endif#define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC
至此,重新编译模块。一切正常。
[root@localhost drivers]# insmod test.ko[root@localhost drivers]# rmmod test.ko[root@localhost drivers]# dmesg | tail[ 1586.792291] Hello,world.i am linc.[ 1696.536632] Goodbye, i am linc.
参考:
http://blog.csdn.net/xuxinyl/article/details/6996433
http://www.cnblogs.com/Jezze/archive/2011/12/23/2299871.html
《Linux设备驱动程序》第二章