Linux中多个.c文件编译为一个模块.ko

编程入门 行业动态 更新时间:2024-10-02 16:28:58

Linux中<a href=https://www.elefans.com/category/jswz/34/1771377.html style=多个.c文件编译为一个模块.ko"/>

Linux中多个.c文件编译为一个模块.ko

例如现在有三个文件:

exp.c

exps.c

exp.h

这是目前做实验的代码,其中exps中是工具函数,其内容被exp.c调用,exp.h是exps.c文件中函数的声明以及一些结构体的定义。

下面介绍将exp.c与exps.c编译为一个模块ex.ko,以及在这个过程中遇到的一系列问题。

由于exps.c中是一些工具函数,所以在exps.c中不需要module_init、module_exit等来进行修饰,而exp.c要调用exps.c,并且里面含有模块的入口函数和出口函数,所以在exp.c中使用module_init、module_exit等模块结构。

一个模块只有一个入口和出口,所以只有一对module_init、module_exit,同时要添加上MODULE_LICENSE("GPL")

实验代码不方便贴出来,但是方法已经过真机测试,现在在我的虚拟机上随便写几个函数来演示一下:

exp.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "exp.h"extern void exps_init(int e);static int table_init(void)
{printk("TABLE: table init \n");exps_init(50);   return 0;
}static void table_exit(void)
{printk("TABLE: table exit \n");
}module_init(table_init);
module_exit(table_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me");
MODULE_DESCRIPTION("module test");

extern导入符号是必要的,测试了如果不导入符号,会报如下错误:

error: implicit declaration of function ‘exps_init’ [-Werror=implicit-function-declaration]

即使这句extern 写在exp.h中也不行。

exps.c:

#include "exp.h"
#include <linux/kernel.h>void print(int e)
{printk("parameter is %d \n",e);
}void exps_init(int e)
{printk("hello, this is exps \n");print(e);	
}

在exps.c中,符号exps_init会被exp.c调用,这里既可以使用EXPORT_SYMBOL来导出这个符号,也可以不使用EXPORT_SYMBOL,测试了都没有问题。

exp.h:

#ifndef _LINUX_EXP_COMMON_H_
#define _LINUX_EXP_COMMON_H_void exps_int(int e);#endif

Makefile:

ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=exp.o exps.o
else#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build#complie object
default:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif

Makefile是关键,首先 obj-m指定模块名,然后再根据模块名-objs:=依赖的文件。

最开始我想将模块名设置为exp,但是和我的文件重名了,这时候编译虽然成功了,但是插入模块会报如下错误:

[ 2045.410335] exp: module license 'unspecified' taints kernel.
[ 2045.410338] Disabling lock debugging due to kernel taint

所以我不能选择exp或者exps作为模块名~

依赖文件不需要顺序,比如既可以是:

ex-objs:=exp.o exps.o

也可以是:

ex-objs:=exps.o exp.o

使用make编译得到如下内容:

insmod 插入模块后,dmesg就可以得到想要的信息:

 

多个文件:

多个文件也是一样,比如这里我再增加了一个expss.c文件,该文件中函数expss_init被exps.c中函数调用:

此时exps.c:

#include "exp.h"
#include <linux/kernel.h>extern int expss_init(int e);void print(int e)
{printk("parameter is %d \n",e);
}void exps_init(int e)
{printk("hello, this is exps \n");e = expss_init(e);print(e);	
}

expss.c:

#include <linux/kernel.h>
#include "exp.h"int expss_init(int e)
{return (e+10);
}

Makefile:

ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=expss.o exps.o exp.o 
else#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build#complie object
default:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif

编译出文件如下:

插入模块运行如下:

更多推荐

Linux中多个.c文件编译为一个模块.ko

本文发布于:2024-03-09 03:25:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1723614.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   译为   模块   文件   Linux

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!