https://mp.csdn.net/console/editor/html/107838044
在学习内核模块编程的时候遇到了一些由于Makefile书写不正确导致的问题。一个.c源文件的Makefile按照网上的大部分资料介绍那样是没有问题的,多个源文件的内核模块编程时,就出现问题了。把过程和解决方法贴出来,供大家参考,一起学习。
单文件.c编写内核模块是常用的内核模块编写方法,对一些比较简单的功能比较使用。
test.c
//test.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
static int __init init_test(void)
{
printk("test begin\n");
return 0;
}
static void __exit exit_test(void)
{
printk("test exit\n");
}
module_init(init_test);
module_exit(exit_test);
第一种Makefile书写方法
# Makefile
obj-m := test.o
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
.PHONY:clean
clean:
rm -rf *.o *.ko *.ko.* *.mod.*
这种方法比较死板,编译出来的.ko的名称只能是.c的文件名对应的名称(例如:test.c编译出来的驱动名称只能是test.ko),驱动名称不能随意更改。
第二种Makefile书写方法
obj-m := test1.o
test1-objs := test.o
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
.PHONY:clean
clean:
rm -rf *.o *.ko *.ko.* *.mod.*
第二种书写方法可以改变编译出来的.ko名称,而受.c名称的限制
区别只有前两行:
obj-m := test1.o 确定了编译出来的模块名称是test1.ko
test1-objs := test.o 确定test1.ko模块编译时依赖的文件是test.c
如果把test1改写成abc,则编译出来的模块名称是abc.ko
多文件编程对于需求驱动功能比较多的情况下,进行功能模块化编译比较适用。
多文件驱动模块的编程可以像正常的应用程序的.c .h多问件编程,具体模块的名称就不能依赖.c文件的名称定义模块的名称。
多文件.c .h目录结构:test.c add.c add.h Makefile
test.c 地用add.c中的add函数,计算两个整数和。
test.c
// test.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "add.h"
MODULE_LICENSE("GPL");
static int __init init_test(void)
{
int num = 0;
int a = 0;
int b = 0;
printk("test begin\n");
a = 1;
b = 5;
num = add(a, b);
printk ("a[%d] + b[%d] = num[%d] \n", a, b, num);
printk("test end\n");
return 0;
}
static void __exit exit_test(void)
{
printk("test exit\n");
}
module_init(init_test);
module_exit(exit_test);
add.h
// add.h
#ifndef __ADD__H__
#define __ADD__H__
int add(int a, int b);
#endif //__ADD__H__
add.c
// add.c
#include
#include
#include "abc.h"
int add(int a, int b)
{
return a + b;
}
EXPORT_SYMBOL(add);
Makefile
# Makefile
obj-m := abc.o
abc-objs := test.o add.o
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
.PHONY:clean
clean:
rm -rf *.o *.ko *.ko.* *.mod.*
上面的Makefile就是根据第二种Makefile书写方式,编译出来的驱动模块名称为abc.ko