Linux内核源码外编译linux模块--编译驱动模块的基本⽅法1、先编写⼀个简单的hello模块,hello.c 源码如下:
#ifndef __KERNEL__
#  define __KERNEL__
#endif
#ifndef MODULE
#  define MODULE
#endif
// 下⾯的是主要的内容
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int year=2012;
int hello_init()
{
printk(KERN_WARNING "Hello kernel, it's %d!\n",year);
return 0;
}
void hello_exit()
{
printk("Bye, kernel!\n");
}
/
/ 下⾯两个为关键的模块函数
module_init(hello_init);
module_exit(hello_exit);
如果上⾯的代码看起来不太熟悉,那么需要查看以下相关的书籍,⽐如《Linux设备驱动程序,第三版》,也就是⼤名⿍⿍的LDD;2、⽼式驱动模块编译⽅法:
直接写出make规则到makefile⽂件中,引⽤内核体系的头⽂件路径,举例如下:
# The path of kernel source code
makefile phonyINCLUDEDIR = /media/GoldenResources/linux/linux-2.6.30/include
# Compiler
CC = gcc
# Options
CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)
# Target
OBJS = hello.o
all: $(OBJS)
$(OBJS): hello.c
$(CC) $(CFLAGS) -c $<
install:
insmod $(OBJS)
uninstall:
rmmod hello
.PHONY: clean
clean:
rm -f *.o
这⾥有我是⽤的⼀个linux内核源代码路径:/media/GoldenResources/linux/linux-2.6.30/include ,注意设置到正确的源码路径。
尝试这编译:$make
gcc -D__KERNEL__ -DMODULE -O -Wall -I/media/GoldenResources/linux/linux-2.6.30/include -c hello.c
In file included from /media/GoldenResources/linux/linux-2.6.30/include/linux/kernel.h:11:0,
from hello.c:8:
/media/GoldenResources/linux/linux-2.6.30/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory
compilation tterminate
make: *** [hello.o] Error 1
出现错误: include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory , ⽹上查阅相关资料后,到不错的说明:
主要意思是这种编译⽅法不能很好的解决相关的依赖体系,主要是源于历史原因,linux内核升级很快,越来越复杂,所以建议使⽤kbuild体系来⾃动完成;故下⾯采⽤了可⾏的kbuild体系来完成。
3、使⽤kbuild进⾏模块编译:
核⼼思想是,通过-C指明系统上的内核体系路径,通过M=指明模块源⽂件路径,然后⾃⼰构造⼀个makefile⽂件,从⽽实现编译过程。
3.1 构建适⽤于kbuild⽅法的makefile:
obj-m := hello.o
all :
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
开始make:
$make
make -C /lib/modules/3.5.0-17-generic/build M=/media/GoldenResources/arm/ARM/HelloWorld/hello modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
scripts/Makefile.build:44: /media/GoldenResources/arm/ARM/HelloWorld/hello/Makefile: No such file or directory
make[2]: *** No rule to make target `/media/GoldenResources/arm/ARM/HelloWorld/hello/Makefile'.  Stop.
make[1]: *** [_module_/media/GoldenResources/arm/ARM/HelloWorld/hello] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [all] Error 2
⾃动使⽤了当前运⾏中的内核,构建对应的模块,但是提⽰不到Makefile,⽽该⽬录下的⽂件为makefile,所以尝试修改名字:
$mv makefile  Makefile
特别注意,要使⽤Makefile才⾏!不能时makefile;
修改后,编译成功:
$make
make -C /lib/modules/3.5.0-17-generic/build M=/media/GoldenResources/arm/ARM/HelloWorld/hello modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
Building modules, stage 2.
MODPOST 1 modules  # 说明成功编译了⼀个模块
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
3.2 加载和删除内核模块:
$sudo insmod ./hello.ko #加载
$sudo rmmod hello      #删除
并没有看到源代码中的输出信息,查看系统相应⽇志即可:
$tail /var/log/kern.log  # 注意ubuntu下的⽇志路径
Oct 23 22:22:22 qunengrong-Studio-1450 kernel: [43021.773888] Hello kernel, it's 2012!
Oct 23 22:22:37 qunengrong-Studio-1450 kernel: [43037.092339] Bye, kernel!
⾄此,我们已经可以成功编译和加载内核模块了;
4、额外成就,要注意模块与内核版本的匹配:
假设我直接使⽤另⼀个内核体系进⾏构建,⽐如3.5.0-15-generic,但是当前系统运⾏的为3.5.0-17-generic的内核,则加载时报错,如下:
$make -C /lib/modules/3.5.0-15-generic/build M=`pwd` modules
make: Entering directory `/usr/src/linux-headers-3.5.0-15-generic'
CC [M]  /media/GoldenResources/arm/ARM/HelloWorld/hello/hello.o
/media/GoldenResources/arm/ARM/HelloWorld/hello/hello.c:16:5: warning: function declaration isn’t a prototype /media/GoldenResources/arm/ARM/HelloWorld/hello/hello.c:23:6: warning: function declaration isn’t a prototype  Building modules, stage 2.
MODPOST 1 modules
CC      /media/GoldenResources/arm/ARM/HelloWorld/d.o
LD [M]  /media/GoldenResources/arm/AR/HelloWorld/heARo/hello.ko
make: Leaving directory `/usr/src/linux-headers-3.5.0-15-generic'
$sudo insmod ./hello.ko  # 版本不⼀致报错
insmod: error inserting './hello.ko': -1 Invalid module format
由此可见,使⽤⾃动构建带来的⽅便,将该通⽤Makefile分享如下:
obj-m := name.o
all :
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。