今天闲着没事整理一下内核.ko文件的创建过程,算是一个入门级教程吧。环境:ubuntu。编译工具gcc
1.首先创建一个hello.c的文件,内容如下:
#include <linux/init.h> #include <linux/module.h> static int hello_init(void) { printk("Hello World!\n"); printk("I will win the World!\n"); return 0; } static void hello_exit(void) { printk("Good Bye!\n"); } module_init(hello_init); module_exit(hello_exit);
2.创建Makefile文件,内容如下:
obj-m:=hello.o testmodule-objs:=module KDIR:=/lib/modules/3.11.0-15-generic/build MAKE:=make default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean上面的KDIR的路径可以通过 uname -a 看出你使用的是哪个版本的内核,然后在lib/modules里面找到对应的目录。
注解:首先看第一行 其中的obj-m指的是编译的目标是编译为模块,如果编译的源文件为hello.c 只需写为obj-m:=hello.o即可
default下面的 make -C是切换到指定目录进行编译 如果是编译当前系统的内核模块即为上述目录,如果是进行交叉编译,之需要将目录修改为对应的内核源代码目录即可
下面附一个比较简单的Makefile模板,更具体的内容大家网上找。
#简单实用的Makefile模板: objs := a.o b.o test:$(objs) gcc -o test $^ # .a.o.d .b.o.d dep_files := $(foreach f,$(objs),.$(f).d) dep_files := $(wildcard $(dep_files)) ifneq ($(dep_files),) include $(dep_files) endif %.o : %.c gcc -Wp,-MD,[email protected] -c -o $@ $< clean: rm *.o test
#/*关键解释*/ 这里面用到了一些Makefile函数,首先我们来说一下Makefile函数的格式: $(函数名 参数,参数,......) 这里用到了两个函数,我们分别来说一下: 1、dep_files := $(foreach f,$(objs),.$(f).d) 依次取出objs中的成员,放在f中,然后加上.d后缀,组成一个字符串(各个成员以空格分开),返回给dep_files ! 2、dep_files := $(wildcard $(dep_files)) 展开当前目录下名字为符合dep_files的文件名,并组成字符串返回给dep_files 此外还有一点要说的是: gcc -Wp,-MD,.$@.d -c -o $@ $< 1、-Wp,-MD:表示生成依赖文件,后跟依赖文件的名字 2、$@:表示规则的目标 $^:所有的依赖 $<:第一个依赖 $?:代表依赖文件列表中被改变过的所有文件
# 第一次执行,没有依赖文件,这个ifneq不执行, # 当修改.h文件之后,判断执行这个include $(dep_files) ifneq ($(dep_files),) include $(dep_files) endif-----------------------
3. 执行make Makefile,会生成hello.ko文件
4. insmod hello.ko 加载内核
可以通过dmesg看到打印出来的log
[ 2472.307050] Hello World!
[ 2472.307055] I will win the World!
当然也可以用lsmod|grep hello
root@lll-virtual-machine:/home/lll/share/linuxdev# lsmod|grep hello
hello 12496 0
5. rmmod hello
查看是否成功跟上面一样!
整个流程就是这样了!相当简单。