次のように図1は、第1のシンプルハローモジュール、hello.cのソースコードを記述します。
1 #ifndef __KERNEL__ 2 # define __KERNEL__ 3 #endif 4 #ifndef MODULE 5 # define MODULE 6 #endif 7 8 // 下面的是主要的内容 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/init.h> 12 13 MODULE_LICENSE("GPL"); 14 15 static int year=2012; 16 17 int hello_init() 18 { 19 printk(KERN_WARNING "Hello kernel, it's %d!\n",year); 20 return 0; 21 } 22 23 24 void hello_exit() 25 { 26 printk("Bye, kernel!\n"); 27 } 28 29 // 下面两个为关键的模块函数 30 module_init(hello_init); 31 module_exit(hello_exit);
如果上面的代码看起来不太熟悉,那么需要查看以下相关的书籍,比如《Linux设备驱动程序,第三版》,也就是大名鼎鼎的LDD;
2、老式驱动模块编译方法:
直接写出make规则到makefile文件中,引用内核体系的头文件路径,举例如下:
1 #カーネルのソースコードの経路 2 includedir以下= /メディア/ GoldenResources /リナックス/ linux- 2.6。30 / 含む 3 4 #コンパイラ 5 CC = GCCを 6 7 #オプション 8 CFLAGS = -D__KERNEL__ -DMODULE -O -Wall - I $(includedir以下) 9 10 #ターゲット 11 OBJS = hello.o 12 13 全:$(OBJS) 14 15 $(OBJS)のhello.c 16 $(CC)$(CFLAGS)-c $ < 17 図18は、 インストール: 19 insmodのを $(OBJS) 20 21 uninstall: 22 rmmod hello 23 24 .PHONY: clean 25 clean: 26 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 terminated. make: *** [hello.o] Error 1
出现错误: include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory , 网上查阅相关资料后,找到不错的说明:
请查看:http://stackoverflow.com/questions/9492559/module-compiling-asm-linkage-h-file-not-found
主要意思是这种编译方法不能很好的解决相关的依赖体系,主要是源于历史原因,linux内核升级很快,越来越复杂,所以建议使用kbuild体系来自动完成;故下面采用了可行的kbuild体系来完成。
3、使用kbuild进行模块编译:
基本方法可以参考: http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt
核心思想是,通过-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;
修改后,编译成功:
$ ザ・メイク メイク -C / libに/モジュール/ 3.5を。0 - 17 -generic / M =ビルド/メディア/ GoldenResources / ARM ARM /日コア/実験コードは/ HelloWorldの/ /上級コースこんにちはモジュール メイク [ 1。 ]以下を入力し`/ Linuxの-ヘッダなどディレクトリは/ usr / src の3.5。0 - 。17 -generic 「 ビル・モジュールは、ステージ2 。 MODPOST 。1 モジュール#正常にコンパイルモジュールを説明 メイク [を1。 :ままDirectory`は/ usr / src / Linux-]ヘッダなどの3.5。0 - 。17 -generic "
3.2負荷とカーネルモジュールを削除します。
$ 須藤 insmodの ./ hello.koロード# $ sudoを rmmodはハロー#を削除
私は、ソースコードの出力は、システムを表示するには、対応するログを見ていません。
$のテールは/ var / log / kern.log#Ubuntuのログ・パスに注意してください 月に23は 22です:22です:22がされ qunengrong-Studio- 1450カーネルを:[ 43021.773888 ]こんにちは、ITカーネル" !S 2012を 月に23で 22です:22です:37 [ qunengrong -Studio- 1450カーネル:[ 43037.092339 ]カーネル、さようなら!
これまでのところ、我々は正常にコンパイルし、カーネルモジュールをロードすることができました。
4、追加的な成果は、我々はモジュールとカーネルバージョンにマッチに注意を払う必要があります。
私は次のように、オペレーティングシステムをロードし、そのよう3.5.0-15-総称として、別のカーネルのビルドシステムを直接使用すると仮定しますが、現在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/hello/hello.mod.o LD [M] /media/GoldenResources/arm/ARM高级班/内核第一天/实验代码/HelloWorld/hello/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
转载于:https://www.cnblogs.com/QuLory/archive/2012/10/23/2736339.html