内核模块编译常见问题

我使用的硬件平台是exynos4412,内核版本是3.14

0、卸载模块提示找不到相关目录

收到创建缺少的目录,再重新卸载就可以了

1、显示文件修改时间在未来

make编译的时候出现如下图片:

内核模块编译常见问题_第1张图片

原因:源代码修改时间和make编译的时间不一样,我这里是因为源代码是在Windows下的source insight下编写的,make编译则是在Ubuntu下,Windows下的时间是,但是在Ubuntu下确是:

所以才会显示文件修改的时间是在未来。

2、内核模块由多个.c文件、多个.h文件组成,make报错

我采用的是在Exynos4412的SOC上实现对beep蜂鸣器的内核驱动实验,具体思路如下:

(1)将控制beep的寄存器硬件相关配置存放在fs4412_beep.c文件中,相关头文件声明放在fs4412_beep.h头文件中

(2)内核模块相关函数(加载、卸载等)、ioctl控制函数全部存放在beep_drv.c文件中,声明放在beep_drv.h头文件中

(3)Makefile中声明obj-m += beep_drv.o  beep_drv-objs := fs4412_beep.o

(4)Makefile中头文件EXTRA_CFLAGS += -I$(PWD)/include

会报如下错误fatal error: xxx.h: No such file or directory,头文件找不到内核模块编译常见问题_第2张图片

解决办法:

    在Makefile中添加:EXTRA_CFLAGS += -I$(src)/include告诉内核模块编译的时候,头文件查找路径

接着编译又会报如下错误WARNING: "xxx" [/mnt/hgfs/share/test/beep/drv_beep.ko] undefined!:

内核模块编译常见问题_第3张图片

这个问题产生的原因:Makefile文件在找对应的依赖关系的时候,发现beep_drv模块依赖于beep_drv-objs内容,然后找到文件fs4412_beep.o,最后只会编译生成fs4412_beep.o文件,这时候就不会编译beep_drv.o这个文件了,又因为my_beep这个变量我是放在beep_drv.c这个文件里的,所以会报错说找不到这个变量的定义,要想解决这个问题,如果单独修改Makefile文件,在beep_drv-objs := fs4412_beep.o添加beep_drv-objs := beep_drv.o fs4412_beep.o这是不够的,任然还是会出现这个错误,这是因为内核模块的名称和依赖c源文件的名称一样,这导致make混淆,把c文件混淆成了模块名称,最终还是会报错。所以最终接解决办法就是:在Makefile文件中,修改EXTRA_CFLAGS += -I$(src)/include指定头文件位置,修改模块依赖obj-m += beep.o beep-objs := beep_drv.o fs4412_beep.o

        最后做个总结,在内核源码中编译模块时,如果模块代码有多个.c文件、.h文件,方法如下:

        (1)在Makefile中通过追加EXTRA_CFLAGS += -I$(src)/(源码下头文件位置)指定.h文件路劲

        (2)模块名称不能和.c源文件重名

        (3)内核模块依赖文件关系中要添加所有文件,例如上述例子,一定要将模块名-objs := 所有源文件.o

    注:上述蜂鸣器功能分开代码实现在我的另外一篇博文中:Linux内核驱动之PWM蜂鸣器

3、在内核代码中,函数定义必须指定每个参数名称,但是声明只需要指定参数类型就可以了,不用指定参数名称

4、报错scripts/Makefile.build:313: target `/home/linux/delete/beep' doesn't match the target pattern

    原因:Makefile文件格式有问题,一般是拷贝的时候编码的问题,最好重新编写一个Makefile

    解决方法:重新创建一个Makefile空文件,然后重新写一下

5、编译内核源码时候,进入内核源码后直接离开,不报任何错误

    原因:Makefile文件中,对于内核模块的名称变量定义放在了ifeq内,导致再次进入Makefile的时候找不到这个变量定义

    解决办法:1、将变量定义不放在任何条件判断内。2、不在定义模块名称变量,直接在obj-m后边写依赖文件就可以了

你可能感兴趣的:(Linux驱动)