一个或多个C文件编译KO


参考文档:

文档组织结构

header目录:存放头文件

source目录:存放源文件

单个文件编译KO

在source目录中存放一个文件为kernel_simulator.c,下面的Makefile会编译该C文件,然后在source目录下生成一个kernel_simulator.ko。

KVERS = $(shell uname -r)

# 生成模块名
MODULE_NAME := kernel_simulator

# 源文件目录
SRC_PATH := source/

# 作为一个模块进行编译
CONFIG_RUNYEE_CAMVIB=m

# Kernel modules
obj-$(CONFIG_RUNYEE_CAMVIB) := $(SRC_PATH)$(MODULE_NAME).o

# 指定模块的一些编译选项
EXTRA_CFLAGS=-g -O0

build: kernel_modules
kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

CONFIG_RUNYEE_CAMVIB=m

注意上面的m,表示作为一个模块进行编译,最后在Makefile中需要用到的编译开关。

多个文件编译

在header目录存放一个:test_func.h

在source目录存放两个文件:test_func.c、kernel_simulator.c

通过以下Makefile可以在当前目录生成一个ksimulator.ko。

KVERS = $(shell uname -r)

# 生成模块名
MODULE_NAME := ksimulator

# 源文件目录
SRC_PATH := source/

# 作为一个模块进行编译
CONFIG_TOUCHSCREEN_FOCALTECH=m

# 指定头文件路径,和一些编译选项
EXTRA_CFLAGS += -I$(PWD)/header/
EXTRA_CFLAGS += -Werror
EXTRA_CFLAGS += -g -O0

# Kernel modules
obj-$(CONFIG_TOUCHSCREEN_FOCALTECH) += $(MODULE_NAME).o
$(MODULE_NAME)-objs := $(SRC_PATH)kernel_simulator.o
$(MODULE_NAME)-objs += $(SRC_PATH)test_func.o

build: kernel_modules
kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

CONFIG_TOUCHSCREEN_FOCALTECH=m

注意上面的m,表示作为一个模块进行编译,最后在MAKEFILE中需要用到的编译开关。

然后在相应的源码目录中的Makefile中添加如下语句:

$(MODULE_NAME)-objs := $(SRC_PATH)kernel_simulator.o
$(MODULE_NAME)-objs += $(SRC_PATH)test_func.o

上面的意思就是编译生成ko文件需要两个.c文件(kernel_simulator.c、test_func.c),最后生成名为ksimulator的ko文件。

注意ko文件名一定不能为kernel_simulator。那么在obj-m和$(MODULE_NAME)-objs中都含有kernel_simulator.o,对make来讲会产生循环和混淆,会报如下的错误:

make[2]: Circular /home/kernel/Kernel_Simulator/kernel_simulator.o <- /home/kernel/Kernel_Simulator/kernel_simulator.o dependency dropped.

基本知识

obj-m = *.o
obj-y = *.o

上面两者的区别在于,前者才会生成ko文件,后者只是代码编译进内核,并不生成ko文件。

使用obj-m方式:

使用obj-y方式:

相关